이 책은 꽤나 친절하게 설명해준다. 대신 두껍다. 그래서 여기다 정리한다.
1. OS 는 무엇이냐?
OS 는 명확한 정의가 없다. 목적에 따라 다른 기능에 특화되기 때문이다. Window, Ubuntu 같이 PC 에만 OS 가 있는게 아니라 폰, 냉장고, 자동차 등 온갖 곳에 있다. 다만 나는 PC 를 기준으로 공부할거기 때문에 나머지는 예외다.
OS 는 컴퓨터가 돌 때 항상 돌아가는 Kernal 과 Kenral 이 사용하는 system program 으로 구성된다. 그 위에서 application program 이 돌아간다.
2. 전체적인 흐름
컴이 켜지면 ROM(read only memory) 에서 boostrap program 또는 firmware 로 불리는 프로그램이 실행된다. 하는 일은 RAM, driver 등 온갖 것들을 초기화하고 kernal 을 RAM 에 올리는 것이다. OS 는 우리가 깔고 지우는 software 이기 때문에 애네를 위한 고정 프로그램이 있는 것이다. 물론 boostrap 을 위해 boostrap loader 프로그램을 만들어 boostrap program 을 칩을 바꾸지 않고도 바꿀 수 있게 하기도 하지만 이는 재귀적인 문제일 뿐이다.
kernal 이 올라오면 system daemon 들이 실행된다. kernal 의 확장팩인 system program 이 메모리에 올라온다는 말. 데몬은 백그라운드에서 커널과 같이 계속 돌면서 알아서 작업한다. 이 작업이 끝나면 바탕화면이 보인다.
이렇게 올라온 메모리를 가지고 CPU 가 계속 무슨일을 하는게 컴퓨터가 동작한다는 것이다. 그 일을 프로세스 라고 한다.(정확하게는 시스템에서 일의 처리 단위) 한번에 여러 프로세스를 처리할 수도 있겠으나, 일단 원칙적으론 하나의 CPU는 하나의 프로세스를 처리한다. 한번에 처리한다는 건 0.01초에 a, b, c, d, .. 프로세스를 조금씩 처리해서 1초를 볼 땐 한번에 하는 것 처럼 보이는 것 뿐이다.
컴터에 뭔가를 입력한다던가, 딴데서 돌아가는 Software 가 뭔가를 요청한다던가 하면 interrupt 가 일어난다. CPU 는 그럼 하던 process 를 멈추고 interrupt 를 처리하러 간다. (Software 의 interrupt 는 trap 이라고 부른다. 이는 0으로 나누기 같이 예외 사항 뿐만 아니라 system call 도 포함한다. system call 은 커널의 service route 의 인터페이스이다. )
kernal 이 이 과정을 지도한다. 우선 interrupt 에 딸려오는 interrupt information 을 interrupt vector 의 인덱스로 넣는다. 그럼 이 벡터는 특정한 service routine 의 시작주소를 Program Counter 에 넣고, 기존에 처리하던 프로세스의 주소를 System Stack 에 넣는다. service routine 이 끝나면 스택에서 꺼내와서 하던 일을 한다.
service routine 은 interrupt 를 처리하는 프로세스로 interrupt 의 갯수는 몇억개 이런게 아니라서 벡터에 넣어서 꺼내는게 빠르다. 이 interrupt vector 와 service routine 은 메모리의 초기 주소에 저장되어 있다.
그런데 이러한 I/O device 는 어떻게 작동하느냐. Device 는 device controller 와 연결된다. device controller 는 I/O processor(미니 cpu) 와 local buffer 와 register 를 가지며, I/O processor 가 register 의 값에 따라 device 의 입력을 local buffer 에 저장하든 local buffer 의 내용을 device 에 출력하든 한다. 그리고 소프트웨어인 device driver 는 interrupt 등이 발생 시 cpu 를 끌고 와서 register 나 local buffer 에 읽기 쓰기를 한다. 이 때 interrupt 가 controller 에서 올 수도 있고 다른 프로세서에서 올 수도 있다.
읽기 시 local buffer 의 값은 CPU 의 레지스터에 저장된다. 따로 디바이스용 레지스트리가 있는게 아니라 디스크 읽기랑 비슷한 것이다. device driver 는 결국 cpu 가 명령어를 처리하게 하는 것에 다를 바 없기 때문이다. 그런데 local buffer 크기가 크면 cpu 가 대기하는 시간이 길어진다. 그래서 device controller 가 직접 메모리에 local buffer 의 값을 일정 크기의 block 단위로 올리는 방식도 있다. 이를 DMA(direct memory access) 라고 한다. block 단위 당 interrupt 가 발생되는게 기본이라 cpu 가 입력 기다리느라 노는 시간이 없어진다.
I/O 에서 입력 요청을 하는 경우, 디바이스의 Interrupt 가 올 때 까지 기다리는 Synchronous 한 방식과 안기다리는 ASynchronous 방식이 있다. 후자의 경우 Device_Status Table 을 통해서 디바이스의 상태와 정보 주소를 저장하고, 각 entry 에 Linked List 형태로 요청 명령을 넣는다. 그러면 CPU 는 요청하고 대기하는게 아니라 그 시간에 다른 프로세스를 처리할 수 있게 된다.
3. 프로세서, 코어
디바이스의 특수 processor 는 싱글/멀티 프로세서와는 관계없다. CPU 의 프로세서가 기준이다.
코어 = cpu = processor = cpu, 스레드 = os 의 작업 단위
Multi Processor System 은 작업의 처리방식. 여러개의 cpu 가 하나의 작업을 처리한다는 말.
Multi Core 는 칩 하나에 cpu 가 두개 있는 것. 그래서 자동적으로 Multi Processor System 을 사용.
즉 Multi Core -> Multi Process
물론 오버헤드가 있으니 n개 프로세사가 있다고 n 배 빠른건 아니다.
싱글프로세서 여러개로 하나의 일을 하는 것보다 멀티프로세서 시스템을 쓰는 것은 2가지 이득이 있다. 1. 공통된 데이터가 cpu 각각에 있는게 아니라서 더 빠르다. 즉 디스크는 하나이므로 빠르단 소리. 2. 한 cpu 에서 문제가 생겨도 프로그램이 종료되지 않는다. 1번은 싱글프로세서에 멀티코어를 쓰는 것과 비교했을 때, 멀티코어는 칩이 하나라 전력도 덜먹고 코어간 소통도 빨라 비용대비 좋다곤 말할 수 없다. 다만 2번째는 안정성이 중요한 경우 굉장한 이득이다.
멀티프로세서는 짱 프로세서 하나가 나머지 프로세서를 감독하는 Asymmetric 일 수도 있고, 모두 평등한 Symmetric 일 수도 있다. 요즘 쓰이는건 후자로 SMP(Symmetric Multiprocessing) 이라고 불린다. 장점은 프로세서가 다 똑같아서 그냥 각각 지 할일 시킬 수도 있다는 것이다. 다만 input 이 특정한 하나의 프로세스에 들어가야하고, 놀고있는 프로세서를 안만드는게 이득이므로 OS 를 구현하기가 복잡하다.
또한 여러 프로세서가 메모리를 공유하므로 메모리를 평등하게 접근하기보단(UMA) 여러 프로세서가 원하는 부분을 집중적으로 접근해야한다(NUMA).
Clustered System 은 개개인의 PC 를 네트워크로 연결해 복잡한 계산도 처리하는 시스템이다. 토렌트 같은 것. 얘도 대칭적, 비대칭적일 수 있고, 다수의 데이터 접근을 위해 DLM(Distributed Lock Manager) 같은 것도 사용한다. Parallelization 을 고려해 프로그램이 짜인다.
4. Time_Shared Operating System
Process
: 메모리에 올라가서 돌아가는 프로그램. 프로그램이 하는 것은 Jop 이라서 맥락따라 jop 이라고도 하자.
Multiprograming
: CPU 가 언제나 일하도록 메모리에 프로그램을 쌓아 놓고 대기해야하면 다른거 올린다.
Jop Scheduling
: 근데 메모리가 유한하므로 어떤걸 올려야 할지 정해야 한다. 정하는 방법이 이렇게 부른다.
CPU Scheduling
: 그럼 메모리에 여러개의 Jop 이 있을 것이다. 어떤 순서대로 할 지 정하는 방법을 이렇게 부른다.
TimeSharing (MultiTasking)
: 이제 CPU 를 매우 빠르게 스위칭 하면 된다. 그럼 마치 Jop 들이 동시에 처리되는 것만 같을 것이다. 이러한 CPU Switching(혹은 MultiPrograming) 의 논리적 확장을 이렇게 부른다. 어떤 jop 이든 접근할 수 있는게 목적이므로 response time 이 길면 이 목적과 반한다. 그래서 대개 1초 미만으로 잡는다. 이 결과를 interactive computing 이라고도 한다.
메모리가 좁으니 Jop 들을 swap 하기도 하고 가상메모리를 이용하기도 한다.
5. 듀얼모드
응용프로그램이 여러개 있는데 하나 에러났다고 다 터지면 안된다. 운영체제는 응용프로그램이 하는 일을 응용프로그램이 직접하는 일과 응용프로그램이 커널을 호출하게 하는 일 두가지로 분리한다. 어차피 프로그램은 명령어 집합이다. 이중에서 다른 프로그램에 영향이 큰 명령어는 Privileged Instruction 으로 따로 분류한다. 컴퓨터 하드웨어에서 따로 비트 하나를 떼와서 0이면 Kernal mode 로 1 이면 User mode 로 하여 Privileged Instruction 이 호출 될 때 Kernal mode bit 를 바꾼다. VMM(Virtual Machine Manager) 을 지원하는 하드웨의 경우 비트를 여러개해서 Kernal > MVM > User 의 우선순위를 매긴다. 물론 이런 구분은 필연적인게 아니다.
운영 체제는 Interrupt 가 발생시 kernal mode로 바뀌어 명령을 실행하고 다시 user mode 로 바꾸어 응용프로그램을 돌린다. 응용프로그램의 경우 trap 의 일종으로 service route 인터페이스인 system call 을 호출한다. 이는 레지스터든 스택이든 메모리든 추가 정보가 어딘가 있어서 OS 는 이를 보고 올바른지, 정당한 호출인지 체크 후 service routine 을 실행 후 mode bit 을 1 로 return 한다.
응용프로그램이 무한 루프에 빠지면 컴퓨터를 껐다 킬 순 없다. 그래서 고정 클럭을 가지는 내부 타이머가 있어서 1000부터 센다면 하나하나씩 줄여서 0 될 때 마다 system call 을 불러온다. 그래서 일정 시간마다 Kernal Mode 로 돌아올 수 있어서 응용프로그램의 무한 루프를 피할 수 있다. 물론 타이머의 용도는 더 많다.
API 의 함수들이 system call 의 대표 예이다.
6. 기타
Protection - 리소스나 프로세스를 컨트롤 할 수 있는 권한에 관한 매커니즘
Security - 원하지 않은 접근 등을 통해 내부적/외부적으로 들어오는 공격을 막는 매커니즘
분산 시스템 - 개별 컴퓨터를 네트워크로 연결해서 개개인이 연결된 리소스를 사용하게 되는 시스템
Client-Server - 큰 서버가 많은 클라이언트를 지원함. Computing Server / File Server 가 서비스에 요청하고 파일을 읽고 쓰고 하는 인터페이스를 제공.
P2P - 서버와 클라이언트의 구별이 없어짐. Central Look Up Service 에서 개개인의 요청을 모을 수도 있고 Discovery Protocol 로 클라이언트에 요청을 하기도 함.
DRM(Digital Right Management) <-> GPL(GNU Public License)
댓글 없음:
댓글 쓰기