/* The main system call interface */
/** #Project 2: System Call - 시스템 콜 핸들러 */
void
syscall_handler (struct intr_frame *f UNUSED) {
// TODO: Your implementation goes here.
int sys_number = f->R.rax;
// Argument 순서
// %rdi %rsi %rdx %r10 %r8 %r9
switch (sys_number) {
case SYS_HALT:
halt();
break;
case SYS_EXIT:
exit(f->R.rdi);
break;
case SYS_FORK:
f->R.rax = fork(f->R.rdi);
break;
case SYS_EXEC:
f->R.rax = exec(f->R.rdi);
break;
case SYS_WAIT:
f->R.rax = process_wait(f->R.rdi);
break;
case SYS_CREATE:
f->R.rax = create(f->R.rdi, f->R.rsi);
break;
case SYS_REMOVE:
f->R.rax = remove(f->R.rdi);
break;
case SYS_OPEN:
f->R.rax = open(f->R.rdi);
break;
case SYS_FILESIZE:
f->R.rax = filesize(f->R.rdi);
break;
case SYS_READ:
f->R.rax = read(f->R.rdi, f->R.rsi, f->R.rdx);
break;
case SYS_WRITE:
f->R.rax = write(f->R.rdi, f->R.rsi, f->R.rdx);
break;
case SYS_SEEK:
seek(f->R.rdi, f->R.rsi);
break;
case SYS_TELL:
f->R.rax = tell(f->R.rdi);
break;
case SYS_CLOSE:
close(f->R.rdi);
break;
case SYS_DUP2:
f->R.rax = dup2(f->R.rdi, f->R.rsi);
break;
default:
exit(-1);
}
}
syscall_handler 함수는 시스템 호출(System Call)을 처리하는 핵심 함수로, 사용자 공간에서 커널 공간으로 전달된 시스템 호출 번호와 매개변수에 따라 적절한 커널 함수로 요청을 분배합니다.
struct intr_frame에 저장된 시스템 호출 정보를 기반으로 적절한 시스템 호출을 실행합니다.sys_number)를 확인하여 호출된 시스템 함수에 매핑합니다.rax에 저장해 호출한 프로세스에 반환합니다.c
코드 복사
int sys_number = f->R.rax;
rax 레지스터는 시스템 호출 번호를 저장합니다.시스템 호출 매개변수는 레지스터를 통해 전달됩니다:
%rdi, %rsi, %rdx, %r10, %r8, %r9예를 들어:
SYS_EXIT 호출 시, exit() 함수는 첫 번째 인자를 rdi 레지스터를 통해 전달받습니다.SYS_READ 호출 시, read() 함수는 세 개의 인자를 rdi, rsi, rdx를 통해 전달받습니다.c
코드 복사
switch (sys_number) {
case SYS_HALT:
halt();
break;
case SYS_EXIT:
exit(f->R.rdi);
break;
case SYS_FORK:
f->R.rax = fork(f->R.rdi);
break;
...
}
switch문을 사용하여 시스템 호출 번호에 따라 적절한 커널 함수로 분기합니다.f->R.rdi, f->R.rsi, f->R.rdx 등 레지스터에서 매개변수를 추출하여 커널 함수에 전달합니다.f->R.rax에 저장하여 호출 프로세스에 전달합니다.| 시스템 호출 번호 | 설명 | 활용된 매개변수 |
|---|---|---|
SYS_HALT | 시스템 종료 | 없음 |
SYS_EXIT | 현재 프로세스 종료 | rdi: 종료 코드 |
SYS_FORK | 프로세스 복제 | rdi: 프로세스 이름 |
SYS_EXEC | 프로그램 실행 | rdi: 프로그램 경로 |
SYS_WAIT | 자식 프로세스 대기 | rdi: 자식 프로세스 ID |
SYS_CREATE | 파일 생성 | rdi: 파일 이름, rsi: 크기 |
SYS_REMOVE | 파일 삭제 | rdi: 파일 이름 |
SYS_OPEN | 파일 열기 | rdi: 파일 이름 |
SYS_FILESIZE | 파일 크기 조회 | rdi: 파일 핸들 |
SYS_READ | 파일 읽기 | rdi: 핸들, rsi: 버퍼, rdx: 크기 |
SYS_WRITE | 파일 쓰기 | rdi: 핸들, rsi: 버퍼, rdx: 크기 |
SYS_SEEK | 파일 위치 이동 | rdi: 핸들, rsi: 위치 |
SYS_TELL | 파일 현재 위치 조회 | rdi: 핸들 |
SYS_CLOSE | 파일 닫기 | rdi: 핸들 |
SYS_DUP2 | 파일 디스크립터 복제 | rdi: 원본 핸들, rsi: 대상 핸들 |
사용자는 시스템 호출 인터페이스를 통해 커널 기능을 요청합니다:
c
코드 복사
#include <syscall.h>int fd = open("test.txt");
if (fd < 0) {
exit(-1);
}
write(fd, "Hello, Pintos!", 14);
close(fd);
open(), write(), close() 등은 시스템 호출 인터페이스를 통해 syscall_handler로 전달됩니다.syscall_handler는 위와 같은 시스템 호출을 인터럽트 프레임에서 읽어 처리합니다.SYS_WRITE의 경우 write() 커널 함수를 호출하여 파일 시스템의 쓰기 작업을 수행합니다.default 분기로 이동하여 프로그램을 종료합니다:c
코드 복사
default:
exit(-1);
이 코드는 사용자 프로그램과 커널 사이의 인터페이스를 구현한 중요한 모듈입니다. 시스템 호출 번호에 따라 적절한 커널 함수로 요청을 분배하며, 매개변수 전달과 결과 반환을 위한 구조를 효율적으로 처리합니다. 이를 통해 사용자 프로그램은 커널 기능을 간단하게 사용할 수 있습니다.