개요


교육용 OS로 개발된 XV6의 시스템 콜 호출 과정을 알아보겠습니다.

시스템 콜은 커널 작업을 안전하게 수행할 수 있게 유저에게 제공하는 OS API 입니다.

시스템 콜 정의


usys.S

usys.S

SYSCALL(name) 매크로를 통해 name에 해당하는 시스템 콜을 정의합니다.

movl $SYS_ ## name, $eax;syscall.h에 정의되어 있는 SYS_name에 해당하는 번호를 eax 레지스터에 저장합니다.

이 값은 나중에 시스템 콜 포인터 함수를 검색할 때 키 값으로 사용됩니다.

참고)) ##은 왼쪽 토큰을 오른쪽 토큰에 붙히는 명령어 입니다.

syscall.h

syscall.h

int $T_SYSCALL는 시스템 콜 인터럽트를 발생시킵니다.

T_SYSCALL 상수는 trap.h에 정의 되어 있습니다.

trap.h

trap.h

xv6에서 $T_SYSCALL은 64로 정의되어 있습니다.

int $T_SYSCALL는 64번째 벡터를 가리키게 됩니다.

IDT


vectors.S

vectors.S
vectors.S

vectors.Svectors.pl을 실행시키면 생성됩니다.

이것은 trap.c에서 IDT를 초기화 할 때 사용됩니다.

IDT 초기화(trap.c)

IDT(Interupt Data Table)는 인터럽트의 정보가 담겨져 있는 테이블입니다.

trap.c

IDT에는 alltraps 분기하는 코드가 있습니다.

alltraps의 정의는 trapasm.S에 있습니다.

trapasm.S

trapasm.S

alltraps로 분기하게 되면 트랩에 필요한 스택 프레임을 쌓고 call trap을 실행합니다.

trap()


trap.c

trap.c

trapframe 구조체의 trapno(트랩 번호)를 확인하여 T_SYSCALL(64)이면 syscall()을 호출 합니다.

syscall()


syscall.c

syscall.c

syscall.c

syscall()은 매핑된 함수 포인터를 호출합니다.

defs.h 헤더 파일에 sys_ 함수들이 선언 되어 있고

프로세스 관련 시스템 콜 정의는 sysproc.c, 파일 관련 시스템 콜 정의는 sysfile.c에 있습니다.

XV6 시스템 콜 요약


system-call

리눅스와의 차이


리눅스(2.4 버전)에서는 entry.S 파일에서 system call을 호출하는데, xv6는 syscall.c에서 호출합니다.

분석 커널


mit-pdos/xv6-public