02. Protection

  • Haram Lee
  • 2026-04-14
  • studies / 26-1 / operating-systems

Kernel & Protection

Direct excution

  • 예전에는 부팅한 뒤 OS 커널과 응용 프로그램이 같은 주소 공간에서 실행되었다. 즉, 커널 코드와 데이터, 응용 프로그램 코드와 데이터가 메모리 안에서 격리되지 않았다는 뜻이다. 그러면 응용 프로그램이 커널의 코드나 데이터를 읽거나 수정할 수 있다.
  • Direct execution
    • 운영체제가 프로그램 실행 시,
    1. 프로세스 목록에 엔트리를 만든다
    2. 프로그램용 메모리를 할당한다
    3. 프로그램을 메모리에 적재한다
    4. stack과 argc / argv를 세팅한다
    5. 레지스터를 초기화한다
    6. main()을 호출한다
    7. 프로그램이 main()을 실행한다
    8. main()에서 리턴한다
    9. 메모리를 해제한다
    10. 프로세스 목록에서 제거한다
  • “OS would not control anything about program: OS is just a library”

Problem?

  • 커널은 잘 짠 코드라고 가정해 보자. 그런데 응용 프로그램은? 커널 개발자 입장에서 모르는 사람이 짠 코드, 인터넷에서 받은 코드, 버그 있는 코드를 신뢰할 수 있느냐는 거다. 결론은 당연히 아니고, 그래서 OS 설계자는 buggy하거나 malicious한 application으로부터 kernel을 보호해야 한다는 결론에 도달한다.
    • e.g.
C
int *i;
i = 0;
*i = 1;
C
i = -1;
while (i < 0)
	do something;

Unit of protection

  1. unit of protection을 정의한다 = process
    • 제한된 접근 권한을 가진 실행 중인 프로그램의 인스턴스이고
    • CPU, memory, I/O abstractions를 담는 컨테이너다.
  2. kernel protection mechanism을 고안한다
    • important instructions를 앱이 실행하지 못하게 해야 한다
    • 다른 앱이나 커널의 memory를 읽고 쓰지 못하게 해야 한다
    • OS가 앱으로부터 제어권을 반드시 다시 가져올 수 있어야 한다

Protection design

  • Privileged instruction
  • Memory protection
  • (Timer) interrupt

A naïve ‘SW-only’ approach

  • 각 프로그램 명령을 시뮬레이터에서 하나씩 실행하면서, 허용되면 실행하고 아니면 중단시키면 되지 않나?
    • 느리다!!
    • 모든 instruction에서 소프트웨어가 매번 검사하면서 실행하는 것은 비용이 너무 크다. 일반 목적 운영체제를 이렇게 만들 수 없고, 하드웨어가 직접 도와줘야 한다.

Improved design idea

  • dual mode operation (ring mode)
  • privileged I/O instructions
  • memory protection mechanism

Dual mode: kernel mode and user mode

  • Kernel mode
    • 커널 모드는 하드웨어의 전체 권한을 가진다.
    • 어떤 메모리든 읽고 쓸 수 있고, 어떤 I/O device든 접근할 수 있고, 디스크 섹터를 읽고 쓰거나 패킷을 보내고 받는 것도 가능하다.
  • User mode
    • 사용자 모드는 제한된 권한만 가진다. CPU는 명령을 실행하기 전에 매번 검사해서, 현재 모드에서 허용되지 않는 instruction이면 실행하지 않는다. x86에서는 이런 모드 정보가 EFLAGS 같은 상태 정보에 반영된다.
  • Privileged instruction
    • mode bit를 바꾸는 명령
    • 사용자가 접근 가능한 memory 범위를 바꾸는 명령
    • I/O device에 command를 보내는 명령
    • I/O device에서 데이터를 읽고 쓰는 명령
    • kernel code로 점프하는 명령
    • 만약 user mode 프로세스가 이런 privileged instruction을 실행하려고 하면 어떻게 해야 하느냐? CPU 하드웨어가 그 사실을 커널에 알려야 한다. 그때 등장하는 개념이 exception 이다. 즉 허용되지 않은 행위를 하드웨어가 감지해서 커널에게 통보하는 메커니즘이 exception이다.
  • 그런데 결국 application이 I/O를 해야 하지 않냐?
    • 커널에게 부탁한다!!
      • application은 kernel에게 privileged instruction 수행을 요청한다
      • kernel은 그 요청이 허용 가능한지 검증한다
      • 허용되면 kernel이 대신 privileged instruction을 실행한다
    • 즉 앱은 평소 user mode에 있다가, system call / trap 을 통해 잠깐 kernel mode로 들어가 필요한 작업을 부탁하는 구조다.
  • System call
    • OS가 제공하는 서비스의 programming interface

Memory protection

  • Software-based method
    • 커널이 모든 load/store instruction에 끼어들어서 유효한 접근인지 검사하는 방식이다. very slow
  • Hardware-based method
    • 하드웨어가 load/store를 감시하고, 불법 주소 접근이면 exception을 발생시킨다.
    • 그럼 커널이 제어권을 가져와서 프로세스를 종료하거나 적절한 조치를 취한다. 이 방식이 현실적인 OS의 방식이다.
  • V1: process가 보는 address space
  • V2: hardware가 보는 address space
    • translation은 hardware가 table을 이용해 수행한다
    • 그 table은 OS kernel이 설정한다
  • 즉 커널이 “이 프로세스는 어떤 가상 주소를 어떤 물리 주소로 연결할 수 있는가"를 표에 기록해 두고, 하드웨어가 매 memory access마다 그 표를 참고해서 합법 여부를 검사하는 것.

MMU

  • Memory-Management Unit
  • 실행 중 각 load/store마다 주소를 재배치(relocate)하고, 합법적이면 물리 주소로 변환해 memory에 접근하고, 불법이면 exception 을 발생시킨다.
  • 프로세스는 코드상으로는 kernel address를 가리키는 포인터를 만들 수 있다. 하지만 실제로 (3)에서 쓰기를 하려는 순간, MMU가 그 주소를 검사해서 page fault exception 을 발생시킨다. 그러면 커널의 page fault handler가 실행되고, 불법 접근이라고 판단되면 프로세스를 죽인다. 그 과정에서 SIGSEGV 같은 signal이 전달될 수 있다.

Timer interrupt

  • 부팅할 때 kernel이 timer hardware를 시작한다
  • timer가 몇 ms마다 주기적으로 interrupt를 발생시킨다
  • interrupt가 나면 현재 실행 중인 process가 suspend 된다
  • 그 process의 현재 상태가 저장된다
  • 미리 등록된 interrupt handler 가 kernel 안에서 실행된다
    • 그 결과 kernel은 주기적으로 control을 다시 얻는다. 그래서 프로세스가 무한 루프를 돌더라도 OS는 영원히 CPU를 빼앗기지 않는다. 필요하면 그 프로세스를 종료할 수도 있다. 이게 스케줄링과 강제 선점(preemption)의 출발점이다.

Summary

보통 현대 OS는

  • user-level 에서 application이 실행되고
  • kernel-level 에서 scheduler, memory system, file system, device driver, exception/interrupt handler가 실행된다
  • hardware는 trap, interrupt, system call 을 통해 필요할 때 제어를 kernel로 넘긴다

즉 평소에는 앱이 user mode에서 돌아가다가,

  • system call 이면 앱이 정식으로 커널 서비스를 요청하는 경우
  • exception 이면 잘못된 행위를 하거나 예상 못 한 상황이 생긴 경우
  • interrupt 이면 외부 하드웨어 사건이나 timer가 발생한 경우

커널이 제어권을 갖게 된다. 이 구조 덕분에 운영체제는 보호된 상태를 유지하면서도, 응용 프로그램이 필요한 서비스를 안전하게 제공할 수 있다.

Discussion