티스토리 뷰

Study

[Paper] Mach : A New Kernel Foundation For UNIX Development

생각많은 소심남 2013. 2. 26. 01:31

Paper Resource : Mach : A New Kernel Foundation For UNIX Development (1986) : M. Accetta et al 



 컴퓨터를 사용한다는 건 단순히 서핑을 하고 문서 작업을 하는 것이 대부분이겠지만, 컴퓨터를 배우는 입장에서는 그런 걸 하기 보다는 내부 구조에 대한 이해가 필요하다고 본다. 물론 컴퓨터를 구성하는 요소가 많이 있겠지만 그 중에서도 Kernel이 차지하는 역할이 크다. 그래서 이번 포스트에서 Kernel에서도 그 역할을 함축시킨 MicroKernel-based System인 Mach에 대해서 다뤄보고자 한다.


 

Mach. 이걸 어떻게 발음하냐가 첫번째 이야기다. 다들 마하라고 알고 있고, 보통은 속도의 기본 단위, 또는 기계의 축약어로 표현한다. 그러면 Mach가 그런 것처럼 매우 빠르고, 기계적인 OS라고 생각할 수 있는데 전혀 반대이다. 



사실 Mach는 MUCK가 잘 못 발음되다가 나온 이름이다. 본래 개발자가 생각한 Mach는 Multi User Communication Kernel / Multiprocessor Universal Communication Kernel이라는 의미로 MUCK라고 생각했는데 이게 잘 못 발음되어서 Mach이라는 이름이 나오게 된 것이다. 사실 Mach의 의미를 알기 위해서는 위 이미지에서 나오는 Multi User 나 Multiprocessor에 대해서 알아볼 필요가 있다. 그래서 이 부분은 뒤에서 잠깐 설명하겠다.


 

간단히 소개하자면 Mach은 1985년 CMU가 개발한 1세대 MicroKernel기반의 OS이다. Uniprocessor 기반의 기존 Unix OS와는 다르게 MultiProcessor를 지원한다. 물론 기존 Unix에서 지원하는 기능은 왠만큼 다 지원한다. 그런데 사실 앞에서 언급했던 내용과 같이 무척 느린 성능 때문에 1994년까지만 개발되고 다른 플렛폼으로 전환되었다. 그래도 요즘 잘 나가고 있는 OS인 OS X나 GNU Hurd 같이 MicroKernel이 기반이 된 OS가 계속해서 연구 개발되고 있다.



사실 계속 말이 나오고 있지만 먼저 다뤄야 할 내용은 Kernel인 듯 하다. 컴퓨터가 유기적으로 동작하기 위해서는 Software와 Hardware간의 의사소통이 필요하다. 이를 위해서는 중간에 서로를 연결시키는 통로가 필요한데 이를 Kernel이라고 한다. 이 Kernel을 기준으로 Device와 직접적으로 연결되어 있는 부분을 Kernel Level, 사용자가 어플리케이션을 통해 제어하는 구간을 User Level이라고 한다. 보통 시스템상에서 이뤄지는 일에도 처리에 대한 우선 순위를 두기 때문에 이를 Privilege로 표현하는 경우도 있다. 



Mach이 등장하기 이전의 Unix Kernel은 Monolithic Kernel이라 불리는 큰 Kernel이다. 이름에서 알 수 있다시피 시스템 제어에 관한 모든 기능이 Kernel안에서 뭉뚱그려 있는 Kernel이다. 사실 크기면에서 큰 것이 아닌, 그만큼 Kernel이 System상에서 차지하는 역할의 비중이 크다는 의미이다. 그래서 모든 System Call에 관한 처리가 이 Kernel안에서 이뤄지고 있다.



이 Monolithic Kernel은 사용자가 그냥 원하는 입출력만 Kernel에만 전달해주면 Kernel이 알아서 그에 맞는 system Call을 호출하기에 Kernel의 역할이 중요할 것이다. 하지만 만약 이 Kernel의 일정 부분에서 오류가 발생한다면 어떻게 될 것인가? 가령 부팅을 담당한 Device Driver에서 오류가 발생한다면 아예 고칠 수 있는 여지도 없을 것이다.(물론 그럴 일이 있지는 않겠지만...) 바로 Kernel에 대한 의존성이 크기 때문에 발생하는 문제이다. 그래서 이 의존성을 줄이기 위한 방안 모색하다 나온 발상이 Kernel의 role을 줄이자는 것이고, 그 결과물이 MicroKernel인 것이다.



그래서 MicroKernel에서는 정말로 필수적인 IPC와 Thread Management를 제외한 나머지를 User Level에서 처리하게끔 한다. 당연히 기존 문제시 되었던 의존성에서 벗어나 Kernel의 비중을 줄이고 대신 Server라는 Network 개념을 포함시켜 System이 동작할 수 있게끔 만들어졌다. 그래서 Mach도 이 구조를 바탕으로 만들어졌다.


그러면 Monolithic과 Micro Kernel간의 비교를 해봐야 될 듯하다. 앞에서 언급한 바와 같이 Monolithic kernel은 Kernel에서 시스템에 대한 모든 일을 관장하기 때문에 Task나 Process 전환시 발생하는 Overhead가 적다. 즉 Process 처리시 속도가 빠르다는 것이 큰 장점이다. 하지만 앞에서 언급했던 것과 같이 의존성이 크기 때문에 오류에 대한 대처가 복잡하며, 내부적으로도 코드가 스파게티처럼 꼬여있는 경우가 대부분이다. 사실 요즘에 쓰고 있는 Linux Kernel은 Kernel Module이라는 개념을 둬서 기존의 문제를 조금 해결할 수 있었다.

 반면 MicroKernel은 이미지에서 보는 것처럼 Device Driver를 User가 관리하기 때문에 하드웨어에 대한 의존성을 가지지 않는다. 또한 Server를 통해서 Process를 다중으로 처리할 수 있기에 Multiprocessing을 구현하는데 이점이 있다. Kernel의 비중도 작기 때문에 임베디드 시스템에서도 활용할 수 있다. 

 하지만 MicroKernel이 가지는 가장 큰 단점은 바로 성능이다. 아무리 MultiProcessor에 최적화되어 있다 하더라도 Process간의 의사소통을 위해서는 Port를 통한 Message 교환이 이뤄지는데 MicroKernel에서는 이 하나하나가 Overhead로 작용한다. 알려진 정보에 따르면 기존 Monolithic Kernel system에 비해서 IPC 처리 속도가 최대 50%까지 느리다고 언급되어 있다.   여기서 언급할 수 있는 사건이 바로 Tanenbaum / Torbalds debate이다.



이 두 사람은 Tanenbaum의 이론이 base가 되어 만들어진 minix를 사이를 두고 설전을 벌였다. 재미있는 것은 Torvalds가 Tanenbaum의 제자이며, 지금까지도 서로 엎치락 뒤치락하며 발전시키고 있다. 아무튼 두 Kernel 을 비교하면 각각의 trade off가 존재한다. 



앞에서 언급한 것과 같이 전형적인 Multiprocessor를 지원하는 형태이다. 다만 Kernel PC에는 하나의 고성능 CPU가 달리고 소규모의 Microprocessor가 병렬적으로 연결되어 있다. 물론 이 사이에 Server가 존재하면서 서로간의 Communication을 담당하기 때문에 어떻게 보면 기본적으로 High Speed Network이 보장되는 환경이어야 Mach을 구현할 수 있을 듯 하다. 참고로 앞에서 잠깐 언급된 Multi User는 밑의 Workstation들이, Multiprocessor는 위의 Processor 집단군을 묘사한 것으로 보면 될거 같다. 잘 보면 하나의 연산을 여러 개의 프로세서로 나눠서 연산처리하기 때문에 하나의 Distributed OS의 기본적인 Base를 보여주고 있다.



전체적으로 Mach을 설명하기 위해서는 Process Management 와 IPC, Memory Management에 대해서 다뤄봐야 한다. 위의 요소들이 기본적인 컴퓨터 시스템을 운영하는 요소들이다.



다른 포스트에서도 언급했다시피 Process를 처리하는데 있어서는 Task와 Thread의 개념이 들어간다. 어찌보면 Process 나 Thread나 Task가 동일한 선상에 있는 것처럼 알 수도 있지만 이 논문에서 언급한 바에 따르면 Task는 System Resource들의 모음이고 Thread는 Task를 처리하는 Computation의 기본 단위를 말한다. Modern OS에서는 이 Task와 Thread를 동시에 처리하는 것을 기본적으로 요구하고 있다.



기본적으로 Mach상에서는 Thread의 State를 Running과 Suspended 두 상태로 나눌 수 있다. 말그대로 Process를 수행중인 Thread가 Running State일 것이고, Process를 처리한 이후에 남아있는 idle 상태가 Suspended일 것이다. 이 Thread는 하나의 Queue 형태를 이루며 순차적으로 Process를 수행하게 된다.



 하지만 당연히 Queue 내에서도 순서가 있을 것이고 이를 관리하기 위한 방법으로 Thread마다 Priority Number가 존재한다. 또한 thread간 같은 데이터를 쓰기 위해 동기화가 이뤄지는데 이를 위해 0~127 사이의 Suspend Count가 포함되어 있다. 물론 기존의 Unix Synchronization에서 쓰이던 Mutex 같은 방식도 Mach에서 활용되고 있다.



앞에서 언급되었던 내용이지만, Mach은 기본적으로 Multi Processor를 지원한다. MultiProcessor를 지원하는 입장에서 가장 관건인 것은 바로 Process를 적절히 돌릴 수 있는 Processor를 구별하는 방법이다. Thread를 통한 처리를 위해서는 Processor별로 Process를 효율적으로 분배해야 하는데 어렵다. 또한 Thread간의 Process 전환시 Context Switching이 발생하는데 MultiProcessor 체계에서는 기본적으로 이에 따른 Overhead가 많이 발생한다. 이에 따른 해결책으로 논문에서는 Time Quantum 의 size를 조절할 수 있게 함으로써 Thread의 State가 특정 조건일 때만 변할 수 있도록, 즉 Context Switching이 특정 조건일 때만 이뤄지도록 처리되었다.



다음은 IPC 관련 내용이다. 기본적으로 IPC가 이뤄지기 위해서는 Port와 Message라는게 있어야 한다. process간의 의사소통이 보통 message를 통해서 전달되는데 여기에는 출발점과 도착점, 권한, Data와 같은 정보의 header를 담고 있다. 이게 port를 통해서 다른 process로 전달되는 형태를 취한다. 내부적으로는 역시 Queue로 구현되어 있다.



앞에서 말했다시피 Mach에서는 User Level상에 존재하는 Server가 중요한 역할을 하는데 IPC에서는 net message Server라는 것이 존재해서 IPC를 보조하는 역할을 수행한다. 이 역시 Userlevel에 존재하며 Deamon형태로 상주해있으면서 IPC가 이뤄질 때마다 사용된다. 이 Server의 역할은 Message 전달에 관한 모든 권한과 Data Base를 가지고 있음으로써 어느 Process 상에서 바라봐도 Communication이 보이게 하는 역할이다. 다르게 말하면 Multi User 간의 IPC가 Transparent하게 보이는 것이다.



 물론 이와 같은 Message 전달의 가장 기본적인 기능인 Send와 Receive 사이에도 Server가 동작하면서 IPC가 원할하게 이뤄지게끔 보조하고 있다.


 마지막으로 Mach의 Memory Management에 관한 내용이다. 기본적으로 컴퓨터마다 Physical Memory의 한계를 극복하기 위해서 Hard Disk 의 일부영역을 Cache화시킨 Virtual Memory가 존재한다.



Mach은 이 Virtual Memory를 Allocate/Deallocate 시키고 Protection시키는 방법을 통해 Memory를 관리한다. 이와중에 사용된 기법이 Copy On Write라는 것이다.


Copy On Write는 말그대로 임시본을 만들어서 공유하는 공간을 분산시키자는 것이다. 부연 설명을 하자면 서로 다른 process가 같은 Memory 영역을 공유할 때 한쪽 process가 임의로 내용을 수정하는 경우에는 다른 한쪽 Process의 동작에 영향을 끼칠 수가 있다.


이를 방지하기 위해서 임시본을 복사해 수정하되 기존의 공유 메모리는 계속 유지하게 하는 방법이 바로 Copy On Write이다. Mach은 이 방법을 통해서 Protection까지 수행한다. 


 Mach이 다른 시스템에 비해 가지는 특징 중 하나가 Pager이다. Virtual Memory를 관리하면 등장하는 개념이 바로 Page인데 이 Page를 다룰 수 있는 요소를 Memory 상에 Data로 올릴때 같이 포함시킨다. 당연히 Pager를 통해서 Page Fault나 Data에 대한 권한을 가지게 된다.



이렇게 만들어진 Virtual Memory는 그림과 같이 System 상에 implement되는데 유심히 봐야 할 것은 Machine에 따라서 Section이 나눠져 있다는 것이다. 이를 통해서 얻을 수 있는 장점은 Page Size를 동일하게 할 필요 없이 효율적으로 처리할 수 있다는 것이다. 물론 기존의 시스템에서는 Multi System을 지원하는 것이 아니었기 때문에 구현할 필요가 없지만, Mach는 다중 시스템을 지원하기 지원하면서 이런 방식으로 효율적으로 관리할 수 있다.



 전체적으로 요약하자면 Mach는 1세대 MicroKernel기반의 OS이며 Multiprocessor를 지원한다. 또한 User level 상의 Server를 통해서 Process간 Communication이 투명하게 이뤄지며, 앞에서 언급된 방식처럼 기기에 따라 유연하게 memory를 효율적으로 관리할 수 있다. 그리고 이 설명에는 포함되어 있지는 않지만 Kernel의 영향력이 크지 않기 때문에 다른 소형 임베디드 기기로 올리기에도 적절하다. 

 다만 큰 문제로 작용한 것이 바로 IPC 성능이었고, 이 문제 때문에 개발이 중단되었다.




 하지만 이런 문제에도 불구하고 MultiProcessor를 지원하면서 Process를 여러 시스템이 분산처리한다는 아이디어는 저전력 분산처리시스템이나 소형 클라우드 시스템을 구축하기에 적절한 것으로 보인다. 그리고 현재에도 2세대 Microkernel 기반의 OS가 계속 개발되고 있다. 참고로 언급된 L4 Kernel은 Open Kernel Lab(OKL)에서 연구가 진행되고 있다.


처음에 딱 보면서 느낀 건 이렇게 성능이 좋지 않은 라즈베리 파이라 하더라도 이렇게 여러개로 묶고 하나의 고성능 프로세서와 서버로 연동시키면 하나의 분산 운영체제를 통한 슈퍼컴퓨터를 구현할 수 있지 않을까 였고, 실제로 영국 Southampton 대학에서는 이를 통한 연구가 진행되고 있다. 아마 관심사도 이런쪽이 될 듯하다.


두달동안 연구실에 나가면서 수행한 것을 보자면 우선 64비트 멀티코어 OS 원리와 구조 1권을 끝냈고, 이와중에 Boot Loader나 Kernel, Device 인식과 같은 하드웨어를 다루는 중요한 부분을 구현해봤다. 물론 지금은 아무것도 모르는 상태라 따라치기만 한 상태이고, 복습이 더 중요하다는 사실을 안다. 그리고 MicroKernel이라는 생전 처음 듣는 요소를 공부하면서 컴퓨터 구조와 OS 체계에 대해서 정리를 해볼 수 있었던 좋은 기회를 가졌던 것 같다. 물론 내가 지금까지 스스로 공부한 내용이 제대로 알고 있는 것인지는 대학원을 더 다녀보고 되새기면서 볼 일이다. 밑에 있는 건 이 PT를 만들면서 참고한 문헌이다.



댓글