애플리케이션이 '커널 모드' 또는 '사용자 모드'에서 실행된다는 이야기를 들어본 적이 있을 것입니다. 사실 이는 운영체제가 작동하는 방식과 직결된 문제입니다. 운영체제의 동작 원리를 이해하고 나면 사용자 모드와 커널 모드의 차이도 어렵지 않게 파악할 수 있습니다.

운영체제가 하는 일 이해하기
컴퓨터는 하드웨어(전자 부품)와 소프트웨어(하드웨어가 실행하는 코드)로 구성됩니다. 하지만 이 둘이 어떻게 함께 작동하는지는 다소 생소할 수 있습니다.
컴퓨터의 가장 기본적인 요소는 비트(bit), 즉 '이진수'입니다. 컴퓨터가 수행하는 모든 작업은 0과 1로 표현되며, 각 부품은 서로 다른 방식으로 비트를 나타냅니다. CPU에서는 미세한 트랜지스터가 켜짐과 꺼짐 상태로 1과 0을 표현하고, 이러한 트랜지스터들이 논리 게이트(logic gate)라는 논리 구조로 배열됩니다.

전자식 메모리에서는 메모리 셀이 특정 임계값 이상 또는 이하의 전하를 가지는 방식으로 비트를 표현합니다. 기계식 하드디스크(HDD)에서는 회전하는 플래터 위의 자기 변화로, 광학 디스크(CD/DVD)에서는 레이저 빛을 반사하거나 반사하지 않는 홈(pit)과 평면(land)으로 비트를 나타냅니다.
이진 코드의 물리적 표현 방식이 무엇이든, 결국 모든 컴퓨터 부품은 이러한 원시적인 기계어 수준으로 환원됩니다.

그렇다면 사용자에게 친숙한 컴퓨터 인터페이스와 컴퓨터 내부의 저수준(low-level) 처리 과정은 어떻게 연결될까요? 바로 이 지점에서 운영체제가 등장합니다. 운영체제는 컴퓨터 하드웨어를 직접 제어합니다.
운영체제는 애플리케이션(그리고 그 사용자)이 원하는 모든 작업을 CPU와 다른 부품들이 이해할 수 있는 기계어 명령으로 변환합니다. 이 과정에서 가장 핵심적인 소프트웨어가 바로 커널(kernel)입니다.
커널이란 무엇인가?
커널은 이름 그대로 운영체제의 핵심입니다. 커널은 RAM에 상주하면서 컴퓨터가 하는 모든 작업을 지휘하는 소프트웨어로, 메모리에 무언가를 기록할 때 실행을 지시하는 주체 역시 커널입니다.
커널은 GPU나 네트워크 카드 같은 하드웨어와 통신하는 방법은 알지만, 해당 하드웨어를 최대 성능으로 끌어내는 방법은 모를 수 있습니다. 이 경우 커널은 컴퓨터 업계의 범용 표준에 의존하게 됩니다.

바로 이때 하드웨어 드라이버가 필요합니다. 드라이버는 운영체제에 특정 부품과 함께 작동하는 방법을 알려주는 소프트웨어입니다. 그렇기 때문에 Nvidia GPU와 AMD GPU에 서로 다른 드라이버가 필요한 것입니다.
적절한 드라이버를 갖춘 커널은 컴퓨터 내부의 최종 권한자로서, 치명적으로 데이터를 파괴할 수 있는 작업까지도 수행할 수 있습니다.
API(응용 프로그래밍 인터페이스)의 역할
MS-DOS 시절에는 소프트웨어 개발자가 사용자의 하드웨어에 맞춰 소프트웨어를 직접 작성해야 했습니다. MS-DOS 시스템에서 가장 악명 높았던 예가 바로 사운드 카드 드라이버였습니다.

특정 게임은 사운드 블래스터(Sound Blaster), AdLib, 그래비스 울트라사운드(Gravis Ultrasound) 등 당시 가장 널리 쓰이는 카드들을 지원해야 했고, 대다수 플레이어를 커버하기를 바랄 수밖에 없었습니다. 오늘날에는 API 덕분에 상황이 완전히 달라졌습니다.

마이크로소프트의 DirectX가 대표적인 예입니다. API에 대해 알아야 할 가장 중요한 점은, 소프트웨어 개발자가 GPU 같은 부품의 하드웨어 자원을 요청할 수 있는 표준화된 방법을 제공한다는 것입니다. 또한 하드웨어 제조사는 자사 제품이 DirectX 규격을 준수하기만 하면,同样하게 규격을 준수하는 어떤 소프트웨어와도 완벽하게 호환될 수 있습니다.
API는 소프트웨어 애플리케이션과 하드웨어 드라이버를 갖춘 저수준 커널 사이에서 번역 계층 역할을 합니다. 물론 약간의 성능 저하가 따르지만, 현대 컴퓨터에서는 그 영향이 미미하며 오히려 다양한 장점을 제공합니다. 그리고 바로 여기서 우리는 드디어 사용자 모드와 커널 모드의 이야기에 도달하게 됩니다.
사용자 모드 vs 커널 모드
현대 운영체제는 수백~수천 개의 '프로세스'를 동시에 실행하며, 우선순위와 필요한 연산 능력에 따라 각 프로세스에 CPU 시간을 동적으로 할당합니다.
애플리케이션을 실행하면 프로세스가 생성되고, CPU는 이를 사용자 모드 또는 커널 모드 중 하나로 실행합니다.
사용자 모드에서 실행되는 윈도우 프로세스는 자신만의 전용 가상 메모리 주소 공간과 핸들 테이블에만 접근할 수 있습니다. 소프트웨어는 이 테이블을 이용해 RAM에 데이터를 저장하고 자원을 요청합니다. 즉, 메모리나 다른 하드웨어에 직접 접근할 수 없으며, 이러한 가상 공간을 컴퓨터의 실제 하드웨어에 매핑하는 일은 운영체제의 몫입니다.

이 구조가 좋은 데에는 여러 이유가 있지만, 가장 중요한 이점은 애플리케이션이 자신의 가상 메모리 주소 공간 밖의 데이터를 덮어쓰거나 변경할 수 없다는 점입니다. 또한 사용자 모드 프로세스는 시스템 충돌이나 데이터 파괴를 유발할 수 있는 특정 기능의 사용이 제한됩니다.
반면 프로세스가 실행될 때 또는 승격될 때 커널 모드에 놓이면, 운영체제를 위해 예약된 영역을 포함한 시스템 자원에 대한 전체 접근 권한을 갖게 됩니다. 따라서 이론상으로는 운영체제가 정상적으로 작동하는 데 필요한 핵심 데이터조차 덮어쓸 수 있습니다.
트랩과 예외

주목할 점은 이 두 모드가 소프트웨어가 아닌 CPU 자체의 하드웨어 수준에서 강제된다는 것입니다. 사용자 모드에서 실행 중인 애플리케이션이 커널 모드 접근이 필요한 작업을 시도하면 '트랩(trap)' 또는 '예외(exception)'가 발생합니다. 그러면 운영체제가 해당 애플리케이션을 처리하는데, 보통은 프로그램을 종료하고 크래시 로그를 생성하여 개발자가 문제 발생 시점의 메모리 상태를 확인할 수 있도록 합니다.
커널 모드의 위험성: 블루스크린
컴퓨터를 강제로 종료하거나 재시작하게 만드는 블루스크린(BSOD)을 경험해 본 적이 있다면(경험하지 않은 사람은 없겠죠?), 그 원인이 커널 모드 프로세스였을 가능성이 높습니다.
커널 모드의 프로세스가 해서는 안 되는 작업을 수행하면 운영체제가 이를 복구할 수 없고, 컴퓨터 전체가 멈추게 됩니다. 반면 사용자 모드의 프로세스에 문제가 생기면 해당 애플리케이션만 충돌할 뿐, 나머지 소프트웨어와 운영체제는 아무 문제 없이 계속 작동합니다.

바로 이 부분에서 API가 중요한 역할을 합니다. 커널 모드 권한을 요청하는 주체는 API이며, 사용자 모드 애플리케이션은 본래 커널 모드 권한이 필요한 요청들을 API에 위임하는 셈입니다.
그렇기 때문에 커널 모드 권한은 일반적으로 컴퓨터 하드웨어에 직접 접근해야 하는 저수준 시스템 프로세스에만 부여됩니다. 보통 이 권한이 프로세스에 확장되는 이유는 사용자 모드보다 더 높은 성능이 필요하기 때문이며, 일부 CPU 명령은 커널 모드에서만 작동하므로 해당 기능이 필요한 프로세스는 승격되어야 합니다.
블루스크린 문제로 고생하고 있다면, 윈도우 10 블루스크인 문제 해결 가이드를 참고해 보시기 바랍니다.