개요

Implement system call infrastructure.

Implement the system call handler in userprog/syscall.c.

첫 프로젝트에서 CPU Protection, 즉 운영체제(커널)가 사용자 프로그램으로부터 주도권을 되찾을 수 있는 수단인 Timer 인터럽트를 다루었다. 이 타이머 인터럽트는 타이머 하드웨어에 의해 일어나므로 외부 인터럽트이다.

마찬가지로 OS는 소프트웨어에서 발생하는 예외도 다룰 수 있다. 소프트웨어 예외에는 Page Fault나 0으로 나누는 경우 등이 있을 수 있다. 또 하나 중요한 게 바로 시스템 콜이다.

시스템 콜의 과정(참고)

<aside> 💡 시스템 콜 엔트리와 do_iret()의 차이는? do_iret()은 인터럽트 프레임을 레지스터에 넣어 실행시키고 나면 다시 그 이전 프로세스로 되돌아오지 않는다.

</aside>

x86과는 다르게 x86_64 시스템에서는 syscall이라는 특별한 명령어를 제공한다. x86에서는 그냥 인터럽트 번호가 int 0x80이다. syscall 명령어는 시스템 콜 핸들러를 부를 수 있는 가장 빠른 방법이다.

사용자 프로그램은 syscall 명령어를 통해 시스템 콜을 보낼 수 있다. 이 때 다른 함수들을 호출할 때와 비슷하게 인자들과 리턴값이 레지스터에 저장되는데, 딱 두 가지가 다르다.

시스템 콜을 부른 사용자 함수의 레지스터 값은 struct intr_frame에서 확인할 수 있다.

그리고 리턴값이 있는 시스템 콜의 경우 그 리턴값을 해당 구조체의 rax를 수정해서 커널이 확인할 수 있다.