# Darwin 内核

![](https://1476380306-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MZBTUOxxb0Af3Va3Lxu%2F-Mgd-j_DfQmB8qA-2zAu%2F-Mgd0WJ6rBg-x32WmSM5%2Fimage.png?alt=media\&token=8b122190-ec46-415b-ab64-3e357ad336cb)

图片引用自《深入解析Mac OS X & iOS 操作系统》

Darwin的内核是XNU，XNU is Not Unix。XNU是两种技术的混合体，Mach和BSD。BSD层确保了Darwin系统的UNIX特性，真正的内核是Mach，但是对外部隐藏。BSD以上属于用户态，所有的内容都可以被应用程序访问，而应用程序不能访问内核态。当需要从用户态切换到内核态的时候，需要通过mach trap实现切换。

#### XNU 包含：

* Mach微内核
* BSD层
* libkern
* I/O Kit

#### Mach

Mach 是 XNU的原子核，是一个微内核轻量级操作系统，仅处理最核心的任务

* 进程和线程抽象
* 任务调度
* 进程间通讯和消息传递
* 虚拟内存管理

#### BSD层

BSD层简历在Mach之上，确保了Darwin符合 POSIX 。提供了更高层次的功能，包括：

* UNIX 进程模型
* POSIX线程模型（Pthread）及相关的同步原语
* UNIX 用户和组
* 网络协议栈（BSD Socket API）
* 文件系统访问
* 设备访问（通过/dev目录访问）

#### libKern

I/OKit是C++ 编写的；为了支持C++运行时并提供所需要的基类，是一个內建的自包含的C++库。

I/O Kit\
这是一个在内核中的完整的自包含的执行环境，让开发者可以使用C++快速创建设备驱动程序。

#### POSIX系统调用

POSIX 兼容性是由XNU中BSD层提供的。\
&#x20;所有的POSIX 系统调用不论底层实现如何都有相同的原型，也就是说具有相同的参数和返回值。\
&#x20;系统调用编号：除了固定的原型之外，POSIX还完整定义了系统调用的编号。

#### Mach 系统调用

BSD层是对Mach内核的包装，但是Mach系统调用仍然可以在用户态访问。需要借助mach trap实现用户态到内核态的转换。\
&#x20;在32位系统上，Mach系统调用的编号都为负数，POSIX调用编号为非负。\
&#x20;在64位系统上，Mach系统调用为正数，但是以0x2000000开头，而POSIX调用编号以0x1000000开头。

#### 总结

iOS的核心是Darwin，Darwin的核心是XNU，XNU有两个核心，外层的BSD和内层的Mach。由于有两个内核所有有两种系统调用方式。造成这种现象的原因是OS X作为一款PC操作系统希望运行针对UNIX开发的应用，而iOS作为OS X的分支继承了这个特性。\
