* ASSIGNMENT 2

 

- 이 과제에서는 프로세스 관리를 위한 system call을 구현한다. 이를 위하여 먼저, 소스코드를 분석하도록 한다.

 

- Assignment 2를 위한 준비: 이전과 동일하게, kern/compile에서 ASST2로 준비하도록 한다.

 

- 코드 분석: 아래 세 directory의 파일들을 분석하고, 질문에 답하도록 한다.

 

- 제출물: 질문에 대한 답변을 문서로 작성하여 리포트로 제출

 

- 제출기한: 11/6 (화)

 

kern/userprog: running user process

이 directory에는 user-level program을 적재하고 수행시키는 파일들이 있다. 제공되는 파일은 loadelf.c, runprogram.cuio.c 의 세 개이다. 

loadelf.c: ELF 형식의 수행 파일을 파일시스템으로부터 가상메모리로 적재한다. ELF 형식은 cs161-gcc가 생성하는 실행 파일의 포맷이다. (ASST2 상태에서는 아직 가상메모리가 제공되지는 않는다. 현재로서는 그냥 메모리에 적재하는 것.)

runprogram.c: runprogram() 함수 하나만 구현되어 있다. 커널 메뉴에서 프로그램을 수행할 때 사용이 된다. 나중에 execv() 시스템 호출을 구현할 때 참조할 수 있는데, 둘이 같은 것은 아니므로 그냥 참조만 할 것.

uio.c: 커널과 사용자 공간 사이의 데이터 이동을 위한 함수들이 들어 있다. lib/copyinout.c 도 같이 참조.

아래 질문에 답하라.
  1. ELF 의 매직 넘버(magic number)는 무엇인가?
  2. UIO_USERISPACE 와 UIO_USERSPACE 의 차이는 무엇인가? 언제 UIO_SYSSPACE 사용해야 하는가?
  3. 세그먼트에서 읽기를 위해 사용되는 struct uioload_segment() 에서 스택에 할당될 수 있는 이유는 무엇인가? (메모리 읽기는 실제로 어디에서 일어나는가?)
  4. runprogram()에서 사용자 모드로 가기전에 vfs_close() 를 꼭 불러야 하는 이유는?
  5. 어떤 함수가 프로세서를 사용자 모드로 전환시키는가? 이 함수는 machine-dependent 한가?
  6. copyin 과 copyout 이 정의된 파일은 어떤 것인가? 왜 copyin 과 copyout이 memmove로 간단하게 구현되지 않았는가?
  7. userptr_t는 어디에 쓰는 건가?

kern/arch/mips/mips: traps and syscalls

trap은 OS에서 예외를 처리하는 방법이고, syscall.c 는 시스템 호출에 의한 trap을 처리하는 파일이다. 이 directory의 코드를 이해하는 것은 OS의 동작을 이해하는 데 중요하다.

trap.c: mips_trap()는 OS로 제어를 옮기는 함수로, 어셈블리로 된 예외처리자에 의해 불리게 된다. md_usermode()는 사용자 프로그램으로 제어를 반환하는 함수이다. kill_curthread() 는 문제가 발생한 사용자 프로그램을 처리하는 함수로, 프로그램에서 처리하지 못하는 문제가 생기면 예외를 발생시킨다. 이 예외에서는 복구할 방법이 없고, 따라서 OS는 그 프로세스를 죽이게 된다.

syscall.c: mips_syscall()에서 시스템 호출의 실제 작업을 할 커널 함수로 연결되도록 한다. md_forkentry()는 fork() 시스템 호출을 구현하기 위한 stub으로 mips_syscall()에서 불리게 된다.

아래 질문에 답하라.
  1. MIPS 시스템 호출은 예외(trap) 코드 몇 번인가?
  2. mips_trap() 에서는 splhigh()를  쓰지 않고 왜 직접 curspl을 SPL_HIGH 로 설정하는가? 
  3. MIPS 인스트럭션은 몇 바이트인지가  mips_syscall() 함수에 어떻게 반영되어 있는가?
  4. kill_curthread()에서 수정되어야 할 것은 무엇인가?
  5. 매개변수(argument)가 4개인 시스템 호출을 작성하려면 어떻게 해야 하는가?

lib: user-level library code

lib/crt0: 사용자 프로그램 시작 코드이다. mips-crt0.S 파일 하나만 있고, main()을 시작해 준다execv() 를 구현할 때 참조해야 한다.

lib/libc: 사용자 수준 C library이다. 다 볼 필요는 없고, 필요할 때 참조만 하면 된다.

lib/errno.c: 전역 변수 errno 가 정의되어 있다.

lib/syscalls-mips.S: 시스템 호출에서 필요한 machine-dependent 코드가 있다.

lib/syscalls.S: 이 파일은 컴파일 시에 syscalls-mips.S 로부터 만들어진다. 시스템 호출의 실제 이름은 이 파일에 들어가는데, callno-parse.sh 라는 파일이 커널 헤더 파일들을 읽어서 만든다.

아래 질문에 답하라.
  1. SYSCALL 매크로의 역할은 무엇인가?
  2. 시스템 호출을 위한 진짜 MIPS 명령어는 무엇인가?