개요
OS에 대한 사전 지식은 해당 글을 참조하세요.
커널 (Kernel), 인터페이스 (Interface)
커널은 프로세스, 메모리 관리, 저장 장치 등의 운영체제의 핵심 기능을 담당하는 프로그램입니다.
자동차에 비유한다면, 엔진에 해당됩니다. 때문에 커널의 성능에 따라 운영체제의 성능이 결정됩니다.
물론 엔진만 던져두면 사람들이 이용하기가 힘들겁니다. 때문에 이용자가 편하게 이용하도록 계기판, 핸들, 브레이크, 변속 레버 등의 기능이 존재하는데, 인터페이스 또한 마찬가지입니다.
그냥 커널만 던져주면 이용자가 이용할 수 없으니, 인터페이스를 추가해서 이용자가 이용할 수 있도록 하게 됩니다.
이러한 인터페이스엔 TUI(Text based User Interface), GUI(Graphical User Interface)등의 UI(User Interface)로 구성되며, 커널과 인터페이스는 분리되어 있기 때문에, 커널은 같아도 인터페이스가 다르면 다른 운영체제가 됩니다.
과거 유닉스 커널을 주로 사용했는데, 유닉스 커널은 TUI 였습니다. 즉, 문자로된 명령을 내리는걸로 인터페이스를 사용했는데, 이를 셸(Shell, sh)이라 명칭하며, 셸 외에 bash 등의 인터페이스가 존재합니다.
지금이야 윈도우(Windows)하면 GUI지만, 과거 MS-DOS 시절엔 유닉스 커널과 마찬가지로 TUI 였습니다. 이는 명령 프롬프트(Command Prompt, cmd)이며, Shell과 함께 지금까지 전해져 내려오게 됩니다.
디바이스 드라이버 (Device Driver), 시스템 호출 (System Call)
지난 시간에 배우지 않은 용어가 등장했는데, 디바이스 드라이버는 정말 쉽게 말해서 하드웨어와 커널을 연결시켜주기 위해 존재합니다.커널과 하드웨어를 깡으로 연결하면 작동하지 않기 때문에, 하드웨어와 커널을 디바이스 드라이버를 통해 연결시키게 됩니다. 다른말로 하드웨어의 기능을 추상화해서, 커널에게 전달해주는 역할을 한다고 말할 수 있습니다.
이전 글에서 서술했듯이, 대부분은 운영체제에서 제공하나, 상황에 따라서 그래픽 카드와 같은 커널에서 제공하지 않는 기능들을 사용하기 위해, 외부 드라이버를 설치해야하는 경우도 존재합니다.
하드웨어와 직접적으로 연결되기 때문에, 보안상의 이유로 커널만이 디바이스 드라이버에 접근할 수 있습니다.
하드웨어 접근을 막았다고 해서 안전한게 아닙니다. 커널 또한 응용 프로그램이 마음대로 접근하면 피해을 줄 수 있으며, 이러한 경우를 보호하기 위해서 등장한 친구가 시스템 호출(또는 시스템 콜)입니다.
구조를 보면 인터페이스와 커널 사이에 존재하는데, 예상 했다 싶이, 시스템 호출을 통해서 커널에 접근할 수 있습니다.
시스템 호출 또한 일종의 인터페이스이며, 커널을 보호하기 위해 만들어졌습니다.
커널에 접근하는 프로그램들의 질서를 유지시켜주는 역할도 하는데, 예를 들어 어떤 자원에 write
한다고 가정했을때, 두 프로그램이 직접 접근했을때 문제가 발생할 수 있습니다.
이럴때 write()
라는 시스템 호출을 요청했을때, 시스템 호출이 문제가 발생하지 않도록 커널에 알려주게 됩니다.
커널에 접근하려면 반드시 시스템 호출을 거쳐야 하며, 자원 관리 등을 책임지기 때문에, 상당히 중요한 친구라 할 수 있습니다.
이러한 시스템 호출은 API로 제공되기도 하는데, 그 예시 중 하나가 Windows API입니다.
커널의 역할
컴퓨터의 주 목적은 여러 응용 프로그램을 실행하는 것이며, 프로그램이 시작되면 프로세스(process)라 부르게 됩니다.
커널은 이러한 프로세스가 실행될 수 있는 메모리, CPU 등의 환경을 조성하며, 이를 프로세스 관리라고 부르며, 메모리를 관리할땐 메모리 관리라 부릅니다.
파일 시스템을 다룰땐 파일 시스템 관리라고 부르며, USB 입력등의 입출력을 다룰땐 입출력 관리라 부릅니다.
또한 프로세스와 프로세스 간의 통신을 위해 프로세스 간 통신 관리가 존재합니다.
이렇듯 커널은 5개의 핵심 기능을 가지고 있는데, 정리하자면 아래와 같습니다:
기능 | 설명 |
---|---|
프로세스 관리 | 프로세스가 실행될 수 있도록 CPU 환경 조성 |
메모리 관리 | 프로세스에서의 메모리 관리 |
파일 시스템 관리 | 데이터의 저장/접근 등의 기능 제공 |
입출력 관리 | 입력/출력 기능 제공 |
프로세스 간 통신 관리 | 프로세스 간 통신을 위한 환경 제공 |
이들 모두 나중에 배우게 되며, 세부적인 내용은 이 글에서 다루지 않습니다.
그런데 이렇게 많은 기능을 다루려면 커널 또한 매우 복잡해질텐데, 때문에 커널의 종류가 나눠져 있습니다.
단일형 커널 (Monolithic Kernel)
가장 기본적인 형태의 커널이며, 프로그래밍으로 비유를 하자면, main() 함수에 모든걸 다 구현하는거라 생각하시면 편합니다. (물론 실제론 main() 안에 모든걸 구현하는건 아닙니다.)
장점으로는 오버헤드가 없어서 속도도 빠르고 설계하기도 쉽지만, 단점으로는
- 디버깅, 리팩토링 등의 버그(오류) 수정이나 코드 이해가 어렵습니다. 당연히 오류가 많으면 아무도 안씁니다.
- 1번과 비슷한 경우인데, 한 기능에 오류가 발생하면 다른 기능으로 퍼질 수 있습니다.
- 당연히 모듈화를 하지 않았으니, 이식성이 낮습니다.
- 요즘 운영체제를 따라가기가 힘듭니다. 모듈화하지 않았으니, 당연히 많은 기능도 없고, 이는 곧 운영체제를 구현하기 어려운 이유중 하나입니다.
- 여러 기능을 한곳에 집어넣었기 때문에, 커널의 크기가 커질 수 있습니다.
등이 존재합니다.
유닉스 커널이나 과거의 MS-DOS 등이 단일형 커널을 사용합니다.
리눅스 또한 단일형 커널을 사용하는데, 리눅스는 마이크로 커널의 특성 또한 섞여있는 커널입니다.
계층형 커널 (Layered Kernel)
단순하게 단일형 커널에서 모듈화를 진행한 커널이라 생각하시면 됩니다.
모듈화를 진행한 덕에 디버깅도 쉬워졌으며, 비교적으로 소스코드의 난해함도 해결된 커널 구조입니다.
마이크로 커널 (Micro Kernel)
단일형 커널과 계층형 커널엔 공통된 단점이 존재하는데, 바로 커널의 크기가 너무 커져버렸습니다.
크기가 크면 기능도 많고 좋지 않느냐라고 할 수 도 있지만, 역으로 생각해보면 디버깅 또한 어려워졌다고 볼 수 있습니다.
이러한 단점에 마이크로 커널이 만들어졌는데, 마이크로 커널은 프로세스 관리, 메모리 관리, 프로세스 간 통신 관리 등의 기본적인 기능만 구현되어있는 커널입니다.
즉, 커널 모드(Kernel Mode, 커널에서 다루는 기능)에서 기본적인 기능만 다루며, 유저 모드(User Mode)에서 파일 시스템 등을 다루는 커널이라 볼 수 있습니다.
또한 각각의 모듈은 독립적으로 작동하기 때문에, 한 모듈에서 오류가 발생해도 다른 모듈에 큰 영향을 끼치지 않습니다.
이러한 이유로 안전성이 높지만, 성능 자체는 느려진 편입니다.
단일형 커널과 마이크로 커널을 혼합한 혼합형 커널(Hybrid Kernel)이 존재하기도 합니다.
윈도우의 커널인 NT 커널이 혼합형 커널을 사용하며, XNU(마치 커널 (마이크로) + 단일형 BSD 커널, MacOS, iOS의 기반인 darwin의 기반 커널) 등이 혼합형 커널을 사용합니다.
이 밖에도 다른 구조의 커널도 존재하나, 보통 단일형 커널(또는 계층형 커널) 또는 마이크로 커널(또는 혼합 커널)을 주로 사용합니다. 이 둘은 간간히 논쟁의 주제가 되기도 합니다.