[coreboot] SeaBIOS and USB?

Kevin O'Connor kevin at koconnor.net
Fri Dec 26 23:37:28 CET 2008

SeaBIOS is now booting multiple operating systems on real hardware
(including WinXP, WinVista, Linux, Freedos, etc.).  I think it is time
to start looking at the next steps for SeaBIOS.

USB support is a feature that SeaBIOS must have in order to be
competitive with an "off the shelf" bios.  I've spent some time
investigating how this could be added.  This email is to gather
feedback from the coreboot developers and to see if there is an
approach that makes sense.

A legacy bios typically has two main USB features - usb mass storage
handling and usb keyboard/mouse handling.  The former is needed to
support booting from flash drives, external hard drives, and usb
cdroms.  The latter is needed because some users only have a usb
keyboard - indeed, many machines no longer have PS/2 ports.

Both of the above require usb code that runs in 16bit mode.  This
certainly complicates the usb support - there are several open source
projects that implement usb, but I'm not aware of any with this
requirement.  Since SeaBIOS is compiled with gcc a lot of the issues
with 16bit mode wont be a problem; however, the memory restrictions of
16bit mode can't be ignored.

Some info on the usb requirements:

Mass storage requirements: The usb drive support looks to be straight
forward.  There is a document describing the minimum commands a bios
can expect to have from a drive capable of booting the machine (search
usb_msc_boot_1.0.pdf).  It would seem that the 16bit code need only
support sending BulkOut packets and receiving BulkIn packets.
Interrupt support would not be needed, as the bios can poll for
completion of requests.

Keyboard/mouse requirements: Thankfully, full HID support is not
needed as the USB spec includes a "boot" mode for keyboard and mice.
The limited features of "boot" mode is sufficient for our purposes.
The 16bit code would need to be able to send Control packets and
receive InterruptIn packets.  It looks like it will be necessary to
have a USB interrupt handler - the 16bit code will need to catch an
interrupt, extract the kbd/mouse data, and then ack the irq.

I think it would be possible to add the above USB support to SeaBIOS.
The initialization phase of SeaBIOS (aka "post") runs in 32bit mode
today.  The usb setup, bus scan, and hub detection can all be done
during this post phase.  All the dma setup, device initialization, and
endpoint connections can also be done.  It should then be possible to
arrange for a handful of "transfer descriptors" to be setup in memory
below 1MiB for all the requests that could be needed when in 16bit
mode.  The 16bit mode code would then only need to know how to fill
out a "transfer descriptor" to communicate with the usb devices.

This would require that SeaBIOS add support for uhci and ohci
controllers.  (Support for ehci would also be possible, but it would
only speed up mass storage support - it is probably not worth the
complexity.)  It would also be necessary to setup irqs on the usb
controller.  In particular, this means coreboot will need to populate
PCI_INTERRUPT_LINE and make sure that the pci devices are available in
PIC mode.

This type of support would limit the ability for the BIOS to support
"plug and play" with devices.  Only devices found during "post" would
be available after post, and any device found during post but
subsequently removed would no longer be available.  However, the
primary target for SeaBIOS is support for OS loaders (eg,
lilo/grub/ntldr), and I don't think supporting plug-and-play during
the small time window from bios post to OS load is critical.

Finally, this style of support would not emulate a keyboard/mouse for
software that uses direct PS/2 io port accesses (0x60/0x64).  However,
I have confirmed that none of lilo, grub, nor the windows boot loader
directly access these ports.  (Indeed, even freedos calls the bios to
read the keyboard/mouse.)

An alternative to the above plan would be to implement an SMI handler
for USB support.  I read somewhere that "off the shelf" bios
frequently do this.  Using an SMI handler would allow the usb code to
all be 32bit, and it would allow full emulation of PS/2 keyboard/mouse
accesses (ioport 0x60/0x64).

However, there are some disadvantages to using an SMI handler: SMI
appears to be board specific to setup, SMI has a "bad rap" among many
developers, it may not be easy to share an SMI handler with vendor
code and bios usb code, and it might be difficult to coordinate
kbd/mouse and disk accesses if only part is done with SMI.

One nice tool that already has USB support (uhci) is libpayload.
Unfortunately, libpayload seems to be targeted for standalone
"applications" and it doesn't seem to fit SeaBIOS' model.  Because
SeaBIOS needs to support 16bit callbacks it has more stringent
requirements then a typical bootloader does.  (An example of this in
libpayload is the malloc call - malloc doesn't make sense in seabios
because there are distinct areas that one can grab memory from (high
memory, ebda, f segment, option rom area, etc.).  The parameters to
malloc aren't descriptive enough to convey these requirements.)

One way forward would be to introduce these complications to
libpayload and then use libpayload in seabios.  Another option would
be to introduce separate usb support in seabios.

Well - that was a long email - thanks for reading.  Any thoughts?


More information about the coreboot mailing list