본 포스팅은 인프런의 개발자를 위한 컴퓨터공학 1: 혼자 공부하는 컴퓨터구조 + 운영체제를 참조하여 작성한 글입니다.
컴퓨터 부품들은 전기만 공급하면 마치 마법처럼 알아서 작동하는 것은 아니다. 운영체제라는 특별한 프로그램의 지휘하에 동작한다.
모든 프로그램은 실행을 위해 자원을 필요로 한다. 여기서 자원이란 프로그램 실행에 있어서 마땅히 필요한 요소를 말한다. 쉽게 생각해서 우리가 컴퓨터 구조론때 학습한 4가지 핵심 부품을 쉽게 자원이라고 생각하면 좋을 것이다. 운영체제는 실행할 프로그램에 핗요한 자원을 할당하고 프로그램이 올바르게 실행되도록 돕는 특별한 프로그램이라고 생각하면 좋을 것 같다.
운영체제는 인터넷 브라우저, 게임과 같은 프로그램이다. 그래서 운영체제 또한 어느 프로그램과 마찬가지로 메모리에 적재되어야 한다. 다만 운영체제는 매우 특별한 프로그램이기 때문에 항상 컴퓨터가 부팅될 때 메모리 내 커널 영역 이라는 공간에 따로 적재되어 실행된다. 커널 영역을 제외한 나머지 영역, 사용자가 이용하는 응용 프로그램이 적재되는 영역을 사용자 영역 이라고 한다. 즉, 운영체제는 커널 영역에 적재되어 사용자 영역에 적재된 프로그램들에 자원을 할당하고 이들이 올바르게 작동하도록 돕는다.
응용 프로그램이란, 사용자가 특정 목적을 위해 사용하는 일반적인 프로그램이다.
그러면 하나 궁금한게 생긴다. 이ㄴ 프로그램들은 누가 메모리에 적재하였을까? 우리는 프로그램을 실행할 때 몇 번지에 저장하라고 지정하지 않는데 누가 메모리 주소를 할당해서 적재시킬까? 바로 운영체제이다. 운영체제는 실행할 프로그램을 메모리에 적재하고 더 이상 실행되지 않는 프로그램을 메모리에서 삭제하며 지속적으로 메모리 자원을 관리한다. 또한, 운영체제는 어느 프로그램이 CPU를 얼마나 쓸지를 관리한다. 즉, CPU를 관리한다고 보면 좋을 것 같다. 또한, 운영체제는 동시에 2개의 프로그램이 입출력 장치에 접근하려고 할 때 이를 막고 하나의 프로그램이 입출력 장치를 이용하는 동안 다른 프로그램을 기다리게 만들어 자원을 관리한다. 마지막으로 운영체제는 응용 프로그램에 자원을 효율적으로 배분하고 실행할 프로그램들이 지켜야 할 규칙을 만들어 컴퓨터 시스템 전체를 관리한다. 마치 정부의 역할을 하는 것 같다.
운영체제 없이 개발을 한다면 어떨까? 상상만 해도 끔찍할 것이다. 만약 1과 2를 더한 결과를 모니터에 출력하는 간단한 프로그램을 만들어 본다고 해보자. 운영체제가 없다면 프로그램을 메모리에 적재하는 코드를 작성해야 할 것이고 CPU로 하여금 1과 2를 더하게 하는 코드도 작성해야 하며 모니터에 계산 결과를 출력하는 코드도 작성해야 한다. 운영체제 덕분에 개발자는 이런 것 없이 하드웨어를 조작하는 코드 없이 편하게 개발을 할 수 있는 것이다.
그렇다면 운영체제는 왜 알아야 할까? 운영체제는 사용자를 위한 프로그램이 아닌 프로그램을 위한 프로그램이다. 그렇기에 프로그램을 만드는 개발자는 운영체제를 알아야 한다.
운영체제는 사용자를 위한 프로그램이 아닌 사용자가 실행하는 프로그램을 위한 프로그램이다. 즉, 사용자가 실행하는 응용 프로그램이 올바르게 실행되도록 돕고 필요한 자원을 할당해 주는 프로그램이다. 이번에는 운영체제에서 매우 중요한 개념인 커널에 대해 알아보고 응용 프로그램이 운영체제로부터 어떻게 도움을 받으며 실행되는지를 이해하기 위해 이중 모드와 시스템 호출이라는 개념을 알아보겠다.
운영체제는 현존하는 프로그램 중에 규모가 가장 큰 프로그램 중 하나이다. 또 다양한 종류의 운영체제가 존재한다. 그렇기에 운영체제가 제공하는 기능 또한 다양하다. 하지만 가장 핵심적인 서비스는 존재한다. 예를 들어, 자원에 접근하고 조작하는 기능, 프로그램이 올바르고 안전하게 실행되게 하는 기능이 운영체제의 핵심 서비스에 속한다. 이러한 운영체제의 핵심 서비스를 담당하는 부분을 커널이라고 한다. 마치 자동차의 엔진, 사람의 심장과 같은 역할을 하는 것이다.
그러면 운영체제에는 속하는데 커널에 속하지 않는 기능이 존재하는가? 바로 유저 인터페이스(UI)가 존재한다.
유저 인터페이스란 컴퓨터간의 통로일 뿐 운영체제의 핵심 기능은 아니다.
운영체제가 제공하는 사용자 인터페이스 종류에는 그래픽 유저 인터페이스 와 커맨드 라인 인터페이스 가 있다. 전자는 우리가 보는 컴퓨터 바탕화면이나 스마트폰 화면을 생각하면 좋을 것이다. 후자같은 경우는 명령어를 기반으로 컴퓨터와 상호작용하는 인터페이스이기 때문에 아이콘이나 다채로운 그래픽 화면이 없다. 사용자는 컴퓨터를 사용하기 위해 정해진 명령어를 입력함으로써 컴퓨터와 상호작용을 할 수 있다.
그러면 사용자가 실행하는 프로그램은 자원에 직접 접근이 가능할까? 그렇지 않다. 자원에 직접적으로 접근하는것은 위험하다. 운영체제는 응용프로그램들이 자원에 접근하려 할 때 오직 자신을 통해서만 접근하도록 하여 자원을 보호한다. 응용 프로그램이 자원에 접근하려면 운영체제의 도움을 요청해야 한다. 즉, 운영체제 코드를 실행해야 한다. 이렇게 운영체제는 자원 접근을 대행하는 일종의 문지기 역할을 하는 셈이다. 이러한 운영체제의 문지기 역할은 이중 모드로써 구현이 된다. 이중모드란 CPU가 명령어를 실행하는 모드를 크게 사용자 모드와 커널 모드로 구분한다.
사용자 모드란 운영체제 서비스를 제공받을 수 없는 실행 모드를 의미하며 커널 영역의 코드를 실행할 수 없는 실행모드이다. 해당 모드에서는 자원 접근이 불가능하다. 반면 커널 모드는 운영체제 서비스를 제공받을 수 있는 실행모드로 자원접근을 비롯한 모든 명령어를 실행 가능하다.
CPU가 사용자 모드로 실행 중인지 커널 모드로 실행 중인지는 플래그 레지스터 속의 슈퍼바이저 플래그를 보면 알 수 있다.
이때 운영체제 서비스를 제공받기 위한 요청을 시스템 호출이라고 한다. 사용자 모드로 실행되는 프로그램은 시스템 호출을 통해 커널 모드로 전환하여 운영체제 서비스를 제공받을 수 있다. 일종의 소프트웨어 인터럽트라고 볼 수 있디. 시스템 호출이 처리 되는 방식은 하드웨어 인터럽트 처리 방식과 유사하니 한번 참고 바란다.
운영체제 핵심 서비스로는 프로세스 관리, 자원 접근 및 할당, 파일 시스템 관리가 존재한다.
프로세스란, 실행 중인 프로그램을 뜻하며 수 많은 프로세스들이 동시에 실행한다. 일반적으로 하나의 CPU는 한 번에 하나의 프로세스만 실행할 수 있기에 CPU는 이 프로세스들을 조금씩 번갈아 가며 실행한다. 다시 말해 CPU는 한 프로세스를 실행하다가 다른 프로세스로 실행을 전환하고 그 프로세스를 실행하다가 또 다른 프로세스로 실행을 전환하는 것을 반복한다. 이렇게 동시 다발적으로 생성, 실행, 삭제되는 다양한 프로세스를 일목요연하게 관리한다. 이렇게 관리함으로 프로세스와 스레드, 프로세스 동기화, 교착상태등의 문제들을 해결한다.
모든 프로세스는 실행을 위해 자원을 필요로 한다. 그리고 프로세스들이 사용할 자원에 접근하고 조작함으로써 프로세스에 필요한 자원을 할당해준다. CPU 같은 경우 CPU 스케줄링으로 어떤 프로세스를 먼저 얼마나 오래 실행할지를 결정한다. 메모리 같은 경우는 페이징 기능을 이용해 RAM보다 더 큰 용량도 실행 가능하게 관리하고 입출력 장치도 인터럽트 서비스 루틴으로 제어를 해준다.
또한, 운영체제는 파일 시스템을 관리함으로 관련된 정보를 파일이라는 단위로 저장장치에 보관하고 파일들을 묶어서 폴더 단위로 장치에 보관하는등의 행위를 한다.