Joshua Oreman: 802.11 wireless development

Interesting Idea: Loading part of gPXE over the network

Update 6/29: After talking with Michael, I've realized everything the below idea would offer can also be achieved by chainloading a fully-featured gPXE over the network using a minimal ROM-burned gPXE. That simple solution is orders of magnitude easier than implementing proper modularisation, and so the below becomes something of a curiosity. To it I say: Gloves!


gPXE's capabilities are getting larger, and option ROMs aren't. While we've been able to cram a lot more than one would expect into 64kb by using compression and putting a great deal of effort towards minimizing code size, that can only go so far. The potential trouble appeared with wireless; wireless drivers tend to be much bigger than wired NIC drivers due to a need to initialize a lot of RF parameters (rtl8185, about the smallest driver, is 11kb uncompressed), and the 802.11 link-layer code is also quite hefty (8kb uncompressed) due to the complexities of the 802.11 protocol. Before implementing anything to do with encryption support for wireless, an rtl8185 ROM compiled using stock configuration options is 1,025 bytes too big to fit in 64k. With more common wireless card drivers and encryption, it's only going to get worse; the ath5k driver is roughly five times the size of rtl8185 in Linux, and rtl8185 and ath5k are two of the very few wireless drivers that don't require loading vendor-supplied firmware onto the card to initialize it. (Wikipedia has a good list of possible drivers, though it's slightly out-of-date.)

The total of all option ROMs in a system is limited to 128k; since RAID and SCSI cards generally include an option ROM to allow booting from the array or device they provide, we certainly can't use that whole space. We may be able to get away with a bit over 64k, but not much.

A potential solution is to split out the parts of gPXE that are not essential to loading a small image over the network, and use gPXE itself to load the rest of gPXE, with some code to patch things together so that it acts as a single program once the module image has been loaded.

We certainly wouldn't want this to become the default mode of use; it's not very elegant and it adds setup headaches, and developers who feel they can depend on module loading will be less inclined to put in the additional effort to write concise code. (Consider the explosion that occurred in Linux kernel size after the zImage 512kb limitation went away; my current Linux kernel is 2.4MB.) But there are scenarios where it may well be required to use gPXE at all with certain hardware, particularly wireless hardware.

To avoid losing the benefit of the split, the part of the extension-loading code in gPXE itself would have to be very minimal. Perhaps a simple modification to the ELF loader, that could load ELF images prepended with a !gPXEext ASCII signature or similar and would not shut down gPXE before executing them. Then the extension image itself could include the gPXE symbol table and the symbol fixup function that would enable it to patch itself into the running gPXE executable. There would need to be some mechanism for ensuring the extension image with the symbol table and the gPXE base code that it described didn't get out of sync, perhaps simply checking that some magic symbol pointed correctly at some magic number.

At this point (2009-06-22) this discussion is all highly speculative, and may come to moot if it turns out we can squeeze a modicum of extra kilobytes out of our option ROMs. I'm documenting it here so we have something to refer to if the idea turns out to be necessary after all.