태어나서 처음으로 Pintos라는 것에 대해 들어보았다. 사실 들어본것도 아니다. A4용지 한쪽 귀퉁이에 쓰여진 "Pintos 프로젝트를 수행하라"는 짤막한 한마디. 이너넷을 대충 뒤져보니, Stanford 대학에서 개발한 학습용 OS인 것 같았다.
나중에 프로젝트에 대한 추가 설명이 있겠지만, 주말이고 할 일도 없고 해서 그냥 설치만 미리 해보기로 했다. 근데 이렇게 어려울 줄이야.. 주말이 그냥 지나갔다;;
우분투 7.10 커널 2.6.22.14 기준에서 작성. 정확한 순서는 아니다. 내가 작업하면서 시행착오를 겪은 순서대로 썼다. 아마 거의 대부분의 오류는 여기 다 있을듯. 내용이 길기 때문에, 필요한 부분만 찾아서 보는게 좋겠지요.
1. bochs 설치
Pintos를 구동하려면 이게 필요하단다. (Box와 같은 발음으로 읽는다. 박스.) 이너넷을 통해 구할 수 있는 공개 프로그램(http://bochs.sourceforge.net/)이며 "오픈소스 ia32 에뮬레이션 프로젝트"라는 것을 보니, 뭔가 가상머신의 일종으로 짐작된다.
(1) 설치과정
우분투에서는 bochs가 내장되어있다. 그래서 시스템 - 관리 - 시냅틱 꾸러미 관리자 - 검색 - 'bochs'입력 - 'bochs'체크하여 설치표시 - 적용 요렇게 순서대로 클릭해주면 알아서 설치한다. 쉽군. 별거 아니네. 그러나 이 방법을 통해서 설치하게되면, 2006년도 버전인 bochs-2.2 버전이 설치된다. 뭔가 찜찜하기에, 최신버전(2007년 2.3.6)을 설치하기 위해 위 사이트에서 직접 다운로드하여 설치했다. (지금 생각해보면 이때부터가 실수였을수도. 다음에는 내장 패키지로 한번 해봐야지...;;)
다운받은 파일을 압축을 풀어주고, 터미널을 실행하여 해당 폴더로 간 후,
$ ./configure --enable-gdb-stub $ make $ sudo make install
순서대로 요렇게 해주면 설치가 끝난다. 위의 것들이 한 번에 됐다면 바로 Pintos를 설치해주면 된다.
(2) 첫번째 오류 - error: C compiler cannot create executables
역시,,,,, 한번에 될 리가 없지 않은가. 처음부터 막힌다. $ ./configure --enable-gdb-stub 를 실행해주면,
checking build system type... i686-pc-linux-gnulibc1 checking host system type... i686-pc-linux-gnulibc1 checking target system type... i686-pc-linux-gnulibc1 checking if you are configuring for another platform... no checking for standard CFLAGS on this platform... checking for gcc... gcc checking for C compiler default output file name... configure: error: C compiler cannot create excutables See `config.log' for more details.
컴파일러가 실행파일을 생성하지 못하겠다는 이야기다. (컴파일러가 안하면 누가 하라고;;;;;) 문제의 원인은, C컴파일러는 우분투를 설치하면서 자동으로 설치되나, C++컴파일러 역할을 하는 g++패키지는 직접 설치해주어야 한다는 것.(by 구글) 아래의 방법으로 해결해주었다. 원인을 쉽게 파악해서 그런지, 해결도 쉬웠다.
설치가 끝나면 $ ./configure --enable-gdb-stub 를 다시 실행해준다. 기쁜마음으로.
(3) 두번째 오류 - X windows libraries were not found
그러면 1분만에 두 번째 문제에 봉착하게 된다.
checking whether to build docbook documentation... no checking for wx-config... not_found checking for wxWidgets configuration script... not_found checking for wxWidgets library version... checking for default gui on this platform... x11 ERROR: X windows gui was selected, but X windows libraries were not found.
X윈도우 라이브러리가 없으니 이를 설치하라는 것 같았다. (그게 뭐지... ) 혼자 시냅틱 패키지 관리자를 방황하다가 구글에 그대로 쳐넣으니 의외로 쉽게 답이 나왔다. 나 같은 고생을 하는 사람이 또 있었다. 터미널을 열어 다음과 같이 입력해주면 해결~!
$ sudo apt-get install xorg-dev →이게 아마도 X윈도우 라이브러리...??
그 다음부터는 일사천리로 진행된다.
$ ./configure --enable-gdb-stub $ make $ sudo make install
여기서 sudo 라는 명령어는 시스템으로부터 SuperUser(관리자)권한을 얻겠다는 명령어이다. 저걸 안 넣어주면 가끔 Permission denied라는 오류가 나면서 어쩌고저쩌고 떼를 쓰므로, 시스템을 수정할때는 sudo 를 넣어주어야 한다. 간혹 관리자 비밀번호를 입력하라고 할 때도 있다. 넣어주자.
운좋게도 두 개의 오류만으로 설치가 끝났다. 다행이다. ㅋㅋ 하지만 이것이 다가 아니었다........;;
다운로드후 원하는 곳에다가 압축을 풀어준다. 터미널을 열어서 압축 푼 pintos 디렉토리까지 찾아간 후
$ cd /src/threads $ make
를 차례로 실행해준다. 뭐라고 막 괴물같은 글자들을 뱉어내면서 설치가 되고... 다 된 다음엔 /src/threads 밑에 새로 build라는 디렉토리가 생긴다.
여기까지만 해주면 설치 완료이다. 상대경로를 직접 입력하여 pintos를 실행할 수 있지만, 좀더 편하게 실행하기 위해서 환경변수를 설정해주면 좋다. 터미널에 다음을 입력.
$ sudo gedit ~/.bashrc
관리자 비밀번호 넣으라고 나오고, 넣으면 편집창이 하나 뜬다. 당황하지 말고 맨 아랫줄에 다음을 그대로 입력해주고 저장하고 빠져나온다.
export PATH="$PATH:/home/user/pintos/src/utils" ↑pintos를 설치한 디렉토리경로를 적어준다.
환경변수 설정도 끝. $ bash로 환경변수를 다시 읽어오고 이제 pintos를 테스트하기 위한 최종 명령만이 남아있다.
$ cd build (build 디렉토리로 이동) $ pintos -- run alarm-multiple (이 명령으로 pintos를 테스트할 수 있다. 띄어쓰기 유의)
만약 난 특별하기 때문에 위에서 환경변수 설정을 안했다면, 다음과 같은 방법으로 실행해줄 수 있을 것이다.
$ cd build (build 디렉토리로 이동) $ ../../utils/pintos -- run alarm-multiple (상대경로 직접 찾아가서 실행. 역시 띄어쓰기 유의)
여기까지가 간단하게 요약한 Pintos의 설치과정이다. bochs에 이어서 이것까지 단번에 성공했다면, 당신은 올 한해 운수가 격하게 좋은 것이다.
(2) 첫 번째 오류 - __stack_chk_fail
올 한해 운수는 별로 좋지 않은것 같다. $ make명령 실행의 결과다.
/home/user/pintos/src/threads/build/../../lib/stdio.c:547: undefined reference to `__stack_chk_fail' tests/threads/alarm-wait.o: In function `test_sleep': /home/user/pintos/src/threads/build/../../tests/threads/alarm-wait.c:134: undefined reference to `__stack_chk_fail' tests/threads/alarm-simultaneous.o: In function `test_alarm_simultaneous': /home/user/pintos/src/threads/build/../../tests/threads/alarm-simultaneous.c:19: undefined reference to `__stack_chk_fail' tests/threads/alarm-priority.o: In function `test_alarm_priority': /home/user/pintos/src/threads/build/../../tests/threads/alarm-priority.c:39: undefined reference to `__stack_chk_fail' tests/threads/priority-fifo.o: In function `test_priority_fifo': /home/user/pintos/src/threads/build/../../tests/threads/priority-fifo.c:84: undefined reference to `__stack_chk_fail' tests/threads/priority-sema.o:/home/user/pintos/src/threads/build/../../tests/threads/priority-sema.c:38: more undefined references to `__stack_chk_fail' follow make[1]: *** [kernel.o] 오류 1 make[1]: Leaving directory `/home/user/pintos/src/threads/build' make: *** [all] 오류 2
`__stack_chk_fail'이라는 오류들이 무더기로 발생한 것을 볼 수 있었다. 젠장. 점점 미쳐가고 있었다. 분명이 하라는 대로 잘 하고 있는데 왜 나만 이래 ㅋㅋ 정신을 가다듬고 다시 구글 구글 구글... 우분투 OS에서만 발생하는 오류인 것 같았다. make 도중 stack을 체크하는 과정에서 발생하는 오류..정도? 구글에는 나 말고도 많은 사람들이 이것 때문에 고민한 흔적이 있었다. 유명한 놈이군. 거기서 시키는 대로, /pintos/src 내의 Make.config파일을 찾아서 옵션을 추가해주는 것으로 해결을 보았다.
CFLAGS = -g -msoft-float -O -fno-stack-protector ↑이 부분을 찾아서 ↑요렇게 뒤에 덧붙여준다. no-stack-protector
파일 수정 저장후 빠져나와서, 다시 처음부터 실행. $ make clean으로 이전에 build된 것들을 제거해주어야 $ make 가 정상적으로 수행된다. 결과는? 성공. 환경변수도 이상없이 설정되었다.......만..
(3) 두 번째 오류 - System BIOS must end at 0xfffff
$ pintos -- run alarm-multiple 명령. 지금까지의 과정을 최종 확인하는 순간이다. 그러나 역시 마지막 단계를 넘기 직전, 최후의 보스는 어김없이 나온다. 굉장히 강한 놈이었다. 고민에 고민을 거듭해도 모르겠고, 구글링도 완벽한 답을 주지는 못했다..
Writing command line to /tmp/mcnK5SXSJY.dsk... warning: can't find squish-pty, so terminal input will fail bochs -q ======================================================================== Bochs x86 Emulator 2.3.6 Build from CVS snapshot, on December 24, 2007 ======================================================================== 00000000000i[ ] reading configuration from bochsrc.txt 00000000000i[ ] installing x module as the Bochs GUI 00000000000i[ ] using log file bochsout.txt ======================================================================== Bochs is exiting with the following message: [MEM0 ] ROM: System BIOS must end at 0xfffff ========================================================================
Bochs라는 프로그램의 구 버전에서는 BIOS의 크기가 64k로 고정되어 있으며, 그 시작점의 주소가 0xf0000 이었다. 그러나 2.2.5버전 이후로는 BIOS가 512k까지 커졌고 시작점의 주소를 지정할 필요가 없어지게 되었다. 지금 상황은 새로운 버전의 BIOS를 구버전의 시작점 주소방식으로 사용하고 있는 것 같아보이므로, romimage파일에서 시작점의 주소 parameter를 직접 찾아서 제거해주면 간단히 해결된다.
뭐야. 별거 아니었군. 간단히 해결된대. . . . . . . . . . . 그래서 어떻게 해줄까. romimage 파일은 무엇이며 시작점의 주소 parameter가 무슨 개소리인가.
여기서부터 추론이 시작된다.
위 최종보스의 파란 글씨 부분을 보면 bochsrc.txt로부터 무언가를 읽어들이고 있었다. 저걸 일단 찾아서 열어보았다. build 디렉토리 안에 있는 놈이었다.
너무 쉽게 찾았군. 빨간 색에서 address 뒷부분을 지워주면 해결되겠구나.ㅋㅋㅋㅋ 당장 지우고 저장한 후 다시 실행명령을 먹였다. 결과는 동일했다. '어? 이상하다. 분명히 지웠는데' 하면서 다시 파일을 열어본 순간.. 정말 경악을 금치 못했다. 지우고 저장했던 부분이 거짓말처럼 되살아나있는 것이었다......
이후로 수십번을 그랬다. 지우고 저장하고 실행하고 안되고, 지우고 저장하고 실행하고 안되고, 지우고 저장하고 실행하고 안되고, ........... 그야말로 좀비가 따로 없었다. 최종보스답군. 미치는 줄 알았다. 이런 괴물이 또 있었나 싶었다.
이성적으로 생각해보았다. 수정하고 저장까지 완벽이 끝낸 파일이 다시 살아날 수는 없는 일. 수정한 부분이 되살아난다는건 어떤 다른 파일로부터 갱신된 정보를 받고 있는거겠지. 지우고 저장하고 다시 열어볼 때는 저장한 그대로 있었으나, 실행하고 안되고 이후에 열어볼 때는 되살아나 있었다. 실행할 때 뭔가 정보를 넘겨받는군. 결론은 실행파일을 뜯어보자!
실행파일은 /pintos/src/utils 디렉토리 안에 있는 pintos라는 놈이다.
$ sudo gedit pintos
드디어 최종보스를 물리치는 순간이었다. 추론이 맞아들어갔다. 다음은 최종보스의 내부구조이다.
# Write bochsrc.txt configuration file. open (BOCHSRC, ">", "bochsrc.txt") or die "bochsrc.txt: create: $!\n"; print BOCHSRC <<EOF; romimage: file=\$BXSHARE/BIOS-bochs-latest, address=0xf0000 vgaromimage: file=\$BXSHARE/VGABIOS-lgpl-latest boot: disk cpu: ips=1000000 megs: $mem log: bochsout.txt panic: action=fatal EOF
빨간글씨를 보면 알 수 있다. 놈은 갱신되고 있었다. address=0xf0000을 과감히 지워주고 저장. pintos의 거지와도 같은 설정파일갱신기능이 이렇게 몸고생 맘고생을 시켰다. 젠장.
_____________________
최종보스를 물리친 결과이다. 알람메시지가 출력된 모습.
여기까지가 설치 끝. 이제부터가 시작이구나;;; 지겨워지겨워. 리눅스를 쓰면 쓸수록 드는 생각은 "윈도우는 위대하다~?" 이런 시행착오를 겪으면서 점점 강해지는 것이 아닐까. 강한 최종보스를 물리쳤으니, 경험치 급상승? ㅋㅋㅋㅋ