THE USB DRIVER SPECIFICATIONS

USB Controllers
First, you need to know what kind of USB "Host Controller" hardware you have. Mainstream hardware has one of three kinds, named after the hardware register-level "Host Controller Interface" (HCI) they implement. The first one was Intel's "Universal" HCI (UHCI). That type of controller doesn't do very much in hardware, which makes the software do more work (and need more memory). Most controllers on Intel or Via chipsets use UHCI. The second kind of USB 1.1 host controller was organized by Compaq and several other companies, and had fewer "Intellectual Property" restrictions. That was called the "Open" HCI (OHCI), and does quite a bit more of USB in hardware. Learning that two kinds of register interface was one too many, USB 2.0 defined just one, with much less legal encumbrance. The third, and newest, kind is the "Enhanced" HCI (EHCI), and is the only kind used to talk to high speed devices. Source: www.linux-usb.org.

USB Support in Qemu
QEMU emulates a PCI UHCI USB controller and a 8 port USB hub connected to it. You can virtually plug to the hub virtual USB devices or real host USB devices (experimental, works only on Linux hosts). Source: Qemu manual

A virtual USB mouse device is available for testing in QEMU: here. You can add -usbdevice mouse on the command line.

The goal for LSE/OS
The goal is to have at least the mouse driver working for UHCI (the simplest protocol) with two methods: IO based and memory based (see detail in next section).

Development resources
The following resources are available for development:

  • The Qemu sources contains an emulation of UHCI (in 'hw' directory, especially the file usb-uhci.c): It is easy to recompile it and wrap source to print debug message. It is also very useful to understand how USB packets are handled.
  • Access to PCI devices can be done according to two methods: IO based (with inb() and oub()) or memory based. Remember: unlike ISA where ioports are fixed, this is the PCI controller that decides which ioport will be used. An example of PCI based driver that implement both can be found here in lseos-srv/net/rtl8139 (the Realtek Ethernet Driver).
  • The 8237 driver example in Writing Driver Tutorial explains how to create syscall entry points.

    Development environment
    For development, no need to have the unix glue, so use the following minimal conf in the conf/in/config file:

    #define USE_BOCHS
    
    #define NEED_PIC
    #define LAUNCH_PIC
    
    #define NEED_TIMER
    #define LAUNCH_TIMER
    
    #define NEED_PCI
    #define LAUNCH_PCI
    
    #define NEED_SASH
    #define LAUNCH_SASH
    
    Try to boot the image. You should have a sash prompt. List the PCI devices for example:
    sash> lspci
    

    Directory structure
    The source code shall be the following:

    $ cd lseos-srv/hw/usb/uhci/
    $ ls
    uhcireg.h uhcivar.h main.c libuhci.h libuhci.c
    

    There shall be builtin 'testusb' in sash for testing the mouse. You simply have to add a command in lseos-cmd/sash/cmdtab.c.

    Source code structure
    You should have the same code structure as in the 8237 driver:

  • Low_Level_Functions: function that accesses the hardware
  • Syscalls: services to tasks
  • Syscall_Entry_Point: the taskgate stuff and the main switch case for syscalls.
  • Main: creation of the service, enabling of ioports/memory mapped io, start of the service

    Good luck!