XNU is the kernel of Mac OS X and Darwin. grub2 has support for loading it directly. For now it only works on i386 and x86_64 platforms
- Sample code to boot is:
root=hd0,2
fsb=133
insmod vbe
gfxpayload=1024x768x32
xnu_kernel /mach_kernel rd=disk0s2
if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
xnu_mkext /System/Library/Extensions.mkext
else
xnu_kextdir /System/Library/Extensions
fi
Grub2 tries to autodetect FSB but it doesn't work on all CPUs. So it's better to explicitely set fsb variable to your FSB frequency in MHz, not quadrupled. The part
insmod vbe gfxpayload=1024x768x32
isn't needed if you're already in gfxterm mode or on a EFI platform
List of xnu-related commands:
xnu_kernel First argument is the name of the kernel. The rest is passed to the kernel as command line. Note however that options -f and -v in official booter are parsed by booter and would have no effect here. Verbose mode is assumed by default unless you load a splash and to get equivalent of -f replace
if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
xnu_mkext /System/Library/Extensions.mkext
else
xnu_kextdir /System/Library/Extensions
fi
with
xnu_kextdir /System/Library/Extensions
For the moment prelinked kernels aren't supported
xnu_mkext loads a mkext. Only one argument: the filename. You may combine multiple mkexts and mix them with other kext loading functions
xnu_kext loads one kext. Either one argument specifying the kext or 2 arguments specifying plist and binary in that order. If either one is missing replace it by dash. This command is mainly for kext developper since it allows them to load a potentially buggy extension from a non-standard path
xnu_kextdir scans a directory for kexts. First argument is a directory. Second optional argument is a comma-separated list of accepted OSBundleRequirement. If omitted it's assumed to be Console,Root,Local-Root,Network-Root
xnu_ramdisk receives one argument which is the filename of ramdisk image. You can access ramdisk as /dev/md0. If you want to use it as root pass rd=md0 on kernel command line
xnu_devtree loads a devtree dump. Without devtree dump your graphics or sound adapter may fail to work or may work only partially. To obtain devtree dump execute grub-dumpdevtree from Mac OS X when booted with boot.efi. This annoyance will be removed in the future. If you previously used device-properties parameter then your device tree dump will look as follows:
656669{ 6465766963652d70726f70657274696573:
<your device properties come here>
;}
These hexadecimal values are actually "efi" and "device-properties" strings
xnu_splash recieves one argument which is the filename of the image displayed on xnu boot. For the moment doesn't work on EFI. It supports any grpahic format supported by grub. However you may need to load the appropriate module manually
insmod jpeg xnu_splash /Extra/mysplash.jpg
Executing this command automatically desactivates verbose mode. Also note that if you load splash and boot into single mode (-s) you won't be able to see the console behind the splash
- xnu_resume receives as an argument a name of hibernate image (usually /var/vm/sleepimage). Note that you don't need to load the kernel in this case
Efiemu
xnu loading is heavily based on EFI. So in non-EFI platform it uses a facility named efiemu. It consists of two parts: loader in efiemu.mod and runtime (efiemu32.o or efiemu64.o). To configure grub before compiling with following options:
./configure --enable-efiemu
Runtime is normaly loaded automatically. However you can also do it manually by
efiemu_loadcore <path to runtime>
Note: all efiemu-related commands need to precede first xnu command (xnu_kernel) If you want to put some values in pseudo-nvram do
efiemu_pnvram FILENAME
Where filename contains the nvram in the following format:
guid1:attr1:name1:data1; guid2:attr2:name2:data2; ...
All fields are hexadecimal. An example
61DFE48B CA93 d211 AA0D00E098032B8C : 7 : 4700 5200 5500 4200 0000: 4700 5200 5500 4200 0000 ;
This will create a variable named "GRUB" with value "GRUB" in the global namespace.
ACPI spoofing
Unfortunately many BIOS vendors provide ACPI tables which break darwin (not an issue with Mac OS X since it only runs on macs which have decent ACPI tables). If you want to add your own tables execute
acpi -e <filename1> <filename2> ...
before any efiemu-related commands. If you want to prevent some tables to load use -x option. It's not necessary for DSDT since there can be only one DSDT and so if any of files is DSDT it will automatically replace the default one.
osprober
If you install grub from linux, use grub-mkconfig and have os-prober installed the following entry will be generated for any Darwin or Mac OS X install
menuentry "<name>" {
set root=<your root partition>
insmod vbe
insmod gfxterm
gfxmode="1024x768x32;800x600x32"
terminal_output gfxterm
do_resume=0
if [ /var/vm/sleepimage -nt10 / ]; then
if xnu_resume /var/vm/sleepimage; then
do_resume=1
fi
fi
if [ \$do_resume == 0 ]; then
if [ -f /Extra/DSDT.aml ]; then
acpi -e /Extra/DSDT.aml
fi
xnu_kernel /mach_kernel rd=<your root>
if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
xnu_mkext /System/Library/Extensions.mkext
else
xnu_kextdir /System/Library/Extensions
fi
if [ -f /Extra/Extensions.mkext ]; then
xnu_mkext /Extra/Extensions.mkext
fi
if [ -d /Extra/Extensions ]; then
xnu_kextdir /Extra/Extensions
fi
if [ -f /Extra/devtree.txt ]; then
xnu_devtree /Extra/devtree.txt
fi
if [ -f /Extra/splash.jpg ]; then
insmod jpeg
xnu_splash /Extra/splash.jpg
fi
if [ -f /Extra/splash.png ]; then
insmod png
xnu_splash /Extra/splash.png
fi
if [ -f /Extra/splash.tga ]; then
insmod tga
xnu_splash /Extra/splash.tga
fi
fi
}
As you see with this entry you can put your splash in /Extra/splash.{png,jpg,tga}, devtree dump in /Extra/devtree.txt, custom DSDT in /Extra/DSDT.aml and additional extensions to load into /Extra/Extensions or /Extra/Extensions.mkext