해당 과제 commit
과제 목표
- xv6 설치 및 컴파일
- xv6 쉘 명령어 추가를 통한 "Hello Soongsil xv6" 출력
과제명세
- xv6 설치 및 컴파일
- 쉘 프로그램 작성
a. helloworld
b. hcat
- 부팅시 Username: root, Password: 1234를 입력하여 로그인
1. xv6 설치 및 컴파일
- 주변 사람들이 이 과정이 매우 쉽다고 하지만 docker에서 작동시키는 입장에서 매우 애를 먹었다. 우선 과제에 주어진 실행방법을 먼저 소개하겠다.
- xv6 다운로드
git clone git@github.com:mit-pdos/xv6-public.git
- http가 아닌 git으로 시작하는 주소일때, 해당 컴퓨터의 ssh key가 github에 등록되어 있지 않으면 에러가 난다. 반드시 해당 사항을 확인하자
- 필요 패키지 설치
apt-get install qemu-kvm
- xv6는 x86 하드웨어를 에뮬레이트 하는 qemu x86 에뮬레이터에서 실행된다.
- 없어도 운용이 가능하나 커널 함수 등 하드웨어 종속성이 있는 코드를 수정하기 위해 에뮬레이터 사용을 권장한다.
- xv6 컴파일 및 실행
make
make qemu
- ubuntu desktop등 window x 환경이 제공되는 경우에서만 해당 명령어를 사용할 수 있다. 이외는 그래픽 드라이버 오류 등을 띄우면서 종료된다.
- 따라서
make qemu-nox
를 활용해야만 한다.
겪었던 오류들
-
기초적인 package 부족
- git clone이 안되는 경우
apt install git-all
- gdb 및 gcc 등 c 언어 실행을 위한 프로그램들
apt-get install -y build-essential gdb gcc-multilib
-
qemu 실행시 생기는 오류
*** Error: Couldn't find a working QEMU executable.
- qemu-kvm이 없어서 생기는 문제, docker에서는 qemu-kvm을 위한 여러 종속성이 없어 다른 프로그램들도 추가해줘야함
- 해결책
- `apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager
Unable to init server: Could not connect: Connection refused gtk initialization failed
- gtk: 리눅스에서 GUI를 다루기 위해 쓰이는 대표적인 라이브러리
- make qemu
가 아닌 make qemu-nox
로 실행해야한다.
2. 쉘 프로그램 작성
a. helloworld [source]
- 명세: "Hello World xv6"를 출력하는 helloworld.c 프로그램 작성
- 매우 간단한 shell 프로그램이다. 메인에서 pirntf만 사용하면 됨
- 단, stdio.h의 printf를 사용하는 것이 아닌, user.h의 printf를 사용하게 됨. source
- printf(<<출력위치>>, <<문자열>>, <<기타 변수들>>...)
- 마치 fprintf 처럼 사용한다. (단, 출력위치는 File* 형이 아닌 file descriptor(int) 이다.)
- 출력위치는 주로 stdout(1)이다.
b. hcat 쉘프로그램
- 파일의 첫 번째 <n>행을 터미널에 출력하는 hcat.c 프로그램 작성
- 기존의 cat.c를 복사해서 출력할 행만 제한해주면 됨!
- 본인은 buffer size를 1로 하고,
\n
값을 입력할때마다 count 값을 올려가면서 주어진 n 값과 계속 비교하는 프로그램으로 작성하였다. 매우 효율이 떨어져 이후 수정이 필요하다.
- source
통합. Makefile build
- Makefile을 수정해야 만든 c 파일이 실행파일로 변환되어, xv6 가상머신 위로 적재가 된다.
- 추가적인 질문을 통해 Makefile 사용법을 알아야겠다.
- URPOGS에
_<<실행파일명>>
추가
- EXTRA에
<<소스코드명>>
추가
실행결과
3. 부팅시 로그인 구현
- init.c [source]
- ssu_login.c [source]
- list.txt를 열어
혹은 \n
마다 단어를 끊어서 저장해야함
- 해당기능을 void parse_word(int fd, char *dest)
로 구현함 source
- init.c의 sh 실행 방식을 그대로 차용하였다. 참고한 코드 22~36라인
- 만약 id와 pw가 동일한 게 존재한다면 sh 실행
- list.txt 추가
- 간단하게 생각해서 README는 compile등의 과정을 거치지 않고 xv6 위에 적재된다.
- 참고한 자료
- Makefile의
README
를 README list.txt
로 치환하면 된다. source
- fs.img
, PRINT
, EXTRA
부분이 수정될 것임
실행결과