운영체제

xv6 - System call

va95 2021. 3. 19. 03:01

시스템콜 과정

 

1. 사용자 프로그램에서 myfunction() 사용

2. user.h에 myfunction()함수가 선언되어있으며

   usys.S에 링크되어 있다.(여기서 .S는 어셈블리어)

3. usys.S에 어셈블리 코드로

 

#include "syscall.h"   <-   여기에 SYS_myfunction의 번호가 저장되어있다.

 

#define SYSCALL(name)   <-   myfunction()의 정의가 이 부분이다.(유저 영역에서의 시스템콜은 모두 옆처럼 정의 되어 있다.)

    .globl name;

    name:

        movl $SYS_ ## name, %eax;

        int $T_SYSCALL;   <-   interrupt로 64를 호출

        ret

 

즉, 유저 영역에서 사용되는 시스템콜의 정의는 단순히 번호를 eax에 넣고 인터럽트를 발생하는 것

 

4. int $T_SYSCALL;로 인해 syscall.c의 syscall()함수가 호출됨

eax의 값을 보고 어떤 SYS_<...> 번호가 호출됬는지 알아냄 <- syscall.h에 번호로 저장되어있음

우선, syscalls[]에 index로 SYS_<...>를 넘겨주면 해당 함수의 포인터를 반환

static int (*syscalls[])(void) = {

[SYS_myfunction]    sys_myfunction,

...

}

 

5. 커널 모드의 시스템 콜과 이의 wrap 함수인 sys_myfunction()은 defs.h에 선언되어 있다.

유저 모드의 시스템 콜을 호출할 때 사용되었던 인자들은 유저 스택에 쌓여있고, 현재는 커널 모드이기 때문에 커널 스택에 있다.

따라서 유저 스택에 접근해서 인자들을 가져올 필요가 있고, 이때 argstr을 통해서 유저 스택에 저장되어있는 인자들을 가져올 수 있다.

바로 커널 모드의 시스템 콜을 사용하기 보다 wrap 함수를 통하여 인자들을 가져온 뒤, 커널 모드의 시스템 콜을 호출하면 된다.

(defs.h는 커널 영역에서 사용되는 시스템 콜을 위한 헤더 파일이다.)