210210 개발일지(65일차) - 운영체제(OS) 프로젝트 #2-2 : System Call 구현(1)

고재개발·2021년 2월 11일
0

OS Project

목록 보기
12/28

pintOS에서 구현해야 하는 System call 종류는 아래와 같다.

<syscall-nr.h>
/* System call numbers. */
enum {
	/* Projects 2 and later. */
	SYS_HALT,                   /* Halt the operating system. */
	SYS_EXIT,                   /* Terminate this process. */
	SYS_FORK,                   /* Clone current process. */
	SYS_EXEC,                   /* Switch current process. */
	SYS_WAIT,                   /* Wait for a child process to die. */
	SYS_CREATE,                 /* Create a file. */
	SYS_REMOVE,                 /* Delete a file. */
	SYS_OPEN,                   /* Open a file. */
	SYS_FILESIZE,               /* Obtain a file's size. */
	SYS_READ,                   /* Read from a file. */
	SYS_WRITE,                  /* Write to a file. */
	SYS_SEEK,                   /* Change position in a file. */
	SYS_TELL,                   /* Report current position in a file. */
	SYS_CLOSE,                  /* Close a file. */

	/* Project 3 and optionally project 4. */
	SYS_MMAP,                   /* Map a file into memory. */
	SYS_MUNMAP,                 /* Remove a memory mapping. */

	/* Project 4 only. */
	SYS_CHDIR,                  /* Change the current directory. */
	SYS_MKDIR,                  /* Create a directory. */
	SYS_READDIR,                /* Reads a directory entry. */
	SYS_ISDIR,                  /* Tests if a fd represents a directory. */
	SYS_INUMBER,                /* Returns the inode number for a fd. */
	SYS_SYMLINK,                /* Returns the inode number for a fd. */

	/* Extra for Project 2 */
	SYS_DUP2,                   /* Duplicate the file descriptor */

	SYS_MOUNT,
	SYS_UMOUNT,
};

project2에서 구현할 14개의 시스템콜 코드를 알아보기 전에 시스템 콜 핸들러(System call handler)에 대해 알아보자.

시스템 콜 핸들러(Syscall handler)

시스템 콜 핸들러에서 시스템 콜 번호를 이용하여, 해당 시스템 콜을 호출한다.

아래의 코드와 같다.

void syscall_handler(struct intr_frame *f UNUSED)
{
    // TODO: Your implementation goes here.

    memcpy(&thread_current()->fork_tf, f, sizeof(struct intr_frame));
    uintptr_t *stack_pointer = f->rsp; // user_stack 을 가리키는 포인터
    
    switch (f->R.rax)
    {
    case SYS_HALT:
        halt();
        break;
    case SYS_EXIT:
        check_address(f->R.rdi);
        exit(f->R.rdi);
        break;
    case SYS_FORK:
        check_address(f->R.rdi);
        f->R.rax = fork(f->R.rdi);
        break;
    case SYS_EXEC:
        check_address(f->R.rdi);
        f->R.rax = exec(f->R.rdi);
        break;
    case SYS_WAIT:
        check_address(f->R.rdi);
        f->R.rax = wait(f->R.rdi);
        break;
    case SYS_CREATE:
        check_address(f->R.rdi);
        f->R.rax = create(f->R.rdi, f->R.rsi);
        break;
    case SYS_REMOVE:
        check_address(f->R.rdi);
        f->R.rax = remove(f->R.rdi);
        break;
    case SYS_OPEN:
        check_address(f->R.rdi);
        f->R.rax = open(f->R.rdi);
        break;
    case SYS_FILESIZE:
        check_address(f->R.rdi);
        f->R.rax = filesize(f->R.rdi);
        break;
    case SYS_READ:
        check_address(f->R.rdi);
        f->R.rax = read(f->R.rdi, f->R.rsi, f->R.rdx);
        break;
    case SYS_WRITE:
        check_address(f->R.rdi);
        f->R.rax = write(f->R.rdi, f->R.rsi, f->R.rdx);
        break;
    case SYS_SEEK:
        check_address(f->R.rdi);
        seek(f->R.rdi, f->R.rsi);
        break;
    case SYS_TELL:
        check_address(f->R.rdi);
        tell(f->R.rdi);
        break;
    case SYS_CLOSE:
        check_address(f->R.rdi);
        close(f->R.rdi);
        break;
    default:
        thread_exit();
        break;
    }
}

리턴 값이 있는 시스템 콜 함수는 f->R.rax에 그 리턴 값을 저장해준다.
+ 각 함수 실행 전 check_address() 함수로 주소유효성 검사를 한다. 포인터가 가리키는 주소가 사용자 영역(0x8048000~0xc0000000)인지 확인하고 유저 영역을 벗어난 영역일 경우 프로세스 종료(exit(-1)) 시킨다.

void check_address(void *addr)
{
    if(!is_user_vaddr(addr)){
        exit(-1);
    }
}

다음 포스팅부터 각 시스템콜 함수 구현을 확인 해보자~!

profile
고재개발

0개의 댓글