본문 바로가기

지식/system

솔라리스, 리눅스, FreeBSD 커널의 비교

필자(Max Bruning)는 학생을 가르치는 강의에서 대부분의 시간을 솔라리스 내부구조, 디바이스 드라이버 및 커널 크래쉬 덤프 분석과 디버깅을 가르치는데 사용합니다. 학생들에게 얼마나 다양한 서브시스템이 솔라리스에 구현되었는지 설명할때면 학생들이 종종 "그것은 리눅스에서 어떻게 동작합니까?" 혹은 "FreeBSD에서는 이렇게 동작하는 솔라리스에서는 어떻습니까?"라는 질문을 합니다. 이 글은 커널의 3가지 기본적인 서브시스템에 대해 설명하고 솔라리스10, 리눅스 2.6, FreeBSD 5.3에서의 구현의 차이점들을 비교합니다.

구현 차이점의 비교를 위해 검사해볼 3가지 서브시스템은 스케줄링, 메모리 관리, 파일 시스템 구조입니다. 이 세 가지가 모든 운영체제에서 공통적인 부분이며, 운영체제에서 이해하기 가장 쉬운 부분이므로 검사 대상으로 선택하였습니다.

이 글은 위의 서브시스템들에 깊게 들어가지 않습니다. 깊게 파고 들기 위해서는 소스코드와 다양한 웹사이트 그리고 책을 참고해야 합니다. 구체적으로 책을 나열하자면 다음과 같습니다:

 

   - Solaris Internals: Core Kernel Architecture by McDougall and Mauro (Solaris Internals)


   - The Design and Implementation of the FreeBSD Operating System by McKusick and Neville-Neil (The Design and Implementation of the FreeBSD Operating System)


   - Linux Kernel Development by Love (Linux Kernel Development, 2nd Edition) and Understanding the Linux Kernel by Bovet and Cesati (Understanding the Linux Kernel, 2nd Edition)


웹에서 리눅스, FreeBSD 그리고 솔라리스의 비교를 검색하면 대부분은 매우 오래된 자료들입니다. (몇몇 경우 솔라리스 2.5, Linux 2.2, 기타 등등) 대부분의 "사실"들이 새로운 버젼에서는 잘못된 것들 입니다. 또한 비교 설명하려한 그 버젼에서 조차 잘못된 정보도 있습니다. 물론 대부분의 자료들이 각각의 OS에 관한 가치있는 비교를 해 줍니다. 또한 커널들을 비교하는 정보가 매우 적은 것도 사실 입니다. 다음의 자료들이 그나마 가장 최신 자료들입니다:


   - "Solaris Vs. Linux" 솔라리스10쪽을 부각시킨 리눅스와의 비교

   - "Comparing MySQL Performance" 솔라리스10 및 리눅스, FreeBSD와 다른 OS들

   - "Fast Track to Solaris 10 Adoption" 리눅스와 솔라리스의 몇가지 비교를 제공

   - "Solaris 10 Heads for Linux Territory" 실제로 비교는 아니지만 솔라리스10의 리뷰를 제공


이 세가지 OS들의 가장 흥미로운 점은 그들 사이의 유사성입니다. 서로다른 명명 규칙들을 가져 왔지만 각 OS는 서로 다른 컨셉들을 구현하는데 서로 비슷한 길을 걸어 왔습니다. 각 OS는 쓰레드를 위해 타임-공유(time-sharing) 스케줄링을 사용하고, 최근에 사용되지 않은 페이지 교체 알고리즘(not recently-used page replacement algorithm) 을 이용한 요구 페이지(demand-paging), 그리고 가상 파일 시스템 레이어를 통한 서로 다른 파일 시스템 아키텍쳐의 구현등을 지원합니다. 한 OS에서 나왔던 아이디어가 다른 쪽에서 그 길을 찾기도 합니다. 예를 들어, 리눅스 또한 솔라리스의 slab memory allocator 의 배경 원리를 사용합니다. FreeBSD 소스에서 나타난 많은 단어들은 또한 솔라리스에서도 존재합니다. 썬의 오픈소스 솔라리스를 향한 노력으로 필자는 양쪽 모두에서 발전하고 있는 기능들을 좀 더 많이 볼 수 있기를 바랍니다. 현재 LXR 프로젝트는 FreeBSD, 리눅스, 유닉그 관련 OS들의 소스의 크로스레퍼런스 브라우져를 fxr.watson.org 에서 제공합니다. 필자는 오픈솔라리스가 사이트에 추가 되길 바랍니다.


스케줄링과 스케줄러

솔라리스에서 스케줄링의 기본적인 단위는 kthread_t 입니다; FreeBSD에서는 thread 이고 ; 리눅스에서는 task_struct 입니다. 솔라리스는 각 프로세스를 proc_t 로 표현하고 프로세스내의 각 쓰레드는 kthread_t 를 가지고 있습니다. 리눅스는 프로세스(그리고 모든 쓰레드들)을 task_struct 구조체 형태로 표현합니다. 리눅스에서 싱글쓰레드 프로세느는 하나의 task_struct 를 가지고 있습니다. 솔라리스에서 싱글-쓰레드 프로세스는 하나의 proc_t,와 하나의 kthread_t, 그리고 klwp_t 를 가지고 있습니다. klwp_t 는 유저와 커널 모드간의 스위칭되는 쓰레드의 정보를 저장하는 공간입니다. FreeBSD에서 씽글 쓰레드 프로세스는 proc 구조체와 thread 구조체 그리고 ksegrp 구조체를 가지고 있습니다. ksegrp 은 "커널 스케줄링 엔티티 그룹" 입니다. 효과적으로 3개의 OS들은 쓰레드를 스케줄링하고 있고 각 쓰레드는 솔라리스에서 kthread_t , FreeBSD에서 thread, 리눅스에서 task_struct 를 가지고 있습니다.

스케줄링 결정은 우선순위에 기반을 두고 있습니다. 리눅스와 FreeBSD에서 낮은 우선순위 값이 더 낳습니다. 이것은 즉 반대입니다; 0이 제일 높은 우선순위를 나타 냅니다. 솔라리스에서는 높은 값이 높은 우선 순위를 나타냅니다. 표 1 은 각기 다른 OS의 우선순위 값을 보여줍니다.


표 1. 솔라리스, 리눅스 그리고 FreeBSD에서의 스케줄링 우선순위
솔라리스
우선순위 스케줄링 클래스
0-59 Time Shared, Interactive, Fixed, Fair Share Scheduler
60-99 System Class
100-159 Real-Time (note real-time higher than system threads)
160-169 Low level Interrupts
리눅스 우선순위 스케줄링 클래스
0-99 System Threads, Real time (SCHED_FIFO, SCHED_RR)
100-139 User priorities (SCHED_NORMAL)
FreeBSD 우선순위 스케줄링 클래스
0-63 Interrupt
64-127 Top-half Kernel
128-159 Real-time user (system threads are better priority)
160-223 Time-share user
224-255 Idle user


3가지 OS 모두 동적인 쓰레드/프로세스 모델을 가지고 있습니다. 동적인 쓰레드는 계산중심적인 쓰레드에 비해 좀 더 낳은 우선순위에서 작동합니다. 그러나 오직 짧은 시간동안만 수행됩니다. 솔라리스, FreeBSD, 리눅스 모두 CPU당 "실행큐"를 사용합니다. FreeBSD와 리눅스는 "활성" 큐와 "만료" 큐를 사용합니다. 쓰레드들은 "활성" 큐에서 스케줄되어 집니다. 쓰레드는 할당된 시간을 다 사용하면 활성 큐에서 만료 큐를 이동됩니다.(그리고 starvation 현상을 회피하기 위해 각기 다른 시간에 이동될것입니다) 활성큐가 비어있다면 커널은 활성 큐와 만료 큐를 스왑하게 됩니다. FreeBSD는 세번? 큐인 "정지"(idle)" 를 가지고 있습니다. 이 쓰레드에 있는 큐는 다른 두 큐가 비어 있을때에만 수행 됩니다. 솔라리스는 각 CPU당 "dispatch 큐"를 사용합니다. 만약 쓰레드가 할당된 시간을 모두 소비하면 커널은 새로운 우선순위를 주고 dispatch 큐에 돌려 놓습니다. 각 OS의 "실행큐"는 링크드 리스트 형태로 실행가능한 서로다른 우선순위를 가진 쓰레드를 분리해놓고 있습니다.(FreeBSD는 하나의 리스트를 4가지 우선순위로 사용하고 솔라리스와 리눅스는 각 우선순위 별로 분리된 리스트를 사용)

리눅스와 FreeBSD는 쓰레드의 런타임과 sleep 타임( "동적임" 에 대한 지표)의 차에 기반한 숫자 계산방법을 사용합니다. 솔라리스는 테이블 찾기를 수행합니다. 3가지 운영체제 모두 "gang 스케줄링"을 지원하지 않습니다. n 쓰레드를 스케줄링 하는 대신 OS는 효과적으로 다음에 실행될 쓰레드를 스케줄링합니다. 3가지 운영체제 모두 캐싱(warm affinity)의 장점을 살릴수 있는 메카니즘을 가지고 있습니다. 하이퍼쓰레드 CPU를 위해 FreeBSD는 쓰레드가 같은 CPU 노드 에 존재하도록 도와 줍니다.(다른 하이퍼쓰레드 일 수도 있음) 솔라리스는 비슷한 메카니즘을 가지고 있지만 유저와 애플리케이션의 통재를 받고 있고 하이퍼 쓰레드에 의해 제약 받지 않습니다.(솔라리스의 "프로세서 셋" 과 FreeBSD의 "프로세서 그룹")

솔라리스와 다른 두 운영체제의 가장 큰 차이는 시스템 상에서 동시에 여러개의 "스케줄링 클래스"를 지원하는 기능입니다. 3가지 운영체제 모두 Posix SCHED_FIFO, SCHED_RR, 그리고 SCHED_OTHER (혹은 SCHED_NORMAL). SCHED_FIFO 그리고 "실시간" 쓰리드를 지원하는 SCHED_RR 를 지원합니다.(알아둘 점으로 솔라리스와 리눅스는 커널 선점을 통한 실시간 쓰레드를 지원함) 솔라리스는 "고정된 우선순위" 클래스를 가지고 있는데 시스템 쓰레드를 위한 "시스템 클래스"(page-out 쓰레드 같은), X server의 제어를 받고 있는 윈도우 환경에서 돌아가는 쓰레드를 위한 "동적" 클래스, 그리고 리소스 관리를 위한 매우 공평한 스케줄러(Fair Share Scheduler) 가 바로 그것들 입니다. priocntl(1) 를 통해 각 클래스의 기능들과 클래스를 사용하는 자세한 정보를 알아보실 수 있습니다. 매우 공평한 스케줄러(FSS) 는 FSS(7) 를 통해 좀더 자세히 알아보시기 바랍니다. FreeBSD의 스케줄러는 컴파일시에 정해지고 리눅스 스케줄러는 리눅스 버젼에 따라 다릅니다.

시스템에 새로운 스케줄링 클래스를 추가시키는 것은 비용이 드는 일입니다.스케줄링 결정이 이루어질 수 있는 커널의 모든 곳은(실제적으로 실행할 쓰레드를 선택하는 작업은 제외) 스케줄링 클래스-특수한 코드를 간접적으로 호출하는 함수와 연관이 있습니다. 예를 들어 쓰레드가 sleep 상태에 들어가면 그것은 스케줄링-클래스-의존적인 코드를 호출해서 클래스가 sleep 으로 전환되는데 필요한 작업을 합니다. 리눅스와 FreeBSD에서 스케줄링 코드는 단순히 필요한 작업만을 합니다. 어떠한 종류의 간접 호출도 필요 없습니다. 추가적인 레이어는 솔라리스에서 스케줄링을 처리하는 데 아주 약간의 오버헤드가 발생할수 있음을 의미 합니다.(그러나 몇가지 기능이 더 추가되어 있음)


메모리 관리와 페이징

솔라리스에서 모든 프로세스는 "세그먼트" 로 불리는 논리적 섹션 분할 공간으로 나누어진 "주소 공간" 을 가지고 있습니다. 프로세스 주소 공간의 세그먼트는 pmap(1) 을 통해 확인 가능합니다. 솔라리스는 메모리 관리 코드 와 데이타 구조를 플랫폼-독립적 그리고 플랫폼-특수한 파트로 나누었습니다. 플랫폼-특수한 부분은 HAT에 존재하거나 하드웨어 주소 처리 레이어에 존재 합니다. FreeBSD 는 프로세스 주소 공간을 vmspace 로 표현하고 범위(region)이라고 불리는 논리적인 섹션으로 나눕니다. 하드웨어-의존적인 부분은 "pmap" (물리적인 맵) 모듈에 있고 "vmap" 루틴은 하드웨어-독립적인 부분과 자료 구조를 다룹니다. 리눅스는 메모리 디스크립터(memory descriptor)를 사용해서 프로세스 주소 공간을 "메모리 지역(memory area)" 라는 논리적 섹션으로 나누며 이 공간은 프로세스의 주소 공간을 나타 냅니다. 리눅스는 또한 pmap 커맨드를 가지고 있어서 프로세스 주소 공간을 검사해볼 수 있습니다.

리눅스는 소프트웨어 상에서 머신-독립적인 레이어를 머신-의존적인 레이어들로 최대한 나누어 놨습니다. 솔라리스와 FreeBSD는 대부분의 코드가, 예를 들어, page fault 처리는 머신-독립적입니다. 리눅스는 page fault 를 다루는 코드가 매우 머신-의존적입니다. 결과적으로 리눅스는 page를 다루는 코드가 매우 빠릅니다. 왜냐하면 코드 내에 추상적인 데이타 레이어의 수준이 덜하기 때문입니다. 어?든 바탕에 깔린 하드웨어 혹은 모델의 요구사항이 많은 코드 변경을 요구할 경우 비용이 들어간다는 단점이 있습니다. 솔라리스와 FreeBSD는 이러한 변화들을 HAT와 pmap 레이어로 독립시켜 놨습니다.

세그먼트, 지역(regions), 그리고 메모리 지역은 다음과 같은 부분으로 구분되어 집니다:


   - 지역의 가상 주소의 시작

   - 맵이라고 불리는 오브젝트/파일 내에서의 위치

   - 허가권한

   - 매핑의 사이즈


예를 들어 프로그램의 텍스트 부분은 세그먼트/지역/메모리 지역내에 위치합니다. 3가지 운영체제의 주소 공간을 관리하는 메카니즘은 매우 유사하지만 자료 구조의 이름들은 완전히 다릅니다. 다시말해서 리눅스의 코드는 다른 운영체제에 비해 매우 머신-의존적입니다.


페이징

3가지 운영체제 모두 LRU(Least Recently Used) 알고리즘을 페이지 교체를 위해 사용합니다. 3가지 모두 페이지 교체를 하는 데몬 프로세스/쓰레드를 가지고 있습니다. FreeBSD에서 vm_pageout 데몬은 정기적으로 혹은 free 메모리가 낮아 질때 깨어납니다. 사용가능한 메모리가 어떤 특정한 임계값보다 낮아지면, vm_pageout 은 루틴을 실행시켜서 (vm_pageout_scan) 몇몇 페이지를 해제하도록 메모리를 검색합니다. vm_pageout_scan 루틴은 수정된 페이지들을 할당해제시키기전에 비동기적으로 디스크에 쓸것을 필요로 할 것입니다. CPU의 갯수에 상관없이 이러한 종류의 데몬이 존재 합니다. 솔라리스 또한 pageout 데몬을 가지고 있고 계속적으로 메모리 부족현상에 대응하고 있습니다. 솔라리스의 페이징 임계값은 시스템 시작시 자동적으로 계산되어 지므로 ㄷ데몬은 CPU를 과다 소비 하거나 디스크에 page-out 요청을 과다하게 요청하지 않습니다. FreeBSD 데몬은 대부분의 경우 직접 코드 된 혹은 튜닝이 가능한 값을 사용합니다. 리눅스는 또한 LRU 알고리즘을 사용하여 동적으로 실행중에 값을 튜닝합니다. 리눅스에서는 여러개의(CPU당 하나) 의 kswapd 데몬이 존재할 수 있습니다. 3가지 운영체제는 모두 글로벌 작업들의 정책을 사용합니다.(프로세스당 작업 셋과는 반대)

FreeBSD 는 몇가지 page 리스트를 최근에 사용된 page를 추적하는데 사용합니다. 이러한 추적은 "활성", "비활성", "캐쉬됨", "자유" 페이지등의 카테고리로 나눠진 리스트를 사용합니다. 페이지들은 이러한 링크드 리스트를 그들의 목적에 맞게 이동하게 됩니다. 자주 접근 되는 페이지는 보통 활성 리스트에 계속 해서 존재하는 경항을 보입니다. 종료된 프로세스의 데이타 페이지는 즉시 "자유" 리스트로 옮겨 집니다. FreeBSD는 vm_pageout_scan 가 로드를 견디지 못할 경우(예를 들어 시스템의 메모리가 부족할 경우) 모든 프로세스들을 swap하려고 할 것입니다. 만약 메모리 부족 현상이 심각하다면 vm_pageout_scan 은 시스템에서 가장 큰 프로세스를 종료 시킬 것입니다.

리눅스는 LRU-스타일의 알고리즘을 제공하기 위해 또한 다른 종류의 페이지 링크드 리스트를 사용합니다. 리눅스는 물리 메모리를 (여러개 셋의) 3가지의 존으로 나눕니다. 하나는 DMA 페이지를 위한 것이고 하나는 일반 페이지 그리고 하나는 동적인 할당 메모리를 위한 것입니다. 3가지 존은 x86의 아키텍쳐 특성에 의해 구현이 상세하된 것으로 보입니다. 페이지는 "hot", "cold" 그리고 "free" 리스트 사이를 이동합니다. 리스트간 이동은 FreeBSD의 메카니즘과 매우 비슷합니다. 자주 접근된 페이지는 "hot"에 위치할것입니다. 할당해제된 페이지는 "cold" 혹은 "free" 리스트에 존재하게 됩니다.

솔라리스는 "free" 리스트, "hashed" 리스트, 그리고 vnode 페이지 리스트를 통해서 LRU 교체 알고리즘의 변수들을 유지 합니다. vnode 혹은 해쉬 페이지 리스트(FreeBSD/리눅스의 "active"/"hot" 리스트와 거의 동일함) 를 검색하는 대신, 솔라리스는 모든 페이지를 "two-handed clock" 알고리즘을 Solaris Internals 에 설명되어 있는대로 이용해서 검색하게 됩니다. two hand는 고정된 거리를 가지고 앞의 hand가 페이지의 참조 비트를 초기화 함으로써 페이지를 age 시킵니다. 만약 앞의 hand가 페이지에 접근했을때 페이지를 참고하고 있는 어떠한 프로세스도 존재하지 않는다면 뒤의 hand는 페이지를 할당해제(만약 수정되었다면 처음에 비동기적으로 페이지를 디스크에 씀)합니다.

3가지 운영체제 모두 NUMA 지역성을 페이징에서 고려합니다. I/O 버퍼 캐쉬와 가상 메모리 페이지 케쉬는 하나의 시스템 페이지 캐쉬로 통합되게 됩니다. 시스템 패이지 캐쉬는 파일의 읽기/쓰기 와 mmap 된 파일 그리고 텍스트와 애플리케이션의 데이타를 위해서 사용됩니다.


파일 시스템

3개의 운영체제 모두 애플리케이션에게 파일 시스템의 구현을 숨기기 위해 추상 레이어를 사용합니다. 3가지 OS 모두 open, close, read, write, stat, 등의 시스템 콜을 사용합니다. 시스템콜을 통해 파일 데이타의 조직 및 바닥에 깔린 구현에 상관 없이 파일을 접근할 수 있도록 해 줍니다. 솔라리스와 FreeBSD는 이러한 메카니즘을 VFS(가상 파일 시스템, "virtual file system") 이라고 부릅니다. 그리고 기본적인 데이타 구조체는 vnode, (가상 노드, 혹은 "virtual node") 라고 나타냅니다. 솔라리스 혹은 FreeBSD에서 접근 되는 모든 파일들은 그것에 지정된 vnode 를 가지고 있습니다. 일반적인 파일 정보에 서 부가적으로 vnode 는 파일-시스템-특수한 정보를 가르키는 포인터를 가지고 있습니다. 리눅스 또한 비슷한 메카니즘인 VFS ("virtual file switch") 를 사용합니다. 리눅스에서 파일-시스템-독립적 데이타 구조체는 inode 입니다. 이 구조체는 솔라리스/FreeBSD의 vnode 와 비슷합니다. (알아둘 점은 솔라리스와 FreeBSD에도 inode 구조체가 존해지만 이것은 UFS 파일 시스템을 위한 파일-시스템-의존적인 데이타 구조체 입니다) 리눅스는 두가지 서로 다른 구조체를 가지고 있는데 하나는 파일 작업을 위한 것이고 하나는 inode 작업을 위한 것입니다. 솔라리스와 FreeBSD는 이것을 "vnode 작업으로 통합했습니다."

VFS는 시스템상에서 많은 파일 시스템 타입들을 구현하도록 허락해 줍니다. 이것은 하나의 운영체제에서 사용하는 파일 시스템을 다른 시스템에서 접근하지 못할 이유가 없다는 것을 의미 합니다. 물론 관련된 파일 시스템 루틴과 데이타 구조체가 각각의 VFS에 포팅되어야 함을 의미 합니다. 각각의 운영체제는 파일 시스템을 여러 파일 시스템을 사용하는 것을 허용 합니다. 표 2 는 각각의 OS에서 구현된 파일 시스템의 타입들을 나타내고 있지만 모든 시스템 타입을 나타내고 있지는 않습니다.


표 2. 파일 시스템 타입의 부분적인 리스트
솔라리스 ufs Default local file system (based on BSD Fast Filesystem)
nfs Remote Files
proc /proc files; see proc(4)
namefs Name file system; allows opening of doors/streams as files
ctfs Contract file system used with Service Management Facility
tmpfs Uses anonymous space (memory/swap) for temporary files
swapfs Keeps track of anonymous space (data, heap, stack, etc.)
objfs Keeps track of kernel modules, see objfs(7FS)
devfs Keeps track of /devices files; see devfs(7FS)
FreeBSD ufs Default local file system (ufs2, based on BSD Fast Filesystem)
defvs Keeps track of /dev files
ext2 Linux ext2 file system (GNU-based)
nfs Remote files
ntfs Windows NT file system
smbfs Samba file system
portalfs Mount a process onto a directory
kernfs Files containing various system information
리눅스 ext3 Journaling, extent-based file system from ext2
ext2 Extent-based file system
afs AFS client support for remote file sharing
nfs Remote files
coda Another networked file system
procfs Processes, processors, buses, platform specifics
reiserfs Journaling file system


결론

솔라리스와 FreeBSD 그리고 리눅스는 절대적으로 서로에게 도움을 주고 있습니다. 필자는 솔라리스가 오픈소스화 되면서 이러한 경향이 좀더 빠른 속도로 지속되기를 기대하고 있습니다. 개인적인 생각으로 변화는 리눅스에서 가장 빠르게 일어나고 있습니다. 이것의 장점으로는 새로운 기술이 시스템에 빠르게 흡수된다는 것에 있습니다. 운이 나쁘게도 문서화(문서의 완전함) 이 종종 뒤쳐질때도 있습니다. 리눅스는 많은 개발자를 가지고 있고 종종 그런면을 볼 수 있습니다. FreeBSD는 3가지 운영체제중에서도 나온지 가장 오래됐습니다. 솔라리스는 BSD의 유닉스와 AT&T 벨 연구소 Unix 를 혼합한 기반을 가지고 있습니다. 솔라리스는 좀 더 심화된 데이타 추상 레이어를 사용했고 이러한 결과로 새로운 기능들을 쉽고 빠르게 추가할 수 있었습니다. 어?든 커널에 있는 대부분의 레이어화된 것들은 문서화되어 있지 않습니다. 아마 소스 코드의 접근이 가능해 진것이 이것을 변화시키리라고 생각됩니다.

각각의 차이를 간단한 예제로 나타낼 수 있는 곳은 page fault 핸들링입니다. 솔라리스에서 page fault 가 일어 나면 코드는 플랫폼-특수한 트랩 핸들러를 시작 시킵니다. 그 후에 일반적인 as_fault() 루틴을 수행시킵니다. 이 루틴은 fault가 발생한 세그먼트를 찾고 "segment driver"를 호출해서 fault를 다루도록 합니다. segment driver는 파일 시스템 코드 내에서 호출됩니다. 파일 시스템 코드는 디바이스 드라이버 내에서 호출 되어 페이지를 불러오게 합니다. page-in이 완료되면 segment driver는 HAT 레이어를 호출하여 page table 항목을 업데이트 하게 됩니다. 리눅스에서 page fault가 일어나면 커널은 fault를 다룰 코드를 호출 합니다. 즉 곧바로 플랫폼-특수한 코드로 들어가게 됩니다. 이것은 fault를 다루는 코드가 리눅스에서 더 빠름을 의미합니다. 하지만 리눅스 코드는 쉽게 포팅되거나 확장되지 못합니다.

커널의 가시성 및 디버깅 툴은 시스템의 행동을 정확하게 이해하는데 가장 중요한 요소들 입니다. 물론 독자는 소스 코드를 읽고 이해할 수 있지만 코드의 뜻을 잘못이해할 수도 있습니다. 여러분의 가설을 테스트해볼 수 있는 툴을 갖는 다는 것은 가치를 따질 수 없을 정도로 중요한 일입니다. 이러한 측면에서 kmdb, mdb, 그리고 DTrace를 가지고 있는 솔라리스가 명확히 승자라고 생각합니다. 필자는 솔라리스를 수년동안 "리버스 엔지니어링" 해 왔습니다. 그리고 소스 코드를 읽어서 문제를 해결하는것 보다 훨씬 빠르게 이러한 툴들을 이용해서 답을 찾아 내었습니다. 리눅스에서는 이러한 것들을 위한 많은 선택이 존재하지 않습니다. FreeBSD는 커널 크래쉬 덤프를 위해 gdb 를 사용할 수 있도록 합니다. gdb 는 브레이크포인트를 설정하고 싱글 스텝, 데이타 및 코드의 검사 및 수정을 가능하게 합니다. 리눅스에서 이것은 툴들을 다운로드 받아서 설치했을때만 가능한 일입니다.