Building the Kernel (xnu)

How do I build xnu, the Darwin kernel?

First of all, you should determine whether or not you really need to build the kernel. Unlike on some other UNIX-like operating systems, you do not need to recompile your kernel to enable/disable/configure drivers.

The simple version:

# if you're running bash/sh:
. SETUP/setup.sh
# else if you're running csh/tcsh:source SETUP/setup.csh

make exporthdrs
make
      

Mac OS X does not ship with all the development tools of Darwin, even if you've installed the Development package on OS X. To get the full Darwin development environment on OS X, you should install this. It essentially contains everything from Darwin's /usr/local.

If you're upgrading your kernel from 103 or earlier (shipped with Darwin 1.2) to 112 or later, you'll need to upgrade your cctools package to version 353 or later. The newer kernel uses a loader in the kernel, and it references a library that is in the newer cctools package. You may need to build the kld_build target in the ld directory of the newer cctools to get the required libkld.a library.

However, if you're using Darwin straight out of the box (1.0.2 or earlier), your compiler is a tad out of date, so you'll need to make a change before being able to build the new Darwin kernel. You need to edit xnu/makedefs/MakeInc.def and remove -fpermissive.

How do I build a "fat" kernel (i386 and ppc kernel)?

Do all of the setup you would normally do (source the setup script), but before actually building the kernel, set the variable ARCH_CONFIGS to "PPC I386". Under *csh, you would do:

setenv ARCH_CONFIGS "PPC I386"

And under Bourne or POSIX shells you would use:

ARCH_CONFIGS="PPC I386" ; export ARCH_CONFIGS

Then you can build the kernel normally.

How do I install my new kernel?

Please Note, on Darwin 1.0 you CANNOT use hard links for the kernel if your root filesystem is HFS+. Hardlinks only kind of work with HFS+. If you use hardlinks in HFS+, you will not be able to boot either of the hardlinked files.

cp /mach_kernel /mach_kernel.orig
cd my-copy-of-the-xnu-source-directory
cp BUILD/obj/RELEASE_PPC/mach_kernel /mach_kernel.new
cd /
cp mach_kernel.new mach_kernel
reboot

My new kernel doesn't boot, what do I do now?

The easy way: boot to Mac OS, and move a known good kernel to mach_kernel on your Darwin partition.

The hard way: Enter the Open Firmware boot prompt by holding down Cmd-Opt-O-F. Many versions of Open Firmware (earlier versions, which I don't know), default to using a serial console. The serial console is on the modem port, and uses 38400 8N1. When you've gotten an Open Firmware prompt, it'll look like this:

Open Firmware, 1.0.5
To continue booting the MacOS type:
BYE<return>
To continue booting from the default boot device type:
BOOT<return>
ok
0 >

For those familier with Sun's boot prompt, this is (almost) the same.

To boot your alternate kernel, at the OF prompt, check to see what your boot device is, using printenv boot-device. On my 7600, it is: scsi-int/@1,0:6. To boot an alternative kernel, simply type:

boot scsi-int/@1,0:6,mach_kernel.orig

Of course, substitute whatever your own boot-device and kernel file are. When I did this, I got a warning message saying:

bad partition number, using 0

But it worked anyway.

For Darwin/x86, booting an alternate kernel is very easy. At the boot2 prompt, type:

hd()mach_kernel.orig

For more information on Open Firmware on Apples, you may want to check out:

BootX is also able to boot an alternate mach system when you press B at boot time.

How do I configure my kernel?

You should not have to configure your kernel. The default kernel as it lives in the CVS repository is configured with just about everything you'll need. Remember, you don't have to enable/disable drivers in Darwin's kernel like on other Unix OS'. Drivers are all modular and are loaded separately from the kernel.

xnu uses a configuration system similar to the "normal" BSD style, except it uses a configuration file for each subsystem. Specifically, bsd, iokit, libkern, osfmk and pexpert. The configuration files for each of these live in the xnu/{subsystem}/conf directory. Within each of the configuration directories, there are the files MASTER, MASTER.i386, MASTER.pcc, files, files.i386, files.ppc.

MASTER contains the machine independant definitions. You can edit this file.

MASTER.{i386|ppc} contains the machine dependant definitions. You can edit this file.

files contains the list of machine independant files that can be built into the final kernel if the correct option is specified in MASTER. Unless adding a machine independant chunk to the kernel, you shouldn't edit this file.

files.{i386|ppc} contains the list of machine dependant files that can be built into the final kernel if the correct option is specified in MASTER.{i386|ppc}. Unless adding a machine dependant chunk to the kernel, you shouldn't edit this file.

In general, the isn't a whole lot of configuring you need to do with a Darwin kernel right now. The BSD subsystem variables can be tuned, but right now Darwin supports few enough drivers, that all of them are built into the kernel, and it doesn't affect performance/memory usage very much. So, unless you're really into kernel hacking, I don't suggest changing the default configuration of xnu's subsystems.

After building xnu, is there anything else I should do?

After building xnu, you have to make sure that IOKit, Kernel and System frameworks are all up-to-date. To generate all the correct files after xnu is built, you should do:

make install

This will put several things into xnu/BUILD/dst, such as the new mach_kernel, and all of the appropriate frameworks. You should first backup the following directories (in case something is wrong, or you want to revert back to a previous kernel):

/System/Library/Frameworks/IOKit.framework
/System/Library/Frameworks/Kernel.framework
/System/Library/Frameworks/System.framework

When backing these things up, DON'T move /System/Library/Frameworks/System.framework! It's the equivalent of libc and is a shared library. If you move it aside, things will stop working!

After you've backed these up, copy the contents of the xnu/BUILD/dst/System/Library/Frameworks/{IOKit,Kernel,System}.framework into /System/Library/Frameworks/{IOKit,Kernel,System}.framework. You can use cp -R on each of these directories, and it'll work pretty well (that's a capital R!). Then all the newly updated header files will be installed.