[Pint OS] System Calls (2)

2023. 6. 11. 01:43·프로젝트/Pint OS

x86-64 기반 Pint OS 프로젝트 2의 System Calls를 구현하기 위해 공부한 개념을 정리한다.

 

User Memory Access

시스템 콜을 구현하기 전에, 유저가 보낸 포인터가 유효한 주소를 가리키는 지 확인할 필요가 있다. 만약에 유저 프로그램이 커널 영역을 조작하려고 한다면, 프로세스를 종료함으로써 막을 필요가 있다. 이외에도 포인터가 NULL 포인터인지, 유효한 페이지를 가리키는 지를 확인해야 한다.

 

check_address()

void
check_address(void *addr) {
    if (is_kernel_vaddr (addr) || addr == NULL || pml4_get_page(thread_current()->pml4, addr) == NULL) {
        exit (-1);
    }
}

 

syscall_handler()

유저 모드에서 유저 프로그램이 보낸 시스템 콜 요청을 커널 모드에서 받고, 커널 모드에서 시스템 콜 핸들러를 통해 시스템 콜을 처리한다. 주어진 스켈레톤 코드를 기반으로 구현하면 된다. 스켈레톤 코드는 시스템 콜 요청을 받으면, 프로세스를 종료하는 것으로 handling한다. 레지스터에 담긴 시스템 콜 번호와 인자를 읽고 적절하게 처리해주면 된다!

 

스켈레톤 코드

/* The main system call interface */
void
syscall_handler (struct intr_frame *f UNUSED) {
    // TODO: Your implementation goes here.
    printf ("system call!\n");
    thread_exit ();
}

 

시스템 콜 번호

int syscall_n = f->R.rax;

유저 프로그램에게서 받은 시스템 콜 번호는 syscall_handler 의 인자인 f->R.rax에 담겨있다. 이를 받아와서 처리해준다.

 

구현

switch (syscall_n) {
	case SYS_HALT:
		halt();
		break;
	case SYS_EXIT:
		exit(f->R.rdi);
		break;
	case SYS_FORK:
		f->R.rax = fork(f->R.rdi, f);
		break;
	case SYS_EXEC:
		f->R.rax = exec(f->R.rdi);
		break;
	case SYS_WAIT:
		f->R.rax = wait(f->R.rdi);
		break;
}

 

유저 모드에서는 시스템 콜 번호를 통해 시스템 콜을 요청한다. 따라서 커널 모드에서 이를 처리할 때도 시스템 콜 번호에 따라 처리해주어야 한다. 번호는 syscall-nr.h에 선언되어 있다. 단순히 switch 문으로 분기하면 된다.

 

그 외

  • 스켈레톤 코드 안에 있던 printf 문과 thread_exit () 함수는 지워야 한다.
  • 출력문이 다르면 fail되고, 시스템 콜을 한 번 처리하고 프로세스를 종료해서는 안 된다.

 

wait

유저 프로그램을 최초 실행할 때, Pint OS의 main() -> run_actions() -> run_task() -> process_wait(process_create_initd(task)) -> 유저 프로그램 실행 및 종료 대기 의 순서대로 실행한다. 유저 프로그램이 종료된 후에 Pint OS의 main() 을 종료하기 위해, process_wait() 을 실행한다. 그러나 프로세스 종료를 현재로선 알아내기 어렵고, 우선 반복문으로 아주 오래 기다려주기로 한다.

 

wait() 시스템 콜에서는 바로 process_wait() 을 호출하도록 한다.

 

wait()

int
wait (pid_t pid) {
    return process_wait (pid);
}

 

process_wait()

int
process_wait(tid_t child_tid) {
    /* XXX: Hint) The pintos exit if process_wait (initd), we recommend you
     * XXX:       to add infinite loop here before
     * XXX:       implementing the process_wait. */

    for (int i = 0; i < 1000000000; i++);
    return -1;
}

 

halt

Pint OS에서 제공하는 power_off() 함수를 사용해서 Pint OS를 강제 종료한다.

halt()

void
halt (void) {
    power_off ();
}

 

exit

현재 실행 중인 유저 프로그램(프로세스)를 종료한다. 현재 프로세스의 부모 프로세스가 wait()을 호출했다면, 이 status가 리턴될 것이다.

exit()

void
exit (int status) {
    struct thread *t = thread_current ();
    printf ("%s: exit(%d)\n", t->name, status);
    t->exit_status = status;
    thread_exit ();
}

 

write

write() 시스템 콜의 헤더는 다음과 같다.

 

int write (int fd, const void *buffer, unsigned size);

인자로 받은 fd(file descriptor)에 size만큼의 buffer를 입력해야 한다. fd는 표준 출력(stdout)이 될 수도 있고, 파일 출력이 될 수도 있다. 따라서 바로 구현하기 꽤나 어려운 함수이다. 그러나 테스트케이스를 pass하기 위해서는 유저 프로그램이 표준 출력(stdout)에 write할 수 있어야 한다. 따라서 우리는 fd가 stdout(1)인 경우에, putbuf() 라는 함수를 사용해서 표준 출력하는 것을 먼저 구현해야 한다.

 

Pint OS에서 제공하는 putbuf(buffer, size) 함수는 size 만큼의 buffer를 바로 콘솔에 출력시켜 준다! 이것을 바로 사용하면 된다.

write()

write (int fd, const void *buffer, unsigned size) {
    if (buffer == NULL)
        exit (-1);
    if (fd == 1) {
        putbuf (buffer, size);
    }
    return size;
}

'프로젝트 > Pint OS' 카테고리의 다른 글

[Pint OS] System Calls (4)  (0) 2023.06.11
[Pint OS] System Calls (3)  (0) 2023.06.11
[Pint OS] 에러: missing "begin" message  (0) 2023.06.09
[Pint OS] System Calls (1)  (0) 2023.06.07
[Pint OS] User Memory Access  (0) 2023.06.07
'프로젝트/Pint OS' 카테고리의 다른 글
  • [Pint OS] System Calls (4)
  • [Pint OS] System Calls (3)
  • [Pint OS] 에러: missing "begin" message
  • [Pint OS] System Calls (1)
KimCookieYa
KimCookieYa
무엇이 나를 살아있게 만드는가
  • KimCookieYa
    쿠키의 주저리
    KimCookieYa
  • 전체
    오늘
    어제
    • 분류 전체보기 (575) N
      • 혼잣말 (88)
      • TIL (3) N
      • 커리어 (24)
        • Sendy (21)
        • 외부활동 기록 (2)
      • 프로젝트 (186)
        • 티스토리 API (5)
        • 코드프레소 체험단 (89)
        • Web3 (3)
        • Pint OS (16)
        • 나만무 (14)
        • 대회 (6)
        • 정글 FE 스터디 (16)
        • MailBadara (12)
        • github.io (1)
        • 인공지능 동아리, AID (5)
        • 졸업과제 (18)
        • OSSCA 2024 (1)
      • 크래프톤 정글 2기 (80)
      • IT (168)
        • 코딩 (4)
        • CS (18)
        • 에러 (5)
        • 블록체인 (23)
        • Front-End (39)
        • 알고리즘&자료구조 정리 (3)
        • 코딩테스트 (3)
        • BOJ 문제정리 (41)
        • WILT (12)
        • ML-Agents (4)
        • 강화학습 (1)
        • Android (0)
        • LLM (2)
      • 전공 (1)
        • 머신러닝 (1)
      • 자기계발 (20)
        • 빡공단X베어유 (2)
        • 독서 (15)
  • 블로그 메뉴

    • 홈
    • 방명록
    • Github
    • Velog
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JavaScript
    니어프로토콜
    react
    졸업과제
    블록체인
    NEAR Protocol
    Flutter
    RNN
    글리치해커톤
    나만무
    딥러닝
    numpy
    해커톤
    파이썬
    Pint OS
    프로그래머스
    docker
    핀토스
    코드프레소
    pintos
    부산대
    머신러닝
    MailBadara
    센디
    알고리즘
    OS
    크래프톤정글
    사이드프로젝트
    자바스크립트
    리액트
  • hELLO· Designed By정상우.v4.10.3
KimCookieYa
[Pint OS] System Calls (2)
상단으로

티스토리툴바