System Calls 과제의 목표는 시스템 콜 핸들러 및 시스템 콜을 구현하는 것이다.
기존의 PintOS 운영체제는 시스템 콜 핸들러가 구현되어 있지 않아 시스템 콜이 호출될 수 없으므로 응용 프로그램이 정상적으로 동작하지 않는다.
시스템 콜(halt, exit, create, remove)을 구현하고 시스템 콜 핸들러를 통해 호출한다.
시스템 콜은 운영 체제가 제공하는 서비스에 대한 프로그래밍 인터페이스이다.
시스템 콜은 사용자 모드 프로그램이 커널 기능을 사용할 수 있도록 한다.
시스템 콜은 커널 모드에서 실행되고, 처리 후 사용자 모드로 복귀한다.
시스템 콜 핸들러를 구현하기 위해서는 시스템 콜 핸들러에서 시스템 콜 번호에 해당하는 시스템 콜을 호출해야 한다.
시스템 콜 핸들러에서 유저 스택 포인터(esp) 주소와 인자가 가리키는 주소(포인터)가 유저 영역인지 확인해야 한다.
유저 영역을 벗어난 주소를 참조할 경우 페이지 폴트 오류가 발생한다.
유저 스택에 있는 인자들을 커널에 저장해야 한다.
시스템 콜의 함수의 리턴 값은 인터럽트 프레임의 eax에 저장한다.
halt(), exit(), create(), remove() 시스템 콜을 구현한다.
시스템 콜 번호를 이용하여 시스템 콜 핸들러에서 해당 시스템 콜을 호출한다.
시스템 콜 핸들러에서 유저 스택 포인터 주소와 인자가 가리키는 주소가 유저 영역인지 확인하기 위해 check_address() 함수를 구현해야 한다.
유저 스택에 있는 인자들을 커널에 저장하기 위해 get_argument() 함수를 구현해야 한다.
유저 스택에 저장된 시스템 콜 넘버에 해당하는 시스템 콜을 호출하기 위해 syscall_handler 함수를 생성한다.
syscall_handler 함수는 스택 포인터가 유저 영역인지 확인하는 get_argument() 함수와 저장된 인자 값이 포인터일 경우 유저 영역의 주소인지 확인하는 check_address() 함수를 포함한다.
PintOS를 종료시키는 halt()와 현재 프로세스를 종료시키는 exit() 시스템 콜을 구현한다.
파일을 생성하는 create()와 파일을 삭제하는 remove() 시스템 콜을 구현한다.
halt()는 shutdown_power_off()를 사용하여 PintOS를 종료하도록 한다.
exit() 실행 중인 쓰레드 구조체를 가져와 종료하도록 한다.
create()는 파일 이름과 크기에 해당하는 파일을 생성하도록 한다.
remove()는 파일 이름에 해당하는 파일을 제거하도록 한다.
check_address() 함수는 주소값이 유저 영역에서 사용하는 주소값인지 확인한다. 시스템 콜이 접근할 수 있는 주소인 유저 영역인 0x8048000~0xc0000000을 벗어난 영역인 경우 프로세스를 종료한다.
get_argument() 함수는 유저 스택에 있는 인자들을 커널에 저장한다. 스택 포인터(esp)에 인자의 갯수(count) 만큼의 데이터를 arg에 저장한다.