운영체제는 사용자와 하드웨어 사이의 인터페이스 역할을 하는 소프트웨어의 집합이다.
여기서 인터페이스
라는 단어를 사용한 이유는 사용자가 하드웨어를 직접 조종하지 않고 운영체제를 통해 하드웨어 자원의 사용을 제어하고 조종하는 중개자 역할을 하기 때문
운영체제는 크게 커널과 인터페이스로 이루어져 있다. 커널은 자원의 추상화와 관리가 이루어지는 공간이고 인터페이스는 각 커널과 상호작용하는 소프트웨어 계층 사이를 중개해주는 연결 장치를 말합니다.
커널은 운영체제의 핵심으로 하드웨어의 자원을 자원을 추상화하여 필요한 프로세스들에게 나눠주는 운영체제의 핵심 자원 관리자이다.
여기서 추상화를 사용한다는 것은, 하나의 하드웨어 자원을 논리적인 단위로 변환하여 여러 프로세스나 태스크들이 하드웨어를 직접 제어하지 않고도 사용할 수 있도록 중재자 역할을 한다는 의미이다.
커널은 각 하드웨어 자원들을 특정 관리자를 통해 추상화한다.
관리자 | 하드웨어 | 추상화 결과 |
---|---|---|
태스크 관리자 | CPU | 태스크(task) |
메모리 관리자 | 메모리 | 페이지(page), 세그먼트(segment) |
파일 시스템 관리자 | 디스크 | 파일(file) |
네트워크 관리자 | 네트워크 | 소켓(socket) |
이러한 관리자를 통해서 컴퓨터의 하드웨어에 대한 세부 사항들을 몰라도 사용자는 쉽고 일관된 방식으로 컴퓨터를 사용할 수 있게 된다.
커널의 구조에 따라 하드웨어 자원을 관리하고 시스템 호출을 처리하는 방식이 달라진다.
커널의 종류는 구조에 따라 크게 모놀리식 커널, 계층형 커널, 마이크로 커널, 하이브리드 커널로 나눌 수 있다.
모놀리식 커널
시스템 콜
: 시스템 콜이 호출되면 커널 내부에서 직접 처리된다.read()
시스템 콜을 호출하면 파일 시스템 모듈이 커널 내부에서 동작하여 파일을 읽는 작업을 수행한다.계층형 커널(Layered kernel)
시스템 콜
: 시스템 콜이 호출되면 해당 요청은 계층적으로 전달되며 처리된다.마이크로 커널
시스템 콜
: 시스템 콜은 커널에서 최소한의 작업(예: IPC로 요청 전달)을 수행하고, 실제 작업은 유저 모드 서비스에서 처리된다.read()
시스템 콜을 호출하면 파일 시스템 서버(유저모드)로 요청을 전달하고 해당 서버가 작업을 처리한 후 결과를 반환한다.하이브리드 커널
시스템 콜
: 시스템 콜은 커널 내부에서 처리되거나, 필요한 경우 일부 작업이 사용자 모드 서비스로 전달된다.운영체제는 시스템의 안전성과 보안을 위해 CPU 실행 모드를 사용자 모드(User Mode)와 커널 모드(Kernel Mode)로 구분하여 관리한다. 이를 Dual Mode라고 한다.
만약 이러한 듀얼 모드를 지원하지 않을 경우 (여러 응용 프로그램들이 CPU, 메모리 등의 자원에 직접적으로 접근하고 조작할 경우) 자원의 공유가 무질서하게 관리될 것이고 응용 프로그램들이 조금만 실수해도 컴퓨터 전체에 악영향을 끼칠 수 있을 것이다.
그렇기에 모드를 논리적으로 나누고 이 사이에 시스템 콜 인터페이스를 둠으로써 이를 막을 수 있다.
시스템 콜
을 통해 모드의 전환이 이루어진다.시스템 콜은 커널이 사용자나 프로그램이 커널에 직접 접근하는 것을 막기위해 만들어진 인터페이스이다.
시스템 콜 인터페이스는 User Space와 Kernel Space의 경계에서 동작하며, 커널 내부의 적절한 모듈로 요청을 전달하는 역할을 한다.
앞서 User 모드 와 Kernal Space의 사이에 시스템 콜을 통해 모드의 전환이 이루어진다고 했다.
즉, User Interface의 작업들이 커널이 관리하는 자원에 접근해야 할 때, System Call Interface를 통해 Kernel Space의 자원 관리자에게 요청이 전달되어 처리되는 것이다.
시스템 콜은 모든 커널에서 기본적으로 커널 모드에서 실행되지만, 커널의 구조에 따라 시스템 콜의 처리 위치와 방식이 약간씩 달라진다.
우리가 사용하는 대부분의 상용 운영체제(예: Linux, Windows, macOS)는 모놀리식 커널 또는 하이브리드 커널 기반으로 시스템 콜을 처리한다.
시스템 콜은 커널에서 지원하는 서비스에 따라 유형이 나뉜다. 크게 프로세스 제어, 파일 조작, 장치 관리, 정보 유지, 통신 등으로 조작할 수 있다.
카테고리 | 주요 작업 | 예시 |
---|---|---|
프로세스 제어 | 프로세스 생성, 종료, 대기 | fork(), exec(), wait() |
파일 관리 | 파일 열기, 읽기, 쓰기, 닫기 | open(), read(), write() |
디바이스 관리 | 디바이스와 데이터 입출력 | ioctl(), read(), write() |
정보 유지 | 시스템 정보 조회 및 설정 | getpid(), gettimeofday() |
통신 | 프로세스 간 데이터 교환 | pipe(), socket(), send() |
메모리 관리 | 메모리 할당, 해제 | mmap(), brk(), munmap() |
보안 | 인증 및 권한 관리 | setuid(), getuid(), chmod() |
서로 다른 시스템 콜의 구분.
- 시스템 콜 번호로 구분
운영체제는 각 시스템 콜에 고유한 번호를 부여한다. 시스템 콜 인터페이스는 이 번호를 통해 어떤 호출인지 식별할 수 있다. (ex.read()
는 시스템 콜 번호 3 으로 식별 가능)- 시스템 콜 이름 으로 구분
시스템 콜 인터페이스가 호출된 함수 이름으로 해당 작업을 구분 가능하다.- 인자(파라미터) 로 구분
전달된 인자(파일 디스크립터, 크기 등)를 통해 작업의 세부 사항을 파악한다.
명령 해석기 ( Command Interpreter )
사용자가 입력한 명령어를 해석하고 그에 따라 작업을 수행하는 프로그램
역할: 명령어를 파싱(parse)하고, 해당 명령어에 맞는 작업을 시스템에 요청하거나 프로세스를 실행.
명령 인터프리터의 구현 방식 두가지
- 명령 인터프리터 자체가 명령을 실행하는 방식:
- 명령 인터프리터 자체가 각 명령어를 처리하는 로직을 가지고 있음.
- 이 경우 명령어와 처리 로직이 인터프리터에 포함되어있어 새로운 명령어를 추가하려면 인터프리터 자체의 변경이 필요
- 예) echo
- 시스템 프로그램이 명령을 실행하는 방식:
- 명령 인터프리터가 명령을 실행할 코드 자체를 가지고 있는 대신 명령을 입력받으면 해당 명령어가 가리키는 쉘 스크립트 파일이나 바이너리 파일을 통해 실행됨.
- 예)
rm {파일이름}
:/bin/rm
경로의 바이너리 파일이{파일이름}
같은 파일을 삭제하는 수행.
CS 스터디를 하면서 조사했던 운영체제 부분을 정리해보았다.
아티클과 책들을 읽으며 정리하는 과정에서, 각 저자마다 커널과 시스템 콜의 역할을 다르게 설명하는 부분이 많아 교차검증에 시간이 많이 소요되었다.
알고 보니 실제로 커널마다 시스템 콜의 동작 방식과 구조가 달랐기 때문이었다.
이를 통해 개념적인 이해와 실제 구현의 차이를 이해하는 것이 얼마나 중요한지 다시 한번 깨달았다.
https://www.quora.com/What-is-the-difference-between-an-interpreter-and-a-shell
https://imbf.github.io/computer-science(cs)/2020/09/03/Operating-System-Structures.html
https://wikidocs.net/230921
https://hongong.hanbit.co.kr/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EB%9E%80-%EC%BB%A4%EB%84%90%EC%9D%98-%EA%B0%9C%EB%85%90-%EC%9D%91%EC%9A%A9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%8B%A4%ED%96%89%EC%9D%84-%EC%9C%84%ED%95%9C/