Universal Serial Bus: Difference between revisions

Added most of USB Framework section, made other minor corrections, removed some more of the original wiki content.
[unchecked revision][unchecked revision]
mNo edit summary
(Added most of USB Framework section, made other minor corrections, removed some more of the original wiki content.)
Line 165:
A control transfer always uses it's maximum data payload size for data payloads unless the data payload is less than the maximum data payload size. That is, if an endpoint has a maximum data payload size of 64 bytes, and a control transfer intends to transmit 100 bytes, the first data payload must contain 64 bytes and no less. The remaining 36 bytes are transferred in the second payload and need not be padded to 64 bytes. When the host receives a data payload less than the maximum data payload, the host may consider the transfer complete.
 
A SETUP packettransaction's data payload is always 8 bytes and thus receivable by the endpoint of any USB device. Consequently, the host may query the appropriate descriptor from a newly-attached full-speed device during configuration in order to determine the maximum data payload size for any endpoint; the host can then adhere to that maximum for any future transmissions.
 
===== Transmission Errors =====
Line 776:
[[Image:HSHBIsoOUT.gif|frame|center|Figure 19: Data Phase Sequence for Isochronous OUT High Bandwidth Endpoints]]
 
== TODOUSB Device Framework ==
The USB device framework is the thing that makes USB support so appealing. The transfer types and USB protocol are well-designed, of course, but the USB device framework defines standard device states that all devices must support, as well as standard requests and responses that allow the host to retrieve more than enough information about a device to determine the correct device driver and report information about the device even if the correct device driver isn't available (e.g, the manufacturer's name, the product's name, etc).
Currently the above article is missing the following topics:
* USB Framework
** Device States
** Standard requests and descriptors
* Typical organization of system software
* Hubs (including Split Transactions)
 
=== Functions, Configurations, Interfaces, and Endpoints ===
== Original USB Wiki Content ==
[[Image:FunctionConfigsIFacesEPs.gif|frame|right|Figure 20: Illustration of the relationship between functions, configurations, interfaces, and endpoints.]]
Until the above sections are complete, the original content of this wiki entry that has not been covered in more depth is placed here.
All USB devices, or functions, have at least one configuration, and every configuration has at least one interface. An interface may define zero or more endpoints. This relationship is illustrated in figure 20.
 
Although configurations descriptors are addressed sequentially starting with configuration descriptor zero, each configuration specifies a unique (within the scope of the function), none-zero configuration value. The '''configuration value''' is what the host needs to know in order to apply a certain configuration to a device. When asking for the current configuration of a device, a returned value of zero indicates that the device is not configured and is thus in the address state.
=== USB keyboards/mice ===
 
An '''interface''' defines the functional use of a set of endpoints and may imply that certain class-specific requests can be executed via the default control pipe. Thus, an interface need not necessarily define any additional endpoints. No interface may define the functional use of endpoint zero.
Keyboards and mice are what the USB standard calls HID (Human Interface Device) class devices, and follow a special superset of the USB standard. Once you have a driver for a HID device, all USB HID devices will work with it, including mice, keyboards, joysticks, game controllers, and so forth. The HID standard is built on top of lower-level USB API's to send and receive data packets across the wire, but provides a translation layer that interprets the USB data so that the HID layer could conceivably be implemented on top of other protocols (Like PS/2 or serial).
 
Each interface describes a unique set of endpoints within the scope of the configuration. However, an interface may provide one or more '''alternate settings''', which may have different definitions for the same set of endpoints. When the host selects an alternate setting for an interface, the alternate setting's definitions are used instead of the default settings of the same interface.
For early stages, you can probably ignore the fact that those devices are USB. Virtually every chipsets will offer a good old PS/2 emulation of the USB human interface devices, so you can use I/O port 0x60 like the rest of us ...
 
=== Booting off of a USB flashDevice diskStates ===
A USB device may define states that are internal to the device, however the USB device framework defines a set of states that are visible to both the host and the device. Those visible states are the following:
 
* '''Attached''' - Immediately after the USB device is attached to the USB system, it is in this state. The USB specifications do not define the state of a USB device that is detached from a USB system.
If the [[BIOS]] supports it is it as simple as selecting USB-FDD in the boot order and putting a simple bootloader (grub might do, I rolled my own) into the first 512 bytes of the device. The BIOS will handle all the fancy PCI / USB stuff via int 0x13. Note that there is no need for any specific filesystem or partitions (which means you can just "dd" a 2.2 linux kernel (which used to contain a simple floppy loader) to /dev/sda and it will easily come up).
* '''Powered''' - A device is in this state after it has both been attached to the bus, and the V<span style="vertical-align:sub;">BUS</span> line is applied to the device (the host controller drives the V<span style="vertical-align:sub;">BUS</span> at +5V, however this is only particularly important for hardware developers). In this state, the device must not respond to any bus transactions. The USB specification recognizes three potential scenarios with respect to how a device draws power:
** ''Self-Powered Devices'' draw power from an external power source (e.g, a USB printer plugs into the wall as well as a USB port). Although the device may be considered technically "powered" even before attachment to the USB, it is still only considered powered after the V<span style="vertical-align:sub;">BUS</span> line is applied to the device.
** ''Bus-Powered Devices'' draw power solely from the USB up to 100mA.
** ''Self- or Bus-Powered Devices'' may draw power from either the bus or an external power source, depending on the configuration. These devices may change power source at any time. If a device is currently self-powered and requires more than 100mA of power, but switches to being bus-powered, then the device must return to the Address state.
* '''Default''' - A device in the powered state enters the default state after receiving a bus reset. In this state, the device is addressable at the default, reserved address of 0. At this point, the device is operating at the correct speed. The host is expected to allow 10 milliseconds before expecting the device to respond to data transfers after reset.
* '''Address''' - A device enters this state after the host assigns it an address via the default control pipe, which is always accessible whether the device's address has been set or not.
* '''Configured''' - A device is in this state after the host examines its possible configurations and selects one. All endpoint's data toggle bits are initialized to zero when a device enters this state.
* '''Suspended''' - When no traffic is observed on the bus for a period of 1 millisecond, a USB device enters this state, characterized by its low power consumption. The device's address and configuration settings are maintained while suspended. A device exits the suspended state as soon as it begins seeing bus activity again. The host is expected to allow 10 milliseconds before expecting the device to respond to data transfers after resume.
 
=== AddingRemote USBWakeup supportCapability ===
One of the reasons a USB device may stop seeing USB traffic and thus enter a suspended state is because the host may have entered a suspended state as well. Some devices, typically keyboards and mice, support the ability to issue a remote wakeup signal to the host. In case the host software does not support remote wakeup, this capability must be disabled when a USB device is reset. If the host does support remote wakeup, then it may selectively enable the remote wakeup capability for specific devices (typically as chosen by the user). Then, these devices may issue a remote wakeup signal while in a suspended state to request that the host exits its own suspended state.
 
=== USB Device Enumeration ===
As a first step, you'll need to provide a driver for the USB Host Controller, which appears in most cases as a [[PCI]] device and will allow you to enumerate devices on the USB [[:Category:Buses|bus]] and send packets to the identified devices. Documentation about the [http://www.o3one.org/hwdocs/usb/hcir1_0a.pdf Open Host Controller Interface], [http://developer.intel.com/design/USB/UHCI11D.htm Universal Host Controller Interface] and [http://www.intel.com/technology/usb/download/ehci-r10.pdf Extended Host Controller Interface] are available freely. Your USB-aware chipset should support one of these three.
The following describes the process of bus enumeration, which occurs after a device is connected to a powered port:
 
# The hub to which the device has been attached notifies the host via its status change pipe. The newly attached device is in the powered state at this point, and the port to which it has been attached is disabled.
Once you know what devices are present, you'll have to identify a device-specific driver that will match that hardware. For some devices (webcams, scanners, etc), this may require a vendor-specific driver while other devices (USB keychains, HID etc) have to adhere to _class_ standards. This means that one can write a generic USB storage driver that will work with all possible keychains, embedded mp3 players, flash card readers, etc.
# The host queries more information from the hub to determine that a device has been attached, and to which port.
# The host must wait at least 100 millisecond to allow a device to complete its insertion process, and for power to stabilize at the device. After the delay, the host enables the port and issues a reset signal to the device for at least 50 milliseconds.
# The hub performs any required reset processing. After the reset signal has been released, the port is enabled and the device enters the default state.
# The host assigns the device a unique address, thereby transitioning the device into the address state.
# The host requests the device descriptor from the device via the default control pipe in order to determine the actual maximum data payload size of the default control pipe for the device. This step may occur before or after the host assigns the device an address.
# The host reads all the possible device configuration information.
# The host selects a certain configuration from the list of configurations supported by the device and sets the device to use that configuration. Optionally, the host may also select alternate interface settings within a configuration. All endpoints are initialized as described by the selected configuration, and the device is ready to use.
 
=== USB Device Requests ===
Don't forget that USB devices are hot-pluggable, that is they can be added and removed at any time while the system is running.
Standard, class-specific, and vendor-specific requests are made to the USB device over the default control pipe. The SETUP transaction always has a data payload size of 8 bytes, as noted in the [[#Maximum_Data_Payload_Size|Maximum Data Payload Size]] section of [[#Control_Transfers|Control Transfers]]. The format of the setup data is as follows:
 
{| border="1" cellpadding="5"
=== Brief Sequence of Operation ===
!Offset
!Field
Note: This is taken from [http://forum.osdev.org/viewtopic.php?f=1&t=17111 this thread] and may be inaccurate. It needs adding to at any rate.
!Size
!Type
'''Setup'''
!Description
|- valign="top" align="center"
* 1) Find ''Host Controller Type'', ''Info'' and ''IO address'' using the [[PCI]] bus
|0
* 2) Reset Host
|bmRequestType
* 3) Reset Port
|1
* 4) Check Port status to detect for device insertion
|Bitmap
* 5) Enable Port.
|align="center" |
{| border="1" cellpadding="15"
'''Device Interaction'''
|D<span style="vertical-align:sub;">7</span>
|D<span style="vertical-align:sub;">6</span>
* 1) Get ''Device Descriptor'' of device
|D<span style="vertical-align:sub;">5</span>
* 2) Get ''Config Descriptor'' of device
|D<span style="vertical-align:sub;">4</span>
* 3) Set ''Address'' of device
|D<span style="vertical-align:sub;">3</span>
* 4) Set ''Configuration'' of device
|D<span style="vertical-align:sub;">2</span>
|D<span style="vertical-align:sub;">1</span>
'''Sending Commands'''
|D<span style="vertical-align:sub;">0</span>
|}
Sending commands is protocol specific, this is dependant on the ''Device Type'' (OHCI, UHCI and EHCI - UHCI being the easiest).
{| border="0" cellpadding="0"
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">7</span>'''
The command is send in a similar manner to the Device Interaction section:
|'''Data transfer direction''' ''* The value of this bit is ignored when wLength is zero''<br />
0b = Host-to-device<br />
* 1) Setup ''Queue Heads'' linked list
1b = Device-to-host
* 2) Setup ''Transfer Descriptors'' linked list
|-
* 3) Populate both lists with valid data
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">6...5</span>'''
* 4) Inform ''USB Host Controller'' to start command transaction
|'''Type of request'''<br />
00b = Standard<br />
For '''Mass Storage Devices''' you must send specific commands using the ''CBW'' and ''CBS'' structures. You will also have to implement the following SCSI commands:
01b = Class<br />
10b = Vendor<br />
Inquiry, Get_Capacity and Read_10 or Write_10
11b = Reserved
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">4...0</span>'''
|'''Recipient'''<br />
00000b = Device<br />
00001b = Interface<br />
00010b = Endpoint <br />
00011b = Other <br />
00100b to 11111b = Reserved
|}
|- valign="top" align="center"
|1
|bRequest
|1
|Value
|align="left" |Specific request
|- valign="top" align="center"
|2
|wValue
|2
|Value
|align="left" |Word-sized field the may (or may not) serve as a parameter to the request, depending on the specific request.
|- valign="top" align="center"
|4
|wIndex
|2
|Index or offset
|align="left" |Word-sized field that may (or may not) serve as a parameter to the request, depending on the specific request. Typically this field holds an index or an offset value.<br /><br />
When bmRequestType specifies an endpoint as the recipient, the format of this field is as follows:
{| border="1" align="center"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|Direction
|colspan="3" |Reserved (reset to zero)
|colspan="4" |Endpoint Number
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |Reserved (reset to zero)
|}
The direction bit (bit '''D<span style="vertical-align:sub;">7</span>''') is set to zero to indicate the OUT endpoint with the specified endpoint number, or it is set to one to indicate the IN endpoint with the specified endpoint number. The host should always set the direction bit to zero (but the device should accept either value) when the endpoint is part of a control pipe.
 
When bmRequestType specifies an interface as the recipient, the format of this field is as follows:
==== Configuration ====
{| border="1" align="center"
The configuration part of the USB standard occurs through the notion of descriptors. Descriptors are blocks of information retrieved through the host controller which defines things like vendor/product identifiers for each device and class/subclass/protocol codes for each device's interface. Based on these informations, the Operating System can assign the proper driver to each device/interface.
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="8" |Interface Number
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |Reserved (reset to zero)
|}
|- valign="top" align="center"
|6
|wLength
|2
|Count
|align="left" |Number of bytes to transfer if there is a DATA stage.<br /><br />
If this field is non-zero, and bmRequestType indicates a transfer from device-to-host, then the device must never return more than ''wLength'' bytes of data. However, a device may return less.<br /><br />
If this field is non-zero, and the bmRequestType indicates a transfer from host-to-device, then the host must send exactly ''wLength'' bytes of data. If the host sends more than ''wLength'' bytes, the behavior of the device is undefined.
|}
 
When a device receives a request that is undefined, is inappropriate given the current setting or state of the device, or uses values that are inappropriate for the particular request, then a '''Request Error''' exists. The device handles a Request Error by returning a STALL PID to the next DATA or STATUS stage, preferably at the next DATA stage transaction.
A list of structures defining USB descriptors is available in [http://clicker.cvs.sourceforge.net/*checkout*/clicker/c32-lxsdk/kernel/src/mods/io/include/usbdescr.h usbdescr.h] from Clicker's CVS (LGPL)
 
===== ReadingStandard descriptorsRequests =====
{|border="1" cellpadding="2" style="float:right;margin-left:20px;"
The host has to explicitly request descriptors from the device before it manipulates them. This is achieved by a setup transfer using a GET_DESCRIPTOR as the host->device data and receiving the descriptor as the data from the host. The whole transfer will look like
|+align="bottom" |'''Standard USB Request Codes'''
!bRequest
!Value
|-
|GET_STATUS
|align="center" |0
|-
|CLEAR_FEATURE
|align="center" |1
|-
|''Reserved''
|align="center" |2
|-
|SET_FEATURE
|align="center" |3
|-
|''Reserved''
|align="center" |4
|-
|SET_ADDRESS
|align="center" |5
|-
|GET_DESCRIPTOR
|align="center" |6
|-
|SET_DESCRIPTOR
|align="center" |7
|-
|GET_CONFIGURATION
|align="center" |8
|-
|SET_CONFIGURATION
|align="center" |9
|-
|GET_INTERFACE
|align="center" |10
|-
|SET_INTERFACE
|align="center" |11
|-
|SYNC_FRAME
|align="center" |12
|}
The standard requests are defined for all USB devices, and all USB devices must respond to these standard requests even if the device hasn't been assigned an address, or the device hasn't been configured. To issue a certain request, the software creates the SETUP stage's DATA packet using the appropriate '''request code''', a valid bmRequestType, the appropriate parameter values (or zero, if not applicable) for wValue and wIndex, and the amount of data bytes to be transfered for wLength. To the right are the standard USB device request codes, and the remainder of this section discusses each request.
 
==== SET_ADDRESS ====
* command transaction:
The SET_ADDRESS request has the following SETUP DATA packet format:
Setup_TOKEN(addr=device, endpoint=0) : host -> device
{| align="center" border="1" cellpadding="5"
DATA[ RequestType=0x80, Request=0x06, value=DESCR_TYPE|DESCR_SELECTOR,
|+align="bottom" |'''SET_ADDRESS SETUP DATA Packet Format'''
index=0, length=wished_length] : h->d, 8 bytes
!bmRequestType
ACK : host <- device
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|00000000b
|SET_ADDRESS<br />5
|Device Address
|Zero
|Zero
|}
 
This request does not have a DATA stage, only a SETUP and STATUS stage.
* response transaction:
IN_TOKEN(addr=device, endpoint=0) : host -> device
DATA(the_descriptor) : host <- device (as much bytes as requested)
ACK : host -> device
 
''wValue'' specifies the address to be assigned to the device. The behavior of a device is undefined when ''wValue'' specifies an address greater than 127.
* confirm transaction:
OUT_TOKEN(addr=device, endpoint=0) : host -> device
DATA() : host -> device (empty)
ACK : host <- device
 
The exact behavior of the device after the SET_ADDRESS requests depends on the current state of the device:
The DATA packet in the command transaction is called the "Setup Packet" (according to Beyond Logic), and carries almost all of the 'interesting' stuff:
* When a device is in the default state, a non-zero ''wValue'' causes the device to transition into the address state. When a device is in the default state, a ''wValue'' of zero has no effect.
* When a device is in the address state, a non-zero ''wValue'' keeps a device in the Address state, but the device responds to the newly set address. When a device is in the address state, a ''wValue'' of zero transitions the device into the default state.
* When a device is in the configurd state, device behavior is not defined for the SET_ADDRESS request.
 
This is the only request that is complete after the STATUS stage completes successfully. After the reset/resume recovery interval (10 milliseconds), a device is expected to be able to complete the STATUS stage of this request within 50 milliseconds. After the STATUS stage is complete, the device is allowed a 2 millisecond recovery interval before it must be able to accept farther SETUP packets for additional requests.
* the RequestType of 0x80 (DeviceToHost=0x80| StandardRequest=0| DeviceTargetted=0)
 
* the Request (command) 0x06 for "GET_DESCRIPTOR"
==== GET_DESCRIPTOR ====
* the value (encoding unknown atm)
{|border="1" cellpadding="2" style="float:right;clear:right;margin-left:20px;"
|+align="bottom" |'''Standard USB Descriptor Types'''
!Descriptor Type
!Value
|-
|DEVICE
|align="center" |1
|-
|CONFIGURATION
|align="center" |2
|-
|STRING
|align="center" |3
|-
|INTERFACE
|align="center" |4
|-
|ENDPOINT
|align="center" |5
|-
|DEVICE_QUALIFIER
|align="center" |6
|-
|OTHER_SPEED_CONFIGURATION
|align="center" |7
|-
|INTERFACE_POWER
|align="center" |8
|}
The GET_DESCRIPTOR request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_DESCRIPTOR SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!colspan="2" |wValue
!wIndex
!wLength
|- align="center"
|10000000b
|GET_DESCRIPTOR<br />6
|Descriptor Type
|Descriptor Index
|Zero or<br />Language ID
|Descriptor<br />Length
|}
 
The high-order byte of ''wValue'' specifies the descriptor type (see table of usb standard descriptor types, to the right). The low-order byte of ''wValue'' is only used for selecting a specific STRING or CONFIGURATION descriptor, and should be reset to zero otherwise.
 
The ''wIndex'' field is only used for STRING descriptors to specify the desired language and should be reset to zero for other descriptor types.
 
Different descriptor types have different lengths which will be discussed soon. If ''wLength'' is less than the size of the descriptor being returned, then the device only returns the first ''wLength'' bytes of the descriptor data. If ''wLength'' is larger than the size of the descriptor being returned, than the full descriptor is returned, followed by a short packet (a packet shorter than the maximum data payload size, including a length of 0 bytes).
 
All USB devices must support requests for DEVICE, CONFIGURATION, and STRING descriptors. All high-speed devices must support basic operations at full-speed; such devices also support DEVICE_QUALIFIER and OTHER_SPEED_CONFIGURATION descriptors which return the same data that the device would return for DEVICE and CONFIGURATION descriptor requests, respectively, if the device were operating at the speed at which it is not currently operating.
 
A request for a CONFIGURATION descriptor also returns all the INTERFACE descriptors for the specified configuration descriptor index (i.e, the low-order byte of ''wValue''), as well as all of the ENDPOINT descriptors associated with all of the returned INTERFACE descriptors, all in a single request.
 
GET_DESCRIPTOR is a valid request for a device in the default, address, or configured state.
 
==== SET_DESCRIPTOR ====
The SET_DESCRIPTOR request is optional; when it is supported, it may be used to update descriptors or add new ones.
 
The SET_DESCRIPTOR request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_DESCRIPTOR SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!colspan="2" |wValue
!wIndex
!wLength
|- align="center"
|00000000b
|SET_DESCRIPTOR<br />7
|Descriptor Type
|Descriptor Index
|Zero or<br />Language ID
|Descriptor<br />Length
|}
 
The high-order byte of ''wValue'' specifies the descriptor type. The low-order byte of ''wValue'' is only used for selecting a specific STRING or CONFIGURATION descriptor, and should be reset to zero otherwise.
 
The ''wIndex'' field is only used for STRING descriptors to specify the desired language and should be reset to zero for other descriptor types.
 
The ''wLength'' field specifies how many bytes will be transfered from the host to the device.
 
This request only supports DEVICE, CONFIGURATIOn, and STRING descriptor types.
 
If this request is not supported, the device responds with a Reuqest Error.
 
If this request is supported, it is only valid when the device is in the address or configured state; the behavior of the device is undefined if this request is made while the device is in the default state.
 
==== GET_CONFIGURATION ====
The GET_CONFIGURATION request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_CONFIGURATION SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000000b
|GET_CONFIGURATION<br />8
|Zero
|Zero
|One
|}
 
The device sends a one-byte DATA packet during the DATA phase of the control transfer. This byte is the value of the current configuration of the device. A value of zero indicates that the device has not yet been configured (it is in the address state). Behavior of a device is undefined if this request is issued while the device is in the default state.
 
==== SET_CONFIGURATION ====
The SET_CONFIGURATION request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_CONFIGURATION SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!colspan="2" |wValue
!wIndex
!wLength
|- align="center"
|00000000b
|SET_CONFIGURATION<br />9
|''Reserved''
|Configuration Value
|Zero
|Zero
|}
 
The low-order byte of ''wValue'' specifies the desired configuration value. The low-order byte of ''wValue'' must either be zero, or it must match the configuration value field of a configuration descriptor returned by the device. Specifying a configuration value of zero sets the device into the address state.
 
If the device is in the default state, or if the high-order byte of ''wValue'' is not zero, ''wIndex'' is not zero, or ''wLength'' is not zero, then the behavior after issuing this request is undefined.
 
If the specified configuration value is neither zero nor a valid configuration value specified by a configuration descriptor of the device, the device responds with a Request Error.
 
==== GET_INTERFACE ====
The GET_INTERFACE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_INTERFACE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000001b
|GET_INTERFACE<br />10
|Zero
|Interface
|One
|}
 
The host uses this request to determine which alternate setting (as described in [[#Functions.2C_Configurations.2C_Interfaces.2C_and_Endpoints|Functions, Configurations, Interfaces, and Endpoints]]) is used for a particular interface of the current configuration. The device responds with a one-byte long DATA packet during the data phase, the transfered byte being the alternate setting value for the interface specified in this request.
 
If ''wValue'' is not zero, ''wLength'' is not one, ''wIndex'' specifies an invalid interface, or the device is in the address state, then the device responds with a Request Error.
 
The behavior of a device in the default state after receiving this request is undefined.
 
This request is valid for a device in the configured state.
 
==== SET_INTERFACE ====
The SET_INTERFACE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_INTERFACE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|00000001b
|SET_INTERFACE<br />11
|Alternate Setting
|Interface
|Zero
|}
 
The host uses this request to select an alternate setting (as described in [[#Functions.2C_Configurations.2C_Interfaces.2C_and_Endpoints|Functions, Configurations, Interfaces, and Endpoints]]) to be used for a particular interface of the current configuration. If the interface specified only supports a default setting, then the device may return a STALL handshake during the STATUS stage of the request.
 
If the interface or alternate setting do not exist, or if the device is in the address state, then the device responds with a Request Error. The behavior of the device is undefined if ''wLength'' is not zero, or the device is in the default state.
 
This is a valid request when the device is in the configured state.
 
==== CLEAR_FEATURE ====
{| style="clear:right;float:right;margin-left:20px;" border="1" cellpadding="2"
|+align="bottom" |'''Standard USB Feature Selectors'''
!Feature Selector
!Recipient
!Value
|-
|DEVICE_REMOTE_WAKEUP
|align="center" |Device
|align="center" |1
|-
|ENDPOINT_HALT
|align="center" |Endpoint
|align="center" |0
|-
|TEST_MODE
|align="center" |Device
|align="center" |2
|}
The CLEAR_FEATURE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''CLEAR_FEATURE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|00000000b<br />00000001b<br />00000010b
|CLEAR_FEATURE<br />1
|Feature Selector
|Zero or<br />Interface or<br />Endpoint
|Zero
|}
 
The host uses this request to clear or disable a specific feature.
 
''wValue'' must contain a feature selector (see table of Standard USB Feature Selectors, to the right) which corresponds with the recipient as specified in the ''bmRequestType'' value.
 
Issuing this request while referencing a feature that cannot be cleared or does not exist, or referencing an interface or endpoint that does not exist will cause the device to respond with a Request Error.
 
If the device is in the default state, or ''wLength'' is non-zero, then the behavior of the device is undefined.
 
This request is valid when the device is in the configured state. When the device is in the address state, this request is only valid when referencing endpoint zero, otherwise the device responds with a Request Error.
 
The TEST_MODE feature cannot be cleared by this request.
 
==== SET_FEATURE ====
{| style="clear:right;float:right;margin-left:20px;" border="1" cellpadding="2"
|+align="bottom" |'''Standard USB Test Selectors'''
!Value
!Description
|-
|align="center" |00h
|''Reserved''
|-
|align="center" |01h
|Test_J
|-
|align="center" |02h
|Test_K
|-
|align="center" |03h
|Test_SE0_NAK
|-
|align="center" |04h
|Test_Packet
|-
|align="center" |05h
|Test_Force_Enable
|-
|align="center" |06h-3Fh
|''Reserved for standard test selectors''
|-
|align="center" |3Fh-BFh
|''Reserved''
|-
|align="center" |C0h-FFh
|''Reserved for vendor-specific test modes''
|}
The SET_FEATURE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_FEATURE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!colspan="2" |wIndex
!wLength
|- align="center"
|00000000b<br />00000001b<br />00000010b
|SET_FEATURE<br />3
|Feature Selector
|Test selector
|Zero or<br />Interface or<br />Endpoint
|Zero
|}
The host uses this request to set or enable a specific feature.
 
''wValue'' must contain a feature selector which corresponds with the recipient as specified in the ''bmRequestType'' value.
 
When ''wValue'' selects the TEST_MODE feature, ''bmRequestType'' and the low-order byte of ''wIndex'' must both be reset to zero. The high-order byte of ''wIndex'' must be a valid test selector (see table of Standard USB Test Selectors, to the right), or the device respond with Request Error. The device must set its upstream-facing port into test mode no longer than 3milliseconds after completing the STATUS stage of this request. In order to exit test mode, the power to the device must be cycled. A device must support the TEST_MODE feature in the default, address, and configured high-speed device states.
 
If this request references a feature that does not exist or cannot be set, then the devices responds with a STALL handshake during the STATUS stage.
 
If an endpoint or interface is specified that does not exist, or if the device is in the address state and an endpoint other than endpoint zero is specified, the device responds with a Request Error.
 
Besides requests which select the TEST_MODE feature, issuing this request to a device in the default state results in undefined behavior. A non-zero value for ''wLength'' also results in undefined behavior.
 
This request is valid when a device is in the configured state, or when the device is in the address state and only endpoint zero is referenced.
 
==== GET_STATUS ====
The GET_STATUS request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_STATUS SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000000b<br />10000001b<br />10000010b
|GET_STATUS<br />0
|Zero
|Zero or<br />Interface or<br />Endpoint
|Two
|}
 
The host uses this request to learn the status of the recipient, as specified by the ''bmRequestType'' field and, in the case of an interface or endpoint recipient, the ''wIndex'' field.
 
If ''wValue'' is not zero, ''wLength'' is not two, or ''wIndex'' is non-zero when ''bmRequestType'' specifies a device recipient, or the device is in the default state, then the behavior of the device is undefined.
 
If this request references an endpoint or interface that does not exist (including any endpoint other than endpoint zero when the device is in the address state), then the device responds with a Request Error.
 
In response to this request, the device issues a 2 byte long data transfer during the DATA stage to the host. These two bytes represent the requested status and the meaning depends on the recipient type.
 
===== Device Recipient =====
When the recipient was a device, the two bytes describe the status as follows:
{| align="center" border="1"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="6" |''Reserved (reset to zero)''
|Remote<br />Wakeup
|Self<br />Powered
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|}
The ''Self Powered'' field is set to 1 to indicate that the device is currently powered by an external power source, or 0 to indicate that the device is currently running on power supplied by the bus.
 
The ''Remote Wakeup'' field is set to 0 when the device is reset and indicates whether or not the device is currently enabled to perform remote wakeup signaling (see [[#Remote_Wakeup_Capability|Remote Wakeup Capability]]). The host may modify the value of the ''Remote Wakeup'' field by issuing either a CLEAR_FEATURE or SET_FEATURE request using the DEVICE_REMOTE_WAKEUP feature selector.
 
===== Interface Recipient =====
When the recipient was an interface, the two bytes describe the status as follows:
{| align="center" border="1"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|}
 
===== Endpoint Recipient =====
When the recipient was an endpoint, the two bytes describe the status as follows:
{| align="center" border="1"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="7" |''Reserved (reset to zero)''
|Halt
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|}
 
All interrupt and bulk endpoint types must implement the halt feature, otherwise it is optional. The ''Halt'' field reflects the status of the halt feature of the endpoint. A value of 0 in the ''Halt'' field indicates that the endpoint is not halted, and a value of 1 in the ''Halt'' field indicates that the endpoint is halted.
 
The host may set the halt feature of an endpoint with the SET_FEATURE request using the ENDPOINT_HALT feature selector, or the host may clear the halt feature of an endpoint with the CLEAR_FEATURE request using the ENDPOINT_HALT feature selector. When the CLEAR_FEATURE request is used in this manner, and the endpoint uses a data toggle bit, the data toggle bit is reset to zero.
 
The default control pipe is not required nor recommended to implement the halt feature, but some devices may choose to use the halt feature on the default control pipe to reflect a functional error condition. When the halt feature is set on the default control pipe, the device responds with a STALL handshake during the DATA or STATUS stage of all transfers with the exception of the GET_STATUS, CLEAR_FEATURE, and SET_FEATURE standard requests. Additionally, the device is not required to stall vendor- or class-specific requests when the halt feature is set.
 
==== SYNCH_FRAME ====
The SYNCH_FRAME request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SYNCH_FRAME SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000010b
|SYNCH_FRAME<br />12
|Zero
|Endpoint
|Two
|}
 
This request is only used for isochronous endpoints that use implicit pattern synchronization. That is, some isochronous endpoints require per-frame transfers to vary in size according to a specific pattern (in order to attain an application-specific bit rate, for example). This call causes the device to send the host a 2 byte value that is the number of the frame where the pattern began.
 
High-speed isochronous endpoints that support this request must synchronize to the zeroth microframe, as well as have a time notion of classic frames (1 millisecond as opposed to 125 microsecond intervals).
 
If ''wValue'' is not zero, ''wLength'' is not two, or the device is in the default state, then the behavior of the device is undefined.
 
If the specified endpoint does not support this request, or the device is in the address state, then the device responds with a Request Error.
 
This request is valid when the device is in the configured state.
 
=== Standard USB Descriptors ===
A '''descriptor''' is a data structure with a defined format. All standard descriptors begin with two bytes. The first byte specifies the total length of the descriptor in bytes, including the first two mandatory bytes. The second byte identifies the type of the descriptor.
 
Some descriptors contain fields which specify an index of a STRING descriptor, but it is optional for a device to support STRING descriptors. If a device does not support STRING descriptors, then all fields which reference an index of a STRING descriptor should be reset to zero. Thus, a value of zero in any field that is meant to supply an index of a STRING descriptor indicates that no such STRING descriptor is available.
 
If the second byte of a descriptor identifies that descriptor as one of the standard USB descriptors, but the first byte of that descriptor specifies a length less than the lengths defined in the USB 2.0 Specifications (and, transitively, here), then the descriptor should be rejected by the host. If the length field reports that the descriptor is longer than expected, then the extra data should be ignored, but still considered part of the descriptor (this is important when the device is returning multiple descriptors, as is the case when the host requests a CONFIGURATION descriptor).
 
If class- or vendor-specific descriptors use the same format as standard descriptors (i.e, the two mandatory bytes at the beginning of the descriptor), then the class- or vendor-specific descriptors are interleaved within the results when the host requests a CONFIGURATION descriptor. Otherwise, the class- or vendor-specific descriptors are accessed by passing a class- or vendor-specific descriptor type in a GET_DESCRIPTOR request.
 
The remainder of this section serves to catalog the standard USB device descriptors and very closely mirrors section 9.6 of the USB 2.0 Specifications. These descriptor definitions supplement the [[#GET_DESCRIPTOR|GET_DESCRIPTOR]] request.
 
==== DEVICE ====
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|-
|align="center" |0
|bLength
|align="center" |1
|Number
|Size of this descriptor in bytes
|-
|align="center" |1
|bDescriptorType
|align="center" |1
|Constant
|DEVICE Descriptor Type
|-
|align="center" |2
|bcdUSB
|align="center" |2
|BCD
|USB Specification Release Number in Binary-Coded Decimal (i.e, 2.10 is expressed as 210h). Identifies the release of the USB Specification with with the device and its descriptors are compliant.
|-
|align="center" |4
|bDeviceClass
|align="center" |1
|Class
|Class code (assigned by the USB-IF)
|-
|align="center" |5
|bDeviceSubClass
|align="center" |1
|SubClass
|Subclass Code (assigned by the USB-IF)
|-
|align="center" |6
|bDeviceProtocol
|align="center" |1
|Protocol
|Protocol code (assigned by the USB-IF)
|-
|align="center" |7
|bMaxPacketSize0
|align="center" |1
|Number
|Maximum packet size for endpoint zero (8, 16, 32, or 64 are the only valid options)
|-
|align="center" |8
|idVendor
|align="center" |2
|ID
|Vendor ID (assigned by the USB-IF)
|-
|align="center" |10
|idProduct
|align="center" |2
|ID
|Product ID (assigned by the USB-IF)
|-
|align="center" |12
|bcdDevice
|align="center" |2
|BCD
|Device release number in binary-coded decimal
|-
|align="center" |14
|iManufacturer
|align="center" |1
|Index
|Index of STRING descriptor describing manufacturer
|-
|align="center" |15
|iProduct
|align="center" |1
|Index
|Index of STRING descriptor describing product
|-
|align="center" |16
|iSerialNumber
|align="center" |1
|Index
|Index of STRING descriptor describing the device's serial number
|-
|align="center" |17
|bNumConfigurations
|align="center" |1
|Number
|Number of possible configurations
|}
 
==== DEVICE_QUALIFIER ====
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|-
|align="center" |0
|bLength
|align="center" |1
|Number
|Size of this descriptor in bytes
|-
|align="center" |1
|bDescriptorType
|align="center" |1
|Constant
|DEVICE_QUALIFIER Descriptor Type
|-
|align="center" |2
|bcdUSB
|align="center" |2
|BCD
|USB Specification Release Number in Binary-Coded Decimal (i.e, 2.00 is expressed as 200h). Identifies the release of the USB Specification with with the device and its descriptors are compliant.
|-
|align="center" |4
|bDeviceClass
|align="center" |1
|Class
|Class code (assigned by the USB-IF)
|-
|align="center" |5
|bDeviceSubClass
|align="center" |1
|SubClass
|Subclass Code (assigned by the USB-IF)
|-
|align="center" |6
|bDeviceProtocol
|align="center" |1
|Protocol
|Protocol code (assigned by the USB-IF)
|-
|align="center" |7
|bMaxPacketSize0
|align="center" |1
|Number
|Maximum packet size for endpoint zero (8, 16, 32, or 64 are the only valid options)
|-
|align="center" |8
|bNumConfigurations
|align="center" |1
|Number
|Number of possible configurations
|-
|align="center" |9
|bReserved
|align="center" |1
| -
|Reserved for future uses, but be zero.
|}
 
==== CONFIGURATION ====
 
==== OTHER_SPEED_CONFIGURATION ====
 
==== INTERFACE ====
 
==== ENDPOINT ====
 
==== STRING ====
 
 
== TODO ==
Currently the above article is missing the following topics:
* USB Framework
** Finish standard descriptors section
* Typical organization of system software
* Hubs (including Split Transactions)
 
== Original USB Wiki Content ==
Until the above sections are complete, the original content of this wiki entry that has not been covered in more depth is placed here.
 
=== USB keyboards/mice ===
 
Keyboards and mice are what the USB standard calls HID (Human Interface Device) class devices, and follow a special superset of the USB standard. Once you have a driver for a HID device, all USB HID devices will work with it, including mice, keyboards, joysticks, game controllers, and so forth. The HID standard is built on top of lower-level USB API's to send and receive data packets across the wire, but provides a translation layer that interprets the USB data so that the HID layer could conceivably be implemented on top of other protocols (Like PS/2 or serial).
 
For early stages, you can probably ignore the fact that those devices are USB. Virtually every chipsets will offer a good old PS/2 emulation of the USB human interface devices, so you can use I/O port 0x60 like the rest of us ...
 
=== Booting off of a USB flash disk ===
 
If the [[BIOS]] supports it is it as simple as selecting USB-FDD in the boot order and putting a simple bootloader (grub might do, I rolled my own) into the first 512 bytes of the device. The BIOS will handle all the fancy PCI / USB stuff via int 0x13. Note that there is no need for any specific filesystem or partitions (which means you can just "dd" a 2.2 linux kernel (which used to contain a simple floppy loader) to /dev/sda and it will easily come up).
 
== See Also ==
Anonymous user