운영체제 — 하드웨어를 길들이는 관리자
컴퓨터를 켜면 수십 개의 프로그램이 동시에 도는 것처럼 보인다 — 브라우저, 음악, 메신저, 백그라운드 업데이트. 그런데 CPU 코어는 몇 개뿐이고, 메모리도 디스크도 하나다. 이 한정된 하드웨어를 수많은 프로그램이 서로 망가뜨리지 않고 공유하게 만드는 게 **운영체제(OS)**다. OS가 하는 일을 한마디로 줄이면 — 하드웨어를 추상화하고, 자원을 관리하고, 프로그램들을 보호한다. 이 노트 전체가 그 세 가지의 전개이고, 첫 페이지에서는 그 토대 — OS가 무엇을 가려 주고, 어떻게 권한을 통제하는지 — 를 본다.
OS는 무엇을 가려 주나 — 네 가지 추상화
프로그래머로서 우리가 하드웨어를 직접 다룬다고 상상해 보자 — 어느 메모리 번지가 비었는지 직접 관리하고, 디스크의 몇 번째 섹터에 쓸지 정하고, CPU를 다른 프로그램과 어떻게 나눌지 협상해야 한다. 끔찍하다. OS는 이 복잡함을 깔끔한 추상으로 가려 준다.
CPU는 프로세스로 추상화된다 — 코어가 몇 개든, 각 프로그램은 자기가 CPU를 독차지한 것처럼 돈다(실은 OS가 빠르게 번갈아 준다). 메모리는 가상 메모리로 추상화된다 — 각 프로그램은 0번지부터 시작하는 깨끗한 자기 메모리가 있는 줄 안다(실은 OS가 물리 메모리로 번역한다). 디스크는 파일로(섹터·블록을 몰라도 이름으로 읽고 쓴다), 네트워크 카드는 소켓으로 추상화된다. 우리가 프로그램에서 변수에 값을 담고 소켓으로 통신할 수 있는 건 — 그 아래 OS가 이 추상들을 깔아 줬기 때문이다.
아무나 하드웨어를 못 만지게 — 커널 모드와 유저 모드
추상화만큼 중요한 게 보호다. 한 프로그램의 버그가 다른 프로그램이나 OS 자체를 망가뜨리면 안 된다. 그래서 CPU는 두 개의 권한 등급을 하드웨어로 강제한다 — **커널 모드(ring 0)**는 하드웨어에 직접 접근하는 모든 권한을 가진 OS의 영역이고, **유저 모드(ring 3)**는 제한된 권한만 가진 일반 프로그램의 영역이다.
핵심은 — *유저 모드 코드가 특권 명령(하드웨어 직접 제어, 남의 메모리 접근)을 시도하면, CPU가 *예외(trap)를 일으켜 막는다는 것이다. (출처: User mode vs Kernel mode.) 그래서 내 프로그램이 폭주해도 — 기껏해야 그 프로그램만 죽고 OS와 다른 프로그램은 멀쩡하다. 이 하드웨어가 강제하는 경계가 프로세스 격리와 권한 분리의 뿌리다.
부탁할 땐 시스템 콜 — 유저에서 커널로
그런데 일반 프로그램도 파일을 읽거나 네트워크로 보내려면 결국 하드웨어를 써야 한다. 직접은 못 하니, OS에게 부탁한다 — 그 창구가 **시스템 콜(system call)**이다. read·write·open·fork·socket 같은 게 모두 시스템 콜로, *유저 모드에서 커널 모드로 안전하게 전환(trap)*해 OS가 대신 일을 하고 결과를 돌려준다.
왜 알아야 하나 — 이 모드 전환은 공짜가 아니다. 시스템 콜마다 유저↔커널 전환 비용이 들어서, 시스템 콜을 자주 부르면 느려진다. 그래서 작은 read를 수천 번 부르는 대신 한 번에 모아(버퍼링) 시스템 콜 횟수를 줄이는 게 성능의 기본이다. *"비싼 전환을 아껴라"*는 이 원칙은 — 뒤에서 볼 문맥 전환·I/O까지 OS 전반을 관통한다.
정리하면, OS는 한정된 하드웨어를 수많은 프로그램이 안전하게 공유하게 만드는 관리자다 — CPU·메모리·디스크·네트워크를 프로세스·가상 메모리·파일·소켓으로 추상화해 복잡함을 가리고, 커널/유저 모드라는 하드웨어 경계로 프로그램을 서로 보호하며, 시스템 콜로 유저가 커널에 안전하게 일을 부탁하게 한다. 이 토대 위에서 — CPU를 어떻게 나누고(프로세스·스케줄링), 메모리를 어떻게 속이고(가상 메모리), 공유 자원의 함정을 어떻게 피하는지(동시성) 가 펼쳐진다. 그 첫걸음, 프로세스부터 본다.