PintOS PJT2 - syscall

김수환·2024년 11월 16일

PintOS

목록 보기
7/15

system call을 호출하는 open-normal 테스트 파일이 실행되는 데까지의 과정


pintos가 실행되면 threads/init.c의 main이 실행된다.


run_actions 호출


run_actions -> run_task 호출


run_task의 USERPROG 부분에서
process_wait(process_create_initd(task)가 호출


이후 동작 흐름

  1. run_task(argv)가 호출됩니다.
  2. argv[1]에 저장된 open-normal을 인자로 받아 process_create_initd("open-normal") 호출.
  3. 새로운 프로세스가 생성되어 open-normal 실행.
  4. open-normaltest_main() 함수가 호출되고, open("sample.txt") 수행.
  5. 파일 핸들이 적절히 반환되면 테스트 성공, 그렇지 않으면 실패.

argv[1]에 저장되는가?

argv[1]open-normal이 저장되는 것은 커맨드 라인 인자 전달의 일반적인 관례에 따른 것입니다:

  1. 전달 규칙
    • argv[0]: 실행되는 프로그램 자체의 이름(예: "pintos").
    • argv[1]: 실행할 작업(Task) 또는 프로그램 이름(예: "open-normal").
    • argv[2] 이후: 프로그램에 필요한 추가적인 인자들.

테스트 파일의 test_main 함수 안에서 open 함수를 호출


open을 호출한 것은 user program이기 때문에 우리가 구현한 userprog/syscall.c의 open이 불리는 것이 아니고, lib/user/syscall.c의 open이 불리게 된다.

그 안에서는 syscall1 함수를 리턴하고 있는데,
syscall 뒤의 숫자는 인자의 갯수를 의미한다.
즉, 인자가 하나인 syscall을 의미하는 syscall1이 호출

syscall1에서는 syscall이 호출되고 함수명에 맞게 인자가 전달된다.

syscall에 전달하는 인자를 보면
첫번째 인자는 시스템콜 넘버, 두번째 인자가 open에서 전달된 인자, 나머지는 0으로 채워져있다.


syscall에서는 레지스터에 인자를 담고나서 syscall을 호출하는 어셈블리어를 볼 수 있다.
이 syscall을 통해서 제어가 커널로 넘어가게 되고

드디어 userprog/syscall.c에 구현한 syscall_handler가 불리게 된다.


syscall_handler에서는 switch문을 통해 호출해야하는 시스템 콜 넘버에 해당하는 코드가 실행된다.
(여기서는 open)


여기서 불리는 open이 이번 과제에서 구현한 open 함수가 된다.

int open(const char *file) {
    check_address(file);
    struct file *newfile = filesys_open(file);

    if (newfile == NULL)
        return -1;

    int fd = process_add_file(newfile);

    if (fd == -1)
        file_close(newfile);

    return fd;
}

그리고 여기서 반환한 fd가 지금까지 거쳐 온 함수들에 반환된다.


이 fd가 최종적으로 테스트 파일인 open-normal에서 호출된 open에 반환되고, handle에 담기게 된다.

ref.
https://e-juhee.tistory.com/entry/KAIST-%EC%A0%95%EA%B8%80-9%EC%A3%BC%EC%B0%A8-System-Calls%EC%9D%B4-%ED%98%B8%EC%B6%9C%EB%90%98%EB%8A%94-%EA%B3%BC%EC%A0%95

profile
juniorDev

0개의 댓글