지난 글에서 task 입력을 파싱해서 "파일이름 인자1 인자2"입력을
["파일이름", "인자1", "인자2"]로 나눠서 file_name에는 "파일이름"만 들어가도록
코딩을 했다.
하지만 root/userprog/syscall.c의 void syscall_handler (...)를 호출해서
system call!이 출력되었지만 시스템 콜 핸들러가 제대로 구현되지 않았기 때문에
이번에 root/userprog/syscall.c의 시스템 콜 함수들을 구현하고자 한다.
먼저 필요한 헤더파일을 include하고 작성할 함수 원형을 적어주자

...
#include <filesys/filesys.h>
...
void check_address(void *addr);
void get_argument(void *rsp, int *arg, int count);
void halt(void);
void exit(int status);
bool create(const char *file, unsigned initial_size);
bool remove(const char *file);
주소유효성 검사: 포인터가 가리키는 주소가 사용자 영역에 속해있는지 확인

/* 주소유효성 검사: 포인터가 가리키는 주소가 사용자 영역에 속해있는지 확인*/
void check_address(void *addr){
if(addr == NULL || addr < (void *)0x08048000 || addr > (void *)0xc0000000){
exit(-1);
}
}

/* 유저 스택에 있는 인자들을 커널에 저장
64비트 환경에서는 86-64 Call Convention(ABI)에 따라 인자들이 스택에 저장된다.
rsp는 스택 포인터를 가리키는 레지스터로, 유저 스택의 주소를 가리킨다. */
void get_argument(void *rsp, int *arg, int count){
int i;
for(i = 0; i < count; i++){
check_address(rsp);
arg[i] = *(int *)rsp;
rsp += 8;
}
}
이번 글에서는 총 4개의 시스템 콜 함수를 구현했는데
종류와 역할은 아래와 같다.
- void halt: PintOS 종료시키는 시스템 콜
- void exit: 현재 프로세스를 종료시키는 시스템 콜
- bool create: 파일을 생성하는 시스템 콜
- bool remove: 파일을 삭제하는 시스템 콜

/* pintos를 종료시키는 시스템 콜 */
void halt(void){
power_off();
}
/* 현재 프로세스를 종료시키는 시스템 콜 */
void exit(int status){
struct thread *curr_thread = thread_current();
printf("%s: exit(%d)\n", curr_thread->name, THREAD_DYING);
thread_exit();
}
/* 파일을 생성하는 시스템 콜 */
bool create(const char *file, unsigned initial_size){
check_address((void*)file); // void*로 묵시적 형변환을 하면 const속성이 사라질 수 있다.
return filesys_create(file, initial_size);
}
/* 파일을 삭제하는 시스템 콜 */
bool remove(const char *file){
check_address((void*)file); // void*로 묵시적 형변환을 하면 const속성이 사라질 수 있다.
return filesys_remove(file);
}
다음은 프로세스 계층구조 구현을 해보도록 하겠다.