7/22/2014

iPXE, support for USB NIC booting


Syslinux is an awesome toolkit by highly talented H. Peter Anvin, next to Linus Tovald he's one of the brightest people I've ever known.

A while ago I messaged him about the idea of USB NIC support in iPXE, since that seemed to be the successor to Etherboot.

The idea was that since isolinux, syslinux and pxelinux were all bootloaders exploiting the native 16 bit BIOS to do various things.. as if it were a mini-operating system.. how about adding USB NIC support?

It's a little more complicated than I thought.. first you have to figure out how your going to get your initial boot loader running. For Syslinux or PXE Linux that involves the native BIOS bootstrap loader that initializes and loads code from a hard disk, or configures and downloads code over a "supported" Ethernet device plugged into something like an ISA or PCI bus.. PXE Linux is great, but it still needs a minimal hardware driver to support that "bus" that acts as a bridge to the network card or adapter.

Since BIOS normally initializes the ISA or PCI bus, that step is pretty simple, its already done by the time your code starts executing, then all you have to do is probe for the attached network hardware and initialize that.. and perform a dhcp protocol routine and a trivial file transfer to download the network boot program (according to the PXE protocol) and turn control over to that.. mission accomplished.

Peter worked with several groups to bring Syslinux and PXE Linux up to where it could work with the myriad ethernet device drivers that were becoming a part of the etherboot, ipxe and gpxe projects.. code reuse is very valuable and orchestrating an interface between multiple code bases is a true skill.

So that bridge crossed, what about USB NICs and PXE support?

Well in theory you would need to bootstrap your code via one of the mechanisms of the BIOS, a hard disk, a different PCI network adapter, ect.. and then load a driver you wrote to "initialize" the USB hardware so that you could then "probe" the USB bus for a network card or adapter and then "initialize" that.. once the hardware is setup and "Ready" then the iPXE or some other PXE code implementation being reused can take over and finish the PXE protocol and download another bootloader program.. like for instance an installer kernel.. or a whole network operating system kernel.

The problem here though.. is something has to initialize the USB hardware, if the USB controller is built into the system the BIOS probably already does that, but it may only support things like a keyboard, a mouse, ect.. and almost surely won't have support for the specific USB NIC chipset in your USB dongle.. there are just too many of them.. the odds are against it.

And to make it more complicated, there have been USB 1.0, 1.1, 2.0 and 3.0

How you set them up and use them varies quite a bit. They are generally different hardware chipsets.

So let's narrow the scope to those most likely to be encountered, say USB 2.0 and USB 3.0 then go further and say only one specific chipset of each.. your USB NIC driver then has to interface with each of those to find and initialize the USB NIC chipset.. not impossible, but this is mostly 16 bit assembly code.. even if written using mostly C or C++ to pull the assembly "strings".

A person did start down this path

Summary This project will enable gPXE to use USB Ethernet Adapters. This includes, Adding USB support to gPXE. Writing a network device driver for an USB Ethernet Adapter.

(not me), for what its worth, here are my notes:

centos 5.9 i386 with EPEL for RHEL 5.4 enabled and yum updated

then

yum install git

check out the git branch - that appears - to be - the one merged up to from ohci <- which is the oldest branch

# git clone git://git.etherboot.org/people/balajirrao/gpxe.git -b usb

cd gpxe/src
make

appears to compile cleanly, almost

Next Steps

Two avenues, study the "Balaji Rao" code base, or consider borrowing an existing USB driver code base from another kernel..  use whatever hardware I have on hand. With an eye to broadening the base to support other USB controller chipsets, and USB NIC chipsets later.

And also another option is let BIOS initialize the USB chipset and simply assume its ready and "use it" rather than setting it up again. Tricky but possible.

Assuming Phoneix or AMI have some standards for their BIOS Interfaces for USB chipset support.. then it becomes a matter of "finding" the USB NIC and identify its chipset type and initializing it, then handing it off to the PXE driver routine.. mission accomplished. I rather like this idea, but I do not know enough about Phoneix and AMI 16 bit programming or where to source public information on this topic. I would think the USB Chipset vendors themselves would publish some reference 16 bit BIOS drivers and those might be integrated or adopted by Phoenix or AMI.. since its in the interests to sell most chips by volume.. the information might be fairly common and available.

SMSC provided some input to the Linux kernel in 2008 providing what looks like a driver for their USB NIC chipset here:

SMSC LAN9500 USB2.0 10/100 ethernet adapter driver

Another useful link: (taking apart an ASIX usb to nic adapter)

Anatomy of a cheap USB to Ethernet adapter