Saturday, June 28, 2014

Netbooting Apple Clients with ipxe or grub

Still trying to image Apple clients (iMacs) with FOG.  In a previous post I discussed setting up the DHCP server to send boot files to the iMac via the Netboot protocol.

FOG sends iPXE to the PCs to control the boot process during imaging.  We can't just use the same iPXE file for the iMacs, because the PCs are booting using legacy BIOS and the iMacs are using EFI.  iPXE supports EFI, so we built an iPXE for EFI file to send to the iMAC.  It is downloaded, but when the iMac tries to run it, the apple loader seems to choke on it, then boots to the default (harddrive).  The same iPXE EFI file runs fine on the iMac if you install it on the hard drive or a USB drive and run it using rEFIt or rEFInd.  I was unable to figure out why there is a difference, and was unable to attract any attention from the iPXE developers.  Without any kind of output from the netboot loaded image, I didn't see how to start debugging the process.

After some googling, I found these links that indicated that GRUB2 might be able to do what we wanted.

iPXE forums
GRUB mailing list

So, I downloaded the GRUB source and built a 64-bit GRUB EFI binary to send to the iMac.  If you do this, be sure the follow the instructions in the GRUB mailing list post.  So, when the mac loaded the grub image, it dropped to the grub shell.  Awesome, if you ask me.

After messing around in the shell a bit, I was able to get GRUB to load the grub.cfg from the network server, and present the menu.  I thought I was almost home.  Wrong. :(

From the instructions, I was expecting the network config file to be loaded automatically.  I need it to load automatically, if this is going to be useful for imaging 50+ macs.

After 2+ days of messing in the GRUB shell and source code, I've found that, at least on our iMacs, there is a problem with the EFI network interface.  BTW, the modularity of the GRUB code is very nice.

Here's the problem as I see it now.  When GRUB loads, it does all of it's initialization code, including detecting network cards and configuring GRUB's view of those cards, by pulling information from EFI using efi API calls.  Well, the cards (yes, both Ethernet and WiFi) are found.  However, the WiFi card wasn't connected to an AP, so it fails the configuration detection, as expected.  And the Ethernet card configuration detection fails when trying to open the PXE protocol.  This failure isn't surprising since the iMac doesn't support PXE.  Thus, GRUB has no network connection.

Mysteries still exist.  Remember that I was able to download the GRUB configuration file from the network after messing around in the GRUB shell for a while.  So, where did the network connection come from?  That's the mystery.  If I let the iMac boot into the GRUB shell, and just leave it sitting there for a while (30 seconds to 30 minutes), the Ethernet interface in GRUB magically becomes configured with the correct settings!   I was just lucky when I first was able to download the configuration file.  I had waited long enough to have the magic happen first.

The GRUB mailing list post mentioned using the net_bootp command to force this magical configuration.  However, that doesn't work for me.  It fails in one of two ways.  1)  If run without arguments, then it tries to send BOOTP packets out on every network card.  It tries the WiFi card first, and when this fails to send, the net_bootp command aborts without trying the Ethernet card, leaving bad temporary addresses for both cards.  2)  If run with the Ethernet card as an argument, it sends several BOOTP packets out to the network over the card successfully, as seen on the DHCP server.  However, this doesn't make the card magically configured, so the rest of GRUB still can't communicate on the network.

I've had trouble trying to contact live developers for GRUB to see if anyone has insight.  I filed a bug report, but haven't heard anything after a couple of days.  So, I assume there aren't any active developers who are EFI network experts.  If there were, this probably would have been solved by now.

So, it looks like I'm going to be learning DeployStudio for now. :(

Edit:

OK, writing up this message helped to clarify my thinking.  When the "net_bootp efinet0" command is run in the GRUB shell, it actually sends a BOOTREQUEST message to the DHCP server.  The DHCP server logged this message: "BOOTREQUEST from c4:2c:03:1c:68:2b via 144.38.197.1: BOOTP from dynamic client and no dynamic leases".  I have "allow bootp" configured, but they DHCP server doesn't use that to control responses to BOOTREQUEST messages.  Re-reading the man page for dhcpd.conf shows that the "dynamic-bootp" option to the "range" directive enables responses.  Now, the server responds with a BOOTREPLY, which is enough to trigger the DHCP response handling code in the network portion of GRUB.  So, with this configuration, GRUB can be used to Netboot and bootstrap an iMAC!  Yea!


No comments:

Post a Comment