728x90
System call
- 응용 프로그램에서 운영체제에게 기능을 수행해달라고 요청하는 하나의 수단.
- user processor가 소프트웨어 인터럽트를 통해 커널의 기능을 이용하기 위한 서비스를 요청하는 하나의 방법.
- 소프트웨어 인터럽트
- 커널 영역의 기능을 사용자 모드가 사용 가능하게, 즉 프로세스가 하드웨어에 직접 접근해서 필요한 기능을 사용할 수 있게 해준다.
- 각 시스템 콜에는 고유한 번호가 할당되고 시스템 콜 인터페이스는 이러한 번호에 따라 인덱스 되는 테이블(IDT)을 유지된다
- IDT (Interrupt Descriptor Table) 테이블
- 리눅스에서는 인터럽트 처리를 위해서 IDT를 사용하는데 각 인터럽트를 처리하기 위한 서비스 루틴을 함수로 구현해두고, 각 함수의 시작점 주소(handler fucntion)를 IDT에 등록한다. ( Trap, syscall 포함)
- IDT는 메모리에 위치하고, 해당 IDT의 위치를 가리키는 레지스터를 IDTR이라고 한다.
- 작동순서
- 인터럽트 발생
- IDTR을 통해 IDT를 알아냄.
- 인터럽트 번호에 대응되는 테이블 엔트리에서 핸들러를 찾아, 루틴에 정의된 내용을 처리.
- IDT (Interrupt Descriptor Table) 테이블
사용 이유
- user가 애플리케이션으로 운영체제의 치명적인 데이터를 수정/삭제하는 권한을 막기 위해.
- 직접적인 하드웨어 요청이나 기타 시스템 요청은 OS가 제공하는 syscall을 통해 호출하도록 제공한다.
- user application이 syscall을 호출하여 사용하면 해당 app은 잠시 커널모드로 전환되는 작업을 거친다.
- 커널로 진입할 수 있는 방법
- Interrupt
- Trap
- System call
- 커널로 진입할 수 있는 방법
user Mode , Kernel Mode
Kernel
- 모든 시스템 메모리 영역에 접근이 가능하다.
- 모든 CPU명령 실행이 가능하다
- 운영체제에서 프로그램이 구동되는데에 있어 파일을 읽어오거나 쓰거나 화면에 메세지를 출력하는 등 많은 부분에 사용
user
- 접근할 수 있는 영역이 제한 되어있다 ( 하드웨어에 직접적인 접근 불가 == 프로그램의 자원에 관여할 수 없음)
- 사용자 애플리케이션 실행
- syscall 호출 시 일시적으로 커널모드로 전환하여 커널 영역의 기능을 사용자 모드가 접근하게 도와준다.
작동 방식
- user processor가 syscall을 요청하면 커널모드로 넘어간다.
- (커널은 각 syscall을 구분하기 위해서 기능별로 고유 번호를 할당 해 놓는다.)
- vi/usr/include/x86_64-linux-gnu/asm/unistd_64.h 명령을 사용하여 syscall의 고유 번호를 확인할 수 있다.
- (커널은 각 syscall을 구분하기 위해서 기능별로 고유 번호를 할당 해 놓는다.)
- 커널은 요청받은 syscall에 대응하는 기능 번호를 확인 후, 해당 번호에 맞는 루틴을 호출한다.
- 루틴을 모두 처리한 후 다시 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 호출
- syscall 고유의 번호를 define하여 저장한 후 syscall함수를 사용하여 fork 신호를 전송한다.
- system_call() 함수에서 호출된 syscall번호와 모든 레지스터를 스택에 저장하고 올바른 syscall번호인지 검사 후 sys_call_table에서 syscall번호에 해당하는 함수를 호출한다.
- 함수 종료 후 entry.S에 정의되어있는 ret_from_sys_call()함수에 의해 사용자 프로세서로 돌아간다.
- syscall함수로 gerpid 함수를 호출하여 자식프로세스의 pid가 출력되었는지 확인한다.
- fork 함수는 부모 프로세스에게는 자식프로세스의 PID를 반환하며 자식 프로세스에게는 0을 반환한다.
참고
728x90
'😒 저 저 저 개념없는 나 > 🍎 Linux' 카테고리의 다른 글
[리눅스 | Linux] 파이프라인, 리다이렉션 적용 예제 (0) | 2024.11.26 |
---|---|
[리눅스 | Linux] 리다이렉션 파이프라인 (0) | 2024.11.25 |
[리눅스 | Linux] 리눅스 패키지 | 디렉토리 구조 | 마운트 (0) | 2024.11.25 |
[Linux | c] fgets 함수 (0) | 2022.04.15 |
[Linux | C] memset 함수 (0) | 2022.04.15 |