😒 저 저 저 개념없는 나/🍎 Linux

[Linux] System call 작동 원리, 동작 예시

우주수첩 2022. 3. 23. 16:59
728x90

System call

  • 응용 프로그램에서 운영체제에게 기능을 수행해달라고 요청하는 하나의 수단.
  • user processor가 소프트웨어 인터럽트를 통해 커널의 기능을 이용하기 위한 서비스를 요청하는 하나의 방법.
  • 소프트웨어 인터럽트
  • 커널 영역의 기능을 사용자 모드가 사용 가능하게즉 프로세스가 하드웨어에 직접 접근해서 필요한 기능을 사용할 수 있게 해준다.
  • 각 시스템 콜에는 고유한 번호가 할당되고 시스템 콜 인터페이스는 이러한 번호에 따라 인덱스 되는 테이블(IDT)을 유지된다
    • IDT (Interrupt Descriptor Table) 테이블
      • 리눅스에서는 인터럽트 처리를 위해서 IDT를 사용하는데 각 인터럽트를 처리하기 위한 서비스 루틴을 함수로 구현해두고, 각 함수의 시작점 주소(handler fucntion)를 IDT에 등록한다. ( Trap, syscall 포함)
      • IDT는 메모리에 위치하고, 해당 IDT의 위치를 가리키는 레지스터를 IDTR이라고 한다.
      • 작동순서
        1. 인터럽트 발생
        2. IDTR을 통해 IDT를 알아냄.
        3. 인터럽트 번호에 대응되는 테이블 엔트리에서 핸들러를 찾아, 루틴에 정의된 내용을 처리.

사용 이유

  • user가 애플리케이션으로 운영체제의 치명적인 데이터를 수정/삭제하는 권한을 막기 위해.
  • 직접적인 하드웨어 요청이나 기타 시스템 요청은 OS가 제공하는 syscall을 통해 호출하도록 제공한다.
  • user application이 syscall을 호출하여 사용하면 해당 app은 잠시 커널모드로 전환되는 작업을 거친다.
    • 커널로 진입할 수 있는 방법
      1. Interrupt
      2. Trap
      3. System call

 


 

user Mode , Kernel Mode

 

Kernel

  • 모든 시스템 메모리 영역에 접근이 가능하다.
  • 모든 CPU명령 실행이 가능하다
  • 운영체제에서 프로그램이 구동되는데에 있어 파일을 읽어오거나 쓰거나 화면에 메세지를 출력하는 등 많은 부분에 사용

 

user

  • 접근할 수 있는 영역이 제한 되어있다 ( 하드웨어에 직접적인 접근 불가 == 프로그램의 자원에 관여할 수 없음)
  • 사용자 애플리케이션 실행
  • syscall 호출 시 일시적으로 커널모드로 전환하여 커널 영역의 기능을 사용자 모드가 접근하게 도와준다.

 


작동 방식

  1. user processor가 syscall을 요청하면 커널모드로 넘어간다.
    • (커널은 각 syscall을 구분하기 위해서 기능별로 고유 번호를 할당 해 놓는다.)
      • vi/usr/include/x86_64-linux-gnu/asm/unistd_64.h 명령을 사용하여 syscall의 고유 번호를 확인할 수 있다.
  2. 커널은 요청받은 syscall에 대응하는 기능 번호를 확인 후, 해당 번호에 맞는 루틴을 호출한다.
  3. 루틴을 모두 처리한 후 다시 user processor로 넘어온다.

 

 


 

처리 과정

1. C라이브러리에서 fork() syscall의 고유 번호를 확인 후 레지스터에 저장하고 $0x80인터럽트를 발생한다.

2. 커널은 IDT에서 $0x80 주소에 있는 syscall을 찾는다.

3. system_call() 함수에서 호출된 syscall번호와 모든 레지스터를 스택에 저장하고 올바른 syscall번호인지 검사 후 sys_call_table에서 syscall번호에 해당하는 함수를 호출한다.

4. 함수 종료 후 entry.S에 정의되어있는 ret_from_sys_call()함수에 의해 사용자 프로세서로 돌아간다.

 


 

user processor에서 syscall 함수를 사용하여 fork 호출

 

 

  1. syscall 고유의 번호를 define하여 저장한 후 syscall함수를 사용하여 fork 신호를 전송한다.
    • system_call() 함수에서 호출된 syscall번호와 모든 레지스터를 스택에 저장하고 올바른 syscall번호인지 검사 후 sys_call_table에서 syscall번호에 해당하는 함수를 호출한다.
    • 함수 종료 후 entry.S에 정의되어있는 ret_from_sys_call()함수에 의해 사용자 프로세서로 돌아간다.
  2. syscall함수로 gerpid 함수를 호출하여 자식프로세스의 pid가 출력되었는지 확인한다.
    • fork 함수는 부모 프로세스에게는 자식프로세스의 PID를 반환하며 자식 프로세스에게는 0을 반환한다.

 

 

참고

https://duksoo.tistory.com/entry/System-call-등록-순서 

https://min-310.tistory.com/142

728x90

'😒 저 저 저 개념없는 나 > 🍎 Linux' 카테고리의 다른 글

[Linux | c] fgets 함수  (0) 2022.04.15
[Linux | C] memset 함수  (0) 2022.04.15