在Mac OSX 10.7(Lion)上编译XNU内核

Apple虽然备受封闭系统的指责,但事实上只要访问http://www.opensource.apple.com,你就能看到苹果对开源软件的贡献。其中最值得一提的就是OSX内核——XNU。
根据我的理解,XNU是Mac OSX的内核,是一种融合了Mach、BSD和IOKit的混合型内核。其中Mach提供核心的基本操作(IPC、同步、VM、进程管理),BSD负责POSIX API,网络,文件系统(以及很多其他),另外IOKit则包含了驱动模型。
虽然网上有不少关于如何编译XNU的文章(包括项目),但在我的试验中,最后能够成功编译的只有这篇文章(因为正好符合各项条件,另外10.8的文章链接在此,都需翻墙),苹果官网上的文档甚至还停留在PowerPC的时代,告诉你如何通过Open Firmware进入调试模式,而Macbook早已在5年前转换到Intel平台,使用EFI作为bootloader。(另外一个明显问题是gcc4.3可以编译最新XNU,无需倒退到3.3)
具体的步骤我不逐句搬过来,概括来说就是:

  1. 下载dtrace(调试追踪工具)和bootstrap_cmds(用来生成Mach IPC服务端代码,又称Mach Interface Generator,这个是服务器版叫migcom);
  2. 分别编译并安装;
  3. 进入xnu代码目录编译;
  4. 在BUILD/obj/RELEASE_<arch> 目录里的mach_kernel就是最终文件。

有几点需要注意:

  • CC和C++一定要换成GCC前端而不是clang,CC是一个符号链接,C++我改了符号链接似乎还不行,最后指定了CXX的环境变量。
  • dtrace和bootstrap_cmds可以在http://www.opensource.apple.com/tarballs/下载打包好的tarball;
  • Xcode的Command Line Tools需要升到最新,这个不会跟着Xcode一起升级,否则在安装bootstrap_cmds时install_name_tool会报告“malformed object (unknown load command XX)”,具体看这个问答

编译完成之后当然就是更换内核重新启动了。具体步骤请看这里
另外编个内核好歹留点纪念吧,如果需要在uname信息留下你的印记的话,编辑config/version.c (我的OS是中文的,居然uname还给出中文了)

[email protected]$ uname -a
Darwin Marshalls-MacBook-Pro.local 11.4.2 DarwinMarshall’s Kernel Version 11.4.2: 2013年 2月24日 星期日 20时20分00秒 CST; wum:xnu-1699.32.7/BUILD/obj//RELEASE_X86_64 x86_64

最后附上原文里的一些步骤,防止原来的链接丢失。

  1. Build dtrace

    $ cd dtrace-90
    $ mkdir -p obj sym dst
    $ xcodebuild install -target ctfconvert -target ctfdump -target ctfmerge ARCHS="i386 x86_64" SRCROOT=$PWD OBJROOT=$PWD/obj SYMROOT=$PWD/sym DSTROOT=$PWD/dst
    ...
    $ sudo ditto $PWD/dst/usr/local /usr/local
    Password:
    $ cd ..
  2. Build bootstrap_cmds

    $ cd bootstrap_cmds-79
    $ mkdir -p obj sym dst
    $ make install RC_ARCHS="i386" SRCROOT=$PWD OBJROOT=$PWD/obj SYMROOT=$PWD/sym DSTROOT=$PWD/dst
    ...
    $ sudo ditto $PWD/dst/usr/local /usr/local
    Password:
    $ cd ..
  3. Build xnu

    $ cd xnu-1699.22.73
    $ make ARCH_CONFIGS="I386 X86_64" KERNEL_CONFIGS="RELEASE"
    ...
    $ file BUILD/obj/RELEASE_*/mach_kernel
    BUILD/obj/RELEASE_I386/mach_kernel: Mach-O executable i386
    BUILD/obj/RELEASE_X86_64/mach_kernel: Mach-O 64-bit executable x86_64

Leave a comment