[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Netboot Linux on Intel Macs via EFI (long)

From: Stefan Dösinger
Subject: Netboot Linux on Intel Macs via EFI (long)
Date: Fri, 17 Feb 2012 09:03:28 +0100
User-agent: KMail/4.7.4 (Linux/3.2.1-gentoo-r2; KDE/4.7.4; x86_64; ; )


I'm writing this mail mostly to document my efforts for others who try to 
achieve a similar goal. If any Grub experts find a way to improve my solution 
I'm open to suggestions :-)

My goal was to boot a Linux system via the network(nfsroot, ...) on my Intel 
Macs without placing any additional boot media like cdroms, usb mass storage 
or placing data on the built-in disk. If you don't mind using boot cds, stop 
reading now and load iPXE from a cdrom and follow the normal PC netboot 
tutorials out there. It is much easier.

I'm not explaining the the basics of netbooting, like how to set up your dhcp 
and tftp server. There are many (PC-focused) tutorials out there.

Luckily the Mac EFI implementation supports network booting. It can be 
triggered in the following way:

1) Select network boot in the OSX boot settings.
2) Hold down the N key when powering the mac on
3) Hold down the option key when powering the mac on, then press N when the 
menu comes up.

Unfortunately the firmware has some quirks, and the first task is to set up 
dhcpd to return a reply that makes the firmware happy. I've attached my 
dhcpd.conf, the magic is in the 'class "AppleNBI-i386"' definition. Some 
background read can be found at

This allows you to deliver one .efi program to the target machine, specified 
by the "filename" setting. The Mac firmware will download it from the tftp 
server specified by the "next-server" setting.

The next issue is that some Macs have a 32 bit EFI, and others have a 64 bit 
EFI, and the vendor-class-identifier doesn't explicitly say so. Apple has 
universal EFI binaries for that, but apparently grub cannot build them. Thus I 
select the macs I have that need a 32 bit binary with the model info in the 
vendor-class-identifier. This has the potential to get ugly when more 
exceptions are added.

To build the efi binaries I essentially followed the EFI building instructions 
out there. However, you have to link all necessary modules ino the .efi binary 
as you won't be able to load any additional modules for a while. Here are my 
build command lines for i386:

./configure --with-platform=efi --target=i386
./grub-mkimage -d grub-core/ -O i386-efi -o /tftproot/grub/bootia32.efi 
part_gpt hfsplus fat ext2 normal chain boot configfile linux loadenv echo 
search loadbios video_fb videotest pci efi_gop efi_uga font gfxterm font 
memdisk tar tftp reboot efinet --prefix=/boot/grub -m 

Yes, some of those modules are not necessary, like the hfsplus stuff and ext2 
driver. I found them helpful for debugging though.

Next issue: Grub finds the efi network interface efinet0, but the Mac firmware 
apparently doesn't offer the PXE protocol, so you can't autoconfigure the 
interface and have your prefix on the tftp server. Luckily the memdisk can 
help here. My memdisk merely contains a boot/grub/grub.cfg file with the 
following content:

configfile (pxe)/grub/grub.cfg

Interestingly bootp and tftp work, even though pxe as a whole doesn't. Also, 
by default net_bootp configures the IP, but doesn't set the default tftp 
server name. The attached bootp-hack.diff hack changes that. Alternatively you 
can hardcode the server IP into the config file(and thus bootloader binary) 
like this:

configfile (pxe:

I considered that ugly, so I looked for a better way. I'll contact the 
development list regarding the hack.

Okay, from there on it is pretty simple and mostly follows the mac efi booting 
tutorials that explain booting from disk. My (pxe)/grub/grub.cfg file is 
attached. The loadfont and terminal_output gfxterm statements are necessary to 
make the efifb framebuffer work after the kernel has loaded. If your kernel 
instantly uses a GPU-specific framebuffer driver(e.g. KMS radeon, intel or 
nouveau) you may be able to skip it. For instructions on how to create 
unicode.pf2 see .

One other neat thing I came across while working on this: Notice that the 
kernel parameters do not contain a nfsroot parameter. The kernel gets that 
parameter from dhcp as well, via the root-path option in dhcpd.conf.

I hope some fellow out there in the world finds this useful. If you have any 
suggestions or questions please CC me, I'm not subscribed to the mailing list.

Some random notes:

1) You may want to get the wiki up again, a wiki would be a better place for 
tutorials like this

2) When I debugged the PXE services in efinet.c, it took me a while to realize 
that grub_efi_net_config is not called if there's any compiled in module that 
may provide a prefix(e.g. memdisk)

3) I tried chainloading grub from iPXE in the hope that iPXE provides a 
working PXE protocol, but this didn't work.

4) There's net_get_dhcp_option which allows me to retrieve the dhcp server ip, 
or next-server, I don't know because they are the same in my setup. 
(iface=efinet0:dhcp, number=3, description=hex). Unfortunately this returns a 
hexadecimal number which (pxe:server) doesn't understand. This may be another 
way to get rid of the bootp hack. And no, description=string does not return 
"", it just returns "(". Adding a format option like "ip" that does 
that might be a workable solution though.

5) I suspect net_bootp does not set default_server_name etc because it is only 
called from the command line or a config file, and never in an attempt to find 
the prefix.

6) Next plan: Use grub instead of syslinux's menu.c32 for my standard PC side 
setup so I can share the config file, and thus the kernel command line.

Stefan Dösinger

Attachment: dhcpd.conf
Description: Text document

Attachment: bootp-hack.diff
Description: Text Data

Attachment: grub.cfg
Description: Text document

Attachment: signature.asc
Description: This is a digitally signed message part.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]