CS 스터디를 하며 사용자 모드에서 실행되는 프로그램이 운영체제의 핵심인 커널에게 서비스를 요청할 때 사용하는 인터페이스인 시스템 콜에 대해 조금 더 자세히 알아보고자 하였다. 시스템 콜에 대해 알기 위해서는 커널에 대해 알아야 했기에 커널모드와 사용자 모드에 대해서도 정리를 하였다.
커널모드(Kernerl Mode)와 사용자 모드(User Mode)
프로세스가 실행되는 동안 커널 모드와 사용자 모드를 반복적으로 넘나든다. 사용자 애플리케이션은 시스템 서비스를 호출할 때 사용자 모드에서 커널 모드로 전환한다.
커널 모드(Kernerl Mode)
커널 모드에서는 운영체제의 핵심 부분인 커널이 실행된다.
커널 모드에서 실행되는 코드는 운영체제가 필요한 다양한 작업을 수행하기 위해 컴퓨터의 모든 하드웨어 자원과 메모리에 접근할 수 있다.
응용 프로그램이 하드웨어 자원이나 특정 시스템 기능에 접근하려 할 때, 시스템 콜을 통해 커널모드로 전환된다.
커널 모드는 운영체제의 핵심 부분을 포함하므로 잘못된 접근이나 오류는 시스템 전체에 심각한 문제를 발생시킬 수 있다.
✨ 커널이란?
커널은 컴퓨터 운영체제의 핵심이 되는 컴퓨터 프로그램으로 시스템의 모든 것을 완전히 제어한다. 운영체제의 다른 부분 및 응용 프로그램 수행에 필요한 여러 서비스를 제공한다.
커널은 시스템이 부팅될 때 (컴퓨터가 켜질 때) 메모리에 상주하게 된다. 소프트웨어가 컴퓨터 시스템에서 수행되기 위해서는 메모리에 프로그램이 올라가있어야 하는데 마찬가지로 운영체제 자체도 컴퓨터가 켜져 있을 동안 항상 메모리에 머물러 있어 시스템의 기본적인 기능을 수행할 수 있어야 한다.
운영체제의 다른 부분들 (규모가 큰 프로그램들)이 모두 메모리에 올라가면 메모리가 부족할 것이가 때문에 항상 필요한 부분들만 전원 on과 동시에 메모리에 올려놓고 필요 없는 부분들은 필요할 때만 올려서 실행된다.
이 때 메모리에 상주하는 부분들이 커널이다.
사용자 모드(User Mode)
사용자 모드에서는 응용프로그램들이 실행된다.
사용자 모드에서 실행되는 프로그램은 직접적으로 하드웨어 자원에 접근할 수 없다. 필요한 경우에는 시스템 콜을 통해 커널 모드로 전환하여 해당 작업을 수행해야 한다.
사용자 모드에서 실행되는 프로그램은 독립적인 메모리 영역을 가진다. 따라서, 하나의 프로그램에서 오류가 발생하더라도 다른 프로그램이나 전체 시스템에 큰 영향을 주지 않는다.
사용자 모드는 일반적인 프로그램 실행에 필요한 기능만을 제공하므로, 커널 모드보다 더 효율적으로 실행될 수 있다.
시스템 콜(System Call)
사용자 모드에서 실행되는 프로그램이 운영체제의 핵심인 커널에게 서비스를 요청할 때 사용하는 인터페이스이다. 일반적으로, 프로그램은 직접 하드웨어나 다른 중요한 자원에 접근할 수 없기 때문에, 이러한 자원들을 안전하게 관리하고 제어하기 위해 운영 체제를 통해 접근해야 한다.
✨ 보통 C나 C++같은 고급언어로 작성된 프로그램 들은 직접 시스템 호출을 사용할 수 없기 때문에 고급 API를 통해 시스템 호출에 접근하게 하는 방법을 말한다.
고급 언어 API 사용 장점
- 추상화
- 복잡한 시스템 콜의 세부사항을 고민할 필요 없이 기능 사용 가능
- 이식성
- 동일한 API 함수가 여러 운영체제나 플랫폼에서 동작할 수 있기 때문에 이식성이 증가
- 간결성
- 직접 시스템 콜을 관리하는 것 보다 간결하고 읽기 쉽다.
자바(Java) 는?
자바는 자체 표준 클래스 라이브러리를 통해 이러한 시스템 콜과 같은 기능을 제공하기 때문에 시스템 콜을 직접 호출하지 않는다.
자바 가상머신(JVM, Java Virtual Machine)
- Java 프로그램은 JVM 위에서 실행되므로, 운영 체제의 직접적인 시스템 콜을 호출하지 않음
- JVM이 플랫폼에 맞게 시스템 콜을 내부적으로 처리하고, Java 애플리케이션은 이러한 세부사항을 신경 쓸 필요가 없다.
자바의 시스템 콜
직접적인 시스템 콜 호출이 필요한 경우(예: 매우 특수한 하드웨어 조작이 필요한 경우), Java는 네이티브 메소드를 사용하여 이를 지원한다.
Java Native Interface (JNI)를 통해 C나 C++ 코드와 같은 네이티브 코드를 호출하게 해주며, 이 네이티브 코드 내에서 시스템 콜을 할 수 있다.
하지만 이 방법은 복잡하고, 플랫폼에 종속적이며, 보안 문제를 야기할 수 있어 일반적인 상황에서는 권장되지 않는다.
시스템 콜의 목적
시스템 콜의 종류
시스템 콜의 동작
- 사용자 프로세스가 시스템 콜 호출(커널 모드 진입)
- open()에 매칭된 커널 함수 sys_open()을 실행 - 커널은 내부적으로 시스템 콜을 구분하기 위해 기능별로 고유번호를 할당하고 번호에 해당하는 제어 루틴 정의
- 커널은 요청받은 시스템 콜에 대응하는 고유번호 확인 후 번호에 맞는 서비스 루틴 호출
- 커널은 서비스 루틴 처리 후 사용자 모드로 전환
예시
우리는 cmd 창에서 명령어를 사용하면 내부에서는 아래의 동작들이 이루어진다.
✅ cp 명령어로 in.txt 파일을 out.txt 파일로 복사
cp in.txt out.txt
- open() - 파일을 열 때 사용한다. 여기서는 in.txt와 out.txt 두 번 호출됨
- read() - in.txt에서 내용 읽을 때 사용
- write() - out.txt에 내용 쓸 때 사용
- close() - 작업이 끝난 후 파일을 닫을 때 사용
🔻 실제 시스템 콜 과정
- Acquire input file name: 사용자로부터 복사할 원본 파일의 이름을 받습니다.
- Write prompt to screen: 사용자에게 입력을 요청하는 메시지나 프롬프트를 화면에 출력합니다.
- Accept input: 사용자의 입력을 받아들입니다.
- Acquire output file name: 사용자로부터 복사될 대상 파일의 이름을 받습니다.
- Write prompt to screen: 사용자에게 입력을 요청하는 메시지나 프롬프트를 다시 화면에 출력합니다.
- Accept input: 사용자의 입력을 받아들입니다.
- Open the input file: 원본 파일을 열려고 시도합니다.
- If file doesn't exist, abort: 만약 원본 파일이 존재하지 않다면 프로세스를 중단합니다.
- Create output file: 대상 파일을 생성합니다.
- If file exists, abort: 만약 대상 파일이 이미 존재한다면 프로세스를 중단합니다.
- Loop: 이 부분은 파일 내용을 복사하는 과정을 나타냅니다.
- Read from input file: 원본 파일에서 데이터를 읽습니다.
- Write to output file: 읽은 데이터를 대상 파일에 씁니다.
- Until read fails: 읽기가 실패할 때까지 위의 두 단계를 반복합니다.
- Close output file: 대상 파일을 닫습니다.
- Write completion message to screen: 작업이 완료되었음을 사용자에게 알리는 메시지를 화면에 출력합니다.
- Terminate normally: 프로세스를 정상적으로 종료합니다.
✅ ls 명령어로 목록 표시
ls
- 현재 디렉토리 가져오기 - ls명령어를 실행하면 현재 작업 중인 디렉토리의 내용이 기본적으로 표시된다. 현재 디렉토리를 가져오기 위해 getcwd()라는 시스템 콜이 사용될 수 있다.
- 디렉토리 열기 -디렉토리의 내용을 읽기 위해 opendir()라는 시스템 콜을 사용한다.
- 디렉토리 읽기 - readdir() 시스템 콜을 사용하여 디렉토리의 내용을 순차적으로 읽는다.
- 디렉토리 내용 출력 - write() 시스템 콜을 사용하여 터미널에 디렉토리의 내용을 출력한다.
- 디렉토리 닫기 - 모든 내용을 읽은 후 closedir() 시스템 콜을 사용하여 디렉토리를 닫는다.
시스템 콜은 운영체제의 핵심 요소 중 하나로 응용 프로그램으로부터 직접적인 하드웨어 접근을 제한해서 시스템의 안전을 보장하고 효율적인 통신을 가능하게 한다. 개발자로부터 복잡한 하드웨어와 직접 통신하지 않고 자원을 활용할 수 있게 해주며 모든 프로그램이 일관된 API를 통해 시스템 자원을 사용할 수 있게 해준다는 장점이 있다.
📖 참고 자료
'KNOWLEDGE' 카테고리의 다른 글
[디자인 패턴] 싱글톤 패턴 (Singleton Pattern) - 자바 예제 (1) | 2024.04.15 |
---|---|
[OS] 페이징, PTBR, TLB(Translation Lookaside Buffer, 변환색인 버퍼) 란 무엇인가? (0) | 2023.12.14 |
[NETWORK] REST API, RESTful 알아보기 / REST란? (1) | 2023.11.16 |
[OS] CPU 스케줄링 알고리즘 / 프로그램 vs 프로세스 vs 스레드 (2) | 2023.11.08 |
[NETWORK] TCP 의 연결 및 해제 과정 (3-Way Handshake / 3-Way Handshake) (1) | 2023.10.30 |