운영체제 1편 - 추상화

이 글은 학부 운영체제 수업을 듣고 정리한 글입니다.
맥락없이 운영체제에 대한 내용들이 불쑥 등장하니 양해부탁드립니다.

먼저 운영체제를 공부하기에 앞서 살짝 마음가짐을 다르게 해야한다.
운영체제를 이해할때는 Abstraction, 즉 추상화를 이해하는게 가장 중요하다.
운영체제에 대한 연구는 매일매일 이루어지고 실제 구현내용은 정말 자주 바뀐다. 그러므로 운영체제를 공부할때에는 실제 구현에 초점을 맞추기 보다는 Abstraction을 이해해보자.

Memory를 abstract 해주는 것은 memory address 이고, 디스크를 abstract 해주는 것은 File 이다.
그러면 Hardware를 Abstraction 해주는 것은 무엇일까? 바로 운영체제이다.
운영체제는 하드웨어를 손쉽게 사용할 수 있는 Abstraction을 제공한다.
운영체제를 공부할때에는 실제 구현에 초점을 맞추기 보다는 Abstraction을 이해하는게 가장 중요하다.

대표적인 Abstraction인 프로세스와 포트를 알아보자.

Process

Process는 실행되고 있는 프로그램에 대한 Abstraction 이다.
프로그램은 일련의 순차적으로 작성된 명령어들의 모음으로 disk와 같은 secondary storage에 저장되어 있다. 이들이 메모리에 올라오면서 실행이 되는 프로그램이 된다. 그러면 프로그램은 프로세스가 된다.
메모리에 올라와서 동작을 하게되면 이를 프로세스라고 한다.
프로세스의 메모리구조는 다음과 같다.

프로세스 메모리구조(https://sudonull.com/post/95562-Program-anatomy-in-memory)

이후의 프로세스편에서 다룰 예정이라 메모리구조만 살짝 보기만 하고 넘어가자.
물론 당연히 여기서의 메모리구조는 가상메모리를 얘기하는 것이다.

그러면 프로세스는 파일인가? 아니다. 하지만 이를 볼 수 있도록 구현해놓은게 있다.
/proc 을 보면 현재 실행되고있는 프로세스들을 파일로 볼 수 있다.
프로세스가 뜨면 각각 프로세스들은 address space를 가진다.
이는 다른 프로세스끼리 공유가 안되고 직접 접근할 수도 없다. 즉 A 프로세스에서 B 프로세스의 함수로 한번에 jump가 불가능하다는 것이다.

Port

우리가 흔히 말하는 포트도 Abstraction이다.
포트는 프로세스가 세상을 바라보는 창이다.
우리는 여러 프로그램을 동시에 켜고서는 네트워크를 통해 각 패킷을 주고받지만, 외부에서는 우리의 프로세스의 존재를 알지 못한다.
외부에서는 우리의 port를 향해서 보낸다.
포트는 컴퓨터간의 메시지를 주고받는 communication endpoint로 설명할 수 있다.

운영체제의 특징

운영체제는 supervisor mode(kernel mode), user mode가 있다. 운영체제는 hardware 자원을 접근하고 제어한다. 그래서 운영체제는 supervisor mode에서 동작을 한다.
supervisor mode는 cpu가 제공을 해준다. 운영체제가 시작을 하면서 supervisor mode로 switching을 한다.
이와 반대로 다른 애플리케이션들은 user mode로 동작한다. device 들도 프로세스가 직접 제어를 못하고 운영체제를 통해서 제어가 가능하다.

운영체제의 Kernel 이라는 것은 운영체제의 핵심적인 부분으로서 자원할당, hardware에 대한 인터페이스 제공, 보안 등을 담당한다.

Time sharing

운영체제는 CPU의 실행시간을 time slice로 나누어서 실행한다. kernel이 프로세스를 돌리다가 context switching을 한다. 즉, 모든 프로세스는 time slice 동안 CPU를 점유하고 그 시간이 끝나면 CPU를 양보한다.
Time slice는 옛날에는 10ms로 했었는데 이는 아주 옛날이야기이고 점점 timeslice값이 줄어들고 있다.
단순하게 왜 time slice가 줄어들까? CPU가 점점 빨라지고 있기 때문이다.
예전에 10ms로 정했던 이유는 task에 대해 대략적으로 휴리스틱하게 시간을 측정해서 10ms정도면 다 끝나겠다라고 생각해서 정했는데 cpu가 점점 빨라지면서 이 값이 같이 줄어드는게 당연하다.
요즘에는 timeslice를 상수로 두지 않는다. 이를 가변으로 둔다.

이런 CPU의 time sharing으로 concurrent 하게 여러 프로세스들이 수행된다.
싱글코어에서는 cpu에서 특정 시간의 그 순간에 수행되고 있는 프로세스는 1개이지만 밖에서 바라볼때에는 여러개를 동시에 수행하는 것처럼 보인다.
concurrent라는 뜻은 물리적으로는 1개의 프로그램만 수행하더라도 다른 프로그램들도 같이 수행중인 것임을 의미한다.
이와 반대되는 단어로 simutaniously 가 있는데 요즘에는 여러개의 코어로 컴퓨터가 구성되어있는데 실제로 여러 cpu에서 여러 프로그램이 동시에 수행되고 있음을 의미한다.

Cpu mode

위의 운영체제 특징에서 보았듯이 cpu에는 execution mode(실행모드)가 있다.
user mode와 kernel mode가 있다.

Kernel mode

  • 모든 권한을 가진 execution mode
  • Kernel이 실행되는 mode
  • Privileged 명령어 실행 및 register 접근 가능 ex) I/O 장치 제어 명령어, memory management register CR3

User mode

  • Kernel에 비해 낮은 권한의 execution mode
  • User Application이 실행되는 mode
  • Privileged 명령어 실행 불가능

kernel은 오직 kernel mode에서만 작동한다.
user mode에서는 instruction이 수행할 수 있는 previledge가 달라진다.
execution mode는 하드웨어가 지원해준다. 만약에 유저의 application이 device로 직접 접근하려고 하면 hardware로 막아버린다.
kernel mode에서 쓸수있는 instruction을 user mode에서는 쓸수가 없다.
예를들어 in, out이라는 instruction 이 있다. 이런 instruction은 usermode 에서 작동을 안한다. intel processor에는 wing이라는 mechanism을 지원해서 이 wing이 execution mode를 지원한다.
wing 0 는 kernel mode이고 wing 3가 user mode이다.
virtualization으로 가면 wing을 한가지 더 쓴다. 처음에 설계를 할때 wing1과 wing2는 미래를 위해 남겨놓았는데 여기서 쓴다.
당연한 얘기지만 여기서 말하는 kernel mode는 sudo가 아니다. sudo 라는 것은 사용자 관점에서의 권한을 다루는 것이다.
아무리 sudo라고 해서 kernel level에 접근할 수 없다.

그렇다면 user mode에서 kernel mode로 들어갈 일이 있을까? 그러면 뭔가 스위칭 해주는게 필요한가?
여기서 시스템 콜이 필요하다.
시스템콜을 통해서 유저가 커널로 파일을쓰거나 패킷을 읽을 수 있다.
시스템 콜의 종류에는 open, write, msgsnd, shm 등이 있다.

시스템콜

시스템콜은 기본적으로 사용자 프로그램에서 시스템콜을 호출하면 user mode에서 kernel mode로 스위칭이 된다.
그러면 커널함수로 점프를 한다. 예로 open이라고 하면 open을 구현한 커널함수로 뛰어간다.

시스템콜 호출

system call에 파라미터를 받기도하는데 register를 통해서 전달한다.

시스템콜 Argument 전달

애플리케이션과 커널 사이에는 시스템콜이라는 interface가 있는 것이다. 같은 개념으로 하드웨어와 커널사이에는 driver interface가 있다.

정리

  • 운영체제는 하드웨어의 Abstraction 이다.
  • 운영체제는 Time sharing을 지원한다.
  • 운영체제는 Kernel mode에서 실행되며, 애플리케이션이 user mode에서 kernel mode로 가려면 systemcall이 필요하다.

댓글