(프로젝트 개요)


현재 pintos는 시스템 콜 핸들러가 제대로 구현되어 있지 않다. 시스템 콜이 발생해도 system call!! 이라는 출력문 하나만 달랑 뿌리고, 그대로 스레드가 종료된다.(thread_exit()) 따라서, 이번 프로젝트 2는 핀토스의 시스템 콜 핸들러 함수를 구현하고, 간단한 시스템 콜(halt, exit, create, remove)를 구현해본다.



| 시스템 콜?

사용자 모드 수준에서의 프로그램이 커널 기능을 사용할 수 있도록 해주는 인터페이스.

시스템 콜의 기능들은 커널 모드에서 실행되고, 처리 후 사용자 모드로 복귀됨.



(프로젝트 해결 방법 개요)


우선, 2가지 함수를 구현해야 함. 


1. 특정 포인터(주소값)가 유저 영역에 존재하는지 확인하는 함수.

void check_address(void * address);


2. 유저 스택에 들어 있는 인자들의 주소를 저장하는 함수.

void get_argument(void *esp, void *arg, int count);


1. 유저 영역은 0x08048000 에서 0xc0000000 사이에 (경계값 제외) 존재하는 주소값이면 유저 영역인 것이다. check_address를 구현할 때 이 바깥 범위의 값이면 exit (-1)을 호출해 프로그램을 종료시켜야 한다. (유저 영역이 아닌 커널 영역을 건드리는 프로그램은 프로그램을 종료시키는 것이 적절한 운영체제의 반응이다.)


2. get_argument 의 함수는 esp 인자에서 인자들을 4바이트씩 긁어온 후, arg라는 변수에 저장하는 행동을 한다. 참고로, arg에 저장하는 값들은 인자의 주소값이다. (이 부분을 정확히 이해하라.) arg에 주소값을 저장하지 않고 인자값 자체를 저장하면 안된다. 왜냐하면, 시스템 콜의 인자들이 전부 4바이트로 표현할 수 있다는 보장이 없기 떄문이다. (가령 문자열이 전달되어 온다면 어떻게 할것인가..? 해결방법은 문자열 자체의 주소값을 저장하는 것이다.)


따라서, arg에는 반드시 인자의 주.소.값이 저장되어야 함을 무한 강조!!

f->esp 의 첫 4바이트는 시스템 콜 넘버이므로, 그 다음 4바이트씩 count 횟수만큼 긁어와서 arg에 저장하면 된다.



============

시스템 콜 핸들러 함수

static void syscall_handler (struct intr_frame *f UNUSED) { /* 유저 스택에 저장되어 있는 시스템 콜 넘버를 이용해 시스템 콜 핸들러 구현 */ /* 스택 포인터가 유저 영역인지 확인 */ /* 저장된 인자 값이 포인터일 경우 유저 영역의 주소인지 확인*/

}

f->esp (유저 스택)에는 4바이트씩 인자들이 저장되어 있다. f->esp의 첫 번째 4바이트에는 시스템 콜의 넘버가 저장되어 있고, 그 뒤로 4바이트씩 시스템 콜의 인자가 저장되어 있다.


예를 들어, create 시스템 콜은 인자로 파일 이름과 파일의 첫 크기를 인자로 받는다. 그러면, create 시스템 콜이 발생할 때 유저 스택 포인터는

다음과 같은 구조를 띈다.


f->esp

(4바이트) 4

(4바이트) 0x100

(4바이트) 0x104

....

0x100은 파일 이름 문자열의 주소값이고, 0x104는 파일의 첫 크기의 주소값이다. 물론, 파일의 첫 크기값은 정수일테지만, 정수값 자체를 유저 스택에 저장하지 않는다. 유저 스택에는 '주소값'이 저장되어 있음을 무조건 기억하라. 따라서, 나중에 시스템 콜 핸들러에서 create 시스템 콜을 처리할 때 다음과 같이 처리해야 한다.


    case SYS_CREATE:/* 4 */
      f->eax = create((char *)*(int *)arg[0], (unsigned)*(int *)arg[1]);
    break;

현재 arg에는 인자들의 '주소값'이 저장되어 있다. 즉, arg[0], arg[1],...등은 전부 '주소값'이다. 따라서, *arg[0]의 의미는, arg의 첫 번째 값의 내용물을 찾아오는 것이다. 따라서, 첫 번째 인자의 주소값의 내용물을 찾아와서 그들을 시스템 콜 함수의 인자로 넘겨줘야 하는 것이다. 


C 소스 코드를 작성할 때 기본적인 헤더파일들의 위치는


/usr/include/ 에 위치합니다.



tar: 파일을 압축하거나 압축해제하기 위해 사용하는 리눅스 명령어


압축 command:

tar cvf xxx.tar.gz


압축 해제 command:

tar xvf xxx.tar.gz


tar 명령어에 사용하는 몇몇 옵션들을 소개하자면 다음과 같습니다.


-x : 압축 해제한다.

-c : 압축한다.

-v : 압축하거나 압축해제의 과정을 전부 화면에 출력

-f : 파일이름을 지정한다.

-p : 파일권한을 저장한다.

-C : 파일을 압축해제할 경로를 지정한다.


간단하게 사용하는 예제를 보여드릴게요.





touch B C ;B C 라는 빈 파일(empty files)을 생성함.


tar cvf A.tar.gz B C ;B C를 압축하여 A.tar.gz 라는 압축파일을 생성.


rm B C ;B C 파일을 삭제함.(압축해제가 제대로 되었는지 확인하기 위해서)


tar xvf A.tar.gz ;A.tar.gz 압축파일을 해제함.


제대로 압축 해제가 되었음을 알 수 있습니다.

 일반적으로, Windows xp, 7, 8 과 같은 윈도우즈 운영체제를 컴퓨터에 설치해서 사용하시는 분들이 많을텐데요.

공부나 업무용 혹은 호기심의 목적으로 리눅스 우분투등과 같은 다른 운영체제를 사용할 경우가 있습니다. 

 

 윈도우즈 운영체제를 기본적으로 사용하면서 추가로 운영체제를 설치할 수 있는 방법이 있습니다.

바로 '가상머신'이라는 유틸리티 프로그램을 사용하는 것입니다.

 

 가상머신을 사용하게 되면, 기존의 운영체제를 시동한 후, 새로운 운영체제를 그 위에 다시 시동하여 사용할 수 있으며,

이 상태에서는 동시에 두 개의 운영체제를 사용할 수 있습니다. 기존이 운영체제를 '호스트 운영체제'(주인 운영체제)라고 하고,

새로 설치할 운영체제를 '게스트 운영체제'(손님 운영체제)라고 합니다. 

주인 집 위에 손님 집을 짓는다고 생각하면 이해가 빠를 것입니다.

 

 

 오늘은 무료로 사용할 수 있는 'VirtualBox'라고 하는 가상머신을 사용해서

'Linux Ubuntu LTS 12.04' 라고 하는 새로운 운영체제를

설치하는 과정에 대해서 설명해보려고 합니다.

 

 

1. VirtualBox 설치하기

https://www.virtualbox.org/wiki/Downloads 

위 사이트에 들어가신 후, 기존의 운영체제 버전에 맞는 VirtualBox 프로그램을 다운로드합니다.

 



 

 일반적으로는 윈도우즈를 사용하니까, 

VirtualBox 4.2.18 for Windows hosts 에 있는 파일을 다운로드합니다.

(만약 다른 운영체제를 사용한다면 그에 맞춘 파일을 다운로드 받으세요.)

 

 설치파일을 실행시켜서 설치를 진행합니다.

만약, 설치 중에 Installation Failed Error 오류가 난다면 다음 사이트를 참조하여 해결할 수 있습니다.

http://thinkpro.tistory.com/41

 

 

2. 리눅스 우분투 설치하기

http://www.ubuntu.com/download/desktop

 위 사이트에 들어가신 후, 원하는 버전의 운영체제 디스크 이미지 파일을 다운로드하세요.

저는 LTS의 12.04 버전 32bit 를 선택해서 다운로드 하였습니다.

 

 

제대로 가상머신 만들어보기 전에, 가상머신에 리눅스 우분투가 설치되는 큰 설명을 할게요.

버츄얼 박스는 주인 집(윈도우즈) 위에 손님 집(리눅스 우분투)을 짓게 해주는 프로그램입니다.

우리는 우선, 1. 손님 집이 될 빈 집 자리를 만들고, 2. 그 빈 집에 리눅스 우분투를 넣어서 손님 집을 완성시킬 것입니다.

 

 

설치를 완료하였으면, 프로그램을 실행시켜서 빈 집을 만들어 봅시다~

 

 

우선, 새로운 운영체제를 설치해야 하므로 좌측 상단의 '새로 만들기(N)'을 클릭합니다.


 

제일 처음, 이름을 입력하라고 합니다.

저는 'Linux Ubuntu 12.04' 라는 이름을 사용했고, 이름란에 쓰는 단어에 맞추어

밑의 종류(T) 및 버전(V)이 자동으로 설정이 됩니다. 이 둘은 사용자가 임의로 변경할 수도 있습니다.

 

새로운 운영체제에 사용할 램 용량, 즉 메모리 크기에 대해서 설정하는 부분입니다.

리눅스 우분투 운영체제를 설치할 때, 추천 메모리 크기는 512MB입니다.

저는 RAM 용량의 여분이 많은 관계로 4096MB, 즉 4GB를 할당해 주었습니다.


 

그리고 새로운 운영체제가 설치 될 하드 드라이브에 대한 설정입니다.

이미 가상 하드 드라이브가 있다면 '기존 가상 하드 드라이브 파일 사용(U)'를 클릭해서

기존의 가상 하드 드라이브를 사용하시면 됩니다.

 

처음 설치하시는 경우, 가상 하드 드라이브 파일이 없을 테니,

'지금 가상 하드 드라이브 만들기(C)'를 클릭하여 가상 하드 드라이브를 만듭시다.

 

하드 드라이브 파일의 종류에 대한 설정입니다. 어느 것을 선택하여도 됩니다.

다만, 다른 가상머신을 사용할 계획이 있다면 그에 맞추어 변경해주시면 됩니다.

 

예를 들어, 지금 만든 가상 하드 드라이브 파일을 QEMU 라고 하는 새로운 가상머신을 사용해

시동할 경우, QED 확장자를 사용해서 만들어 놓으면 버츄얼 박스에서도 사용이 가능하고, QEMU

가상머신에서도 사용이 가능합니다.


 

하드 드라이브를 어떤 방식으로 만들 것인지 결정하는 단계입니다.

이 부분이 처음 설치하시는 분께는 제일 이해가 안되는(??) 부분입니다.

 

저도 처음엔 동적 할당/ 고정 크기 의 개념이 이해가 되지 않았는데요.

동적 할당은 말 그대로 동적으로 만들겠다는 것입니다. 

설치할 새로운 운영체제에서 파일이 생길 때마다 가상 하드 드라이브 파일의 크기가 커집니다.

고정 크기는 그냥 처음 정해놓은 가상 하드 드라이브 파일의 크기만큼 파일이 생깁니다.


 

가상 하드 드라이브의 크기를 설정하는 단계입니다.

저는 250GB SSD 를 사용해 그리 넉넉치 않은 용량의 하드 디스크를 가지고 있어서,

약 30GB만큼을 할당해주었습니다.

 

새로이 설치할 운영체제에서 얼마만큼의 하드 디스크 용량이 필요한지 계산해서 적절하게 변경해주시면 되곘습니다.

 

이제, 빈 집은 만들었습니다. 

지금까지 빈 집의 램은 얼마고, 하드디스크는 얼마가 되야 할지를 설정한 것입니다.


자, 이제 빈 집에 리눅스 우분투라고 하는 놈을 넣어봅시다.




오른쪽 클릭 후 > 설정(S) 에 들어가서



1. '저장소' 클릭! 

2. '비어 있음' 클릭!

3. 작은 CD 아이콘 클릭!

4. 사용할 리눅스 우분투 이미지 파일을 찾아 선택

5. '확인' 클릭!

 

이제, 리눅스 우분투 이미지 파일까지 빈 방에 집어넣었습니다.

그리고 '시작(T)' 버튼을 누르면 설치가 진행됩니다.

 

 

그 이후 과정은 너무나 쉬워서 이 포스트에서는 설명을 생략하겠습니다.

그냥, 하라는 대로 주우욱 진행하면 됩니다.

 

2. SAMBA란 무엇인가?

삼바는 SMB 프로토콜을 유닉스 컴퓨터에 구현한 프리웨어로서, 원래 국립 호주대학의 앤드루 트리젤이 유닉스용으로 개발하였다. 

이것은 윈도우 클라이언트에서 유닉스 서버에 있는 파일들이나 프린터를 공유할 수 있게 해준다. 

예를 들면, 유닉스 서버에 있는 파일을 편집하기 위하여 텔넷으로 접속하는 대신에, 

윈도우95/98 사용자가 윈도우 익스플로러 내에 있는 드라이브에 연결함으로써 유닉스 컴퓨터 상의 삼바 서버에 접속한 후, 

윈도우용 에디터를 이용하여 그 파일을 편집할 수 있다.


무슨 말인지 모르겠죠...ㅎ

ssh는 '설치'한다고 했는데 samba는 '구축'한다고 할거에요.

왜냐하면 samba는 윈도우 운영체제에서 유닉스 컴퓨터에 접근할 때 사용하는 프로그램이거든요.

우리는 지금 리눅스 우분투를 기반으로 하고 있잖습니까? 즉 우리가 서버 역할을 하는 입장인 거에요.

따라서, 우리한테는 samba를 구축한다고 하는게 더 어울리는 표현인거죠.

이제, 삼바 SAMBA 를 구축하는 방법을 소개해드립니다.


2-1. samba 설치하기

$ sudo apt-get install samba

2-2. smb.conf 파일 수정하기
$ sudo vi /etc/samba/smb.conf

smb.conf 파일은 약간의 수정과 추가할 것이 있어요... 


수정해야 할 것:
....
# security = user
....

줄을 찾아서 #을 지워 주석처리를 해제하고 저장합니다.

추가할 것:
[userid]
path = /home/userid
public = no
only guest = no
writable = yes
create mask = 0777
force user = userid

가장 마지막 줄 뒤에
를 추가합니다. 여기서 'userid'는 사용자 이름입니다.

가령 제 계정 이름이 jeongmin 이면

[jeongmin]
path = /home/jeongmin
public = no
only guest = no
writable = yes
create mask = 0777
force user = jeongmin

이렇게 추가하는 겁니다.



2-3. 사용자 등록
$ sudo smbpasswd -a userid // userid는 사용자 이름 

2-4. samba 재 시작
$ sudo /etc/init.d/smbd restart


리눅스 운영체제는 유닉스 시스템을 기반으로 하고 있으며, 기본적으로 운영체제가 부팅될 때,

'로그인'이라는 과정을 진행하게 됩니다. 


로그인 과정은 user ID 즉, 계정 이름과 비밀번호를 요구합니다. 

오늘은 user ID를 생성하는 방법

계정에 sudo 권한을 부여하는 방법에 대해서 설명하겠습니다.



1. user ID 생성

$ sudo adduser [userid]            // 사용자 계정을 새로 만드는 명령어


[userid]는 생성하고자 하는 user id 값입니다.

가령, jeongmin 이라는 계정을 추가하고 싶다면

$ sudo adduser jeongmin

이렇게 사용하시면 됩니다.



2. 계정에 sudo 권한 부여하기

 우선, sudo 권한이 무엇인지 부터 알려드려야 겠네요.

리눅스 운영체제를 사용해보신 적 있다면 sudo apt-get install... 등 과 같이 sudo 명령어를

은근히 몇 번 써보셨을 겁니다. sudo 명령어는 사용자에게 루트 권한을 부여하는 것입니다.


리눅스 운영체제에서는 일부 중요한 데이터나 시스템을 변경하는 등의

책임이 큰 행동에 대해서는 루트 권한을 요구합니다. 

쉽게 생각해서 루트 권한을 뭐든지 할 수 있는 슈퍼 유저라고 생각하십시오.


그리고 일반 사용자가 잠시동안 루트 권한을 빌리는 방법이 바로 sudo 명령어를 사용하는 것입니다.

그런데 아무 사용자나 sudo 명령어를 쓸 수 있다면 굳이 sudo 명령어가 필요하겠습니까?

일반 사용자도 sudo 명령어를 쓸 수 있는 계정/ 쓸 수 없는 계정이 있습니다.


한 사용자 계정이 sudo 권한을 부여 받으려면 /etc/sudoers 파일 안에 등록이 되어야 합니다.

다음 명령어를 입력해봅시다.

$ sudo visudo                         // /etc/sudoers 에 접근


/etc/sudoers 파일 내에서

....

# User privilege specification

root ALL=(ALL:ALL) ALL

....

이 곳에 

[userid] ALL=(ALL:ALL) ALL                // [userid] 는 권한을 부여하고자 하는 계정 이름.

을 추가하시면 됩니다.


예를 들어, jeongmin 을 추가했다면

jeongmin    ALL=(ALL:ALL) ALL

을 추가해주시면 됩니다.

+ Recent posts