Software interface for a hardware device

Automatically generating code used with device drivers for interfacing with hardware. The method includes receiving a machine readable description of a hardware device, including at least one of hardware registers or shared memory structures of the hardware device. The method further includes determining an operating system with which the hardware device is to be used. The method further includes processing the machine readable description on a code generation tool to automatically generate code for a hardware driver for the hardware device specific to the determined operating system.

BACKGROUND

Background and Relevant Art

General purpose computing systems can utilize a number of devices by using code known as device drivers. The device drivers function as a way to interface hardware or other devices to system resources, such as CPU registers, system memory registers, etc. Device drivers typically run in kernel mode, which is a privileged mode. In particular, in kernel mode, driver code can access any memory address and control any system level component. Hence, a defective or malicious driver can readily compromise the integrity of the computing system, leading to crashes or data corruption.

Thus, device drivers are unsafe. While object oriented design methodologies, language type-safety and static code verification find their way into advanced platforms (e.g. the so-called cloud) and development environments, device drivers are still developed using unsafe languages (e.g. C/C++) and are accessed using type-less, non-object-oriented and error-prone interfaces. Most device drivers are still executed in kernel mode increasing the potential for a single software bug to cause a system failure. Further, insofar as any drivers are implemented in user mode, they are not now capable of being used for high throughput and low latency devices because, in some operating systems, hardware interrupts cannot be delivered efficiently to a user mode process. In other operating systems, the performance of a user mode driver is significantly worse than a kernel mode driver.

Hardware manufacturers typically describe the hardware in free form hardware specifications. Driver developers use these specifications to develop a hardware access layer. This layer enables a driver to interact with device registers and shared memory. Developing this layer is both tedious and error prone as it depends on the quality of the specification and developer's experience. In most cases this layer is operating system dependent and cannot be used by other platforms.

BRIEF SUMMARY

One embodiment illustrated herein includes a method practiced in a computing environment including acts for automatically generating code used by device drivers to interact with the hardware device. The method includes receiving a machine readable description of a hardware device, including at least one of hardware registers or shared memory structures of the hardware device. The method further includes determining an operating system with which the hardware device is to be used. The method further includes processing the machine readable description on a code generation tool to automatically generate code for a hardware driver for the hardware device specific to the determined operating system.

DETAILED DESCRIPTION

Embodiments disclosed herein may include a number of techniques that facilitate the development of high-performance user mode and type safe drivers for all device types. The drivers deliver performance that is comparable to legacy kernel mode device drivers existing in other operating systems.

Some embodiments may implement an auto-generating device driver hardware abstraction layer. As illustrated inFIG. 1, a hardware device102interfaces with the computing system104using registers106in the CPU108and shared memory110in system memory112. The hardware device is typically built in a static fashion to interface with particular registers in the sets of registers106and with particular memory interaction. To ensure that the system104and the registers106and shared memory110, interface properly with the hardware device102, a driver114is used that provides the mapping to and from the system hardware to the device hardware. Drivers114are typically developed manually by using manufacturer provided textual specifications.

Hardware manufacturers typically describe the hardware in free form hardware specifications. Driver developers use these specifications to develop a hardware access layer. As noted, this layer enables a driver to interact with device registers and shared memory, such as by using direct memory access (DMA). Developing this layer is both tedious and error prone as it depends on the quality of the specification and developer's experience. In most cases this layer is operating system dependent and cannot be used by other platforms.

Some embodiments herein simplify driver development by implementing a hardware abstraction mechanism for separating the hardware access layer specification from its implementation. A machine readable hardware specification116can be provided by the device vendor. The machine readable hardware specification is processed by a code generation tool118. The code generation tool118has operating system context for one or more different operating systems and thus can automatically create a hardware device interface layer by processing the machine readable hardware specification116. Thus, the machine readable hardware specification116can be reused to create hardware device interface layers115-1,115-2through115-nfor multiple different operating systems and using various different programming languages. This scheme greatly simplifies driver development and reduces the amount of errors caused by incorrect hardware access. The machine readable hardware specification116can be written in a simple language, such as C# and can be easily validated via inspection.

Thus, a developer or hardware manufacturer can describe the device102hardware registers and shared memory structures (in host memory) using a hardware-software interface language. For this purpose the developer consults the textual hardware specification. Note that a hardware engineer or the hardware vendor can also provide the hardware-software interface description of the machine readable hardware specification116. In particular, a driver developer does not need to be involved in the hardware description phase to define the machine readable hardware specification116using the hardware-software interface language. In the second phase, the hardware description is processed by a code generation tool118that includes a hardware-software interface processor120.

The hardware-software interface processor120can generate various software driver modules as illustrated below.

The hardware-software interface processor120can generate hardware access methods for reading/writing registers and interpreting their fields. For example, based on the machine readable hardware specification116, the code generation tool118can determine what registers in the set of registers106are used for communicating with the hardware device102. Methods can be generated to access these registers and can be used to provide software interfaces to application wishing to control the hardware device102to indicate the purpose of each register and the interpretation of data in each register.

The hardware-software interface processor120can generate methods for reading/writing shared structures fields. For example, based on the machine readable hardware specification116, the code generation tool118can identify, in driver software modules, portions of shared memory110that will be used by the hardware device102. This allows software application to use the driver114to be able to communicate with the portions of shared memory110used by the hardware device102.

The hardware-software interface processor120can generate memory allocators for hardware interface entities expressed in the hardware-software interface description. For example, based on the machine readable hardware specification116, the code generation tool118knows what hardware interfaces are included in the hardware device102. The hardware interface layer115may be automatically generated to therefore include memory allocators to allocate memory in system memory112for the use of the hardware interfaces.

The hardware-software interface processor120can generate log modules that interpret and trace hardware interface entities. For example, based on the machine readable hardware specification116and knowledge about hardware interfaces of the hardware device102, the code generation tool118may automatically generate the hardware interface layer115to include modules that are able to use the hardware interfaces to collect and log data logging hardware actions of the hardware device102.

The hardware-software interface processor120can generate debugger extensions that visualize hardware interface entities. For example, based on the machine readable hardware specification116and knowledge about hardware interfaces of the hardware device102, the code generation tool118may automatically generate the hardware interface layer115to include modules that are able to use the hardware interfaces to collect and log data logging hardware actions of the hardware device102which can be used for debugging purposes.

The following illustrates a hardware-software interface sample description of the USB EHCI controller capability registers.

/// <summary>///  These registers specify the limits, restrictions and capabilitiesof the host controller implementation./// </summary>[MemoryMappedRegister(ResourceType.MemoryRange,Size = 0xC)]struct EhciCapabilityRegisters{/// <summary>///  Capability Registers Length and Hci Version registercombined in a single DWORD./// </summary>[DataField(Offset = 0x0)] public CapLengthHCIVersionCapVer;/// <summary>///  This is a set of fields that are structural parameters:Number of downstream ports, etc./// </summary>[DataField(Offset = 0x4)] public HCSPARAMS HCSPARAMS;/// <summary>///  Multiple Mode control (time-base bit functionality),addressing capability./// </summary>[DataField(Offset = 0x8)] public HCCPARAMSHCCPARAMS;}

As noted, the diagram shows a sample description of a USB EHCI controller registers. The register presented is the capability register. Each register is located at some offset relative to the device memory base address. In this example, the capability register is located at offset 0xC as specified by the “MemoryMappedRegister” attribute that is part of the hardware-software syntax. Once the base address of a register is set, hardware-software interface provides several attributes to present the different register fields. In this example, the “DataField” attribute is used to represent registers that are part of the capability register. For example, HCSPARAMS is a register located at offset 0x4 from the base address of the capability register (at 0xC as explained). Each data field is recursively annotated by the hardware-software interface syntax (as illustrated below).

The following illustrates a hardware-software interface description of the HCCPARAMS register field.

This diagram shows how the HCSPARAMS register is annotated (which is part of the capability register presented above). Hardware-software interface “BitField” and “ReservedBits” attributes enable a developer to annotate the register bits. For example, bit0at this register indicates whether the device supports 64 addresses. The developer uses “[(BitField(0)] public bool Bit64Addressing;” to present this requirement. The generated code, will enable the developer to access the “Bit64Addressing” as a Boolean in order to query the value.

The following shows the generated code for getting/setting HCCPARAMS field values.

The generated code uses operating system specific interfaces and can be easily generated for other operating systems.

The following illustrates the way by which the generated code is used by device driver code.

Once the register is initialized with the underlying memory region, a register can be easily read, manipulated and written back to the device.

In the examples illustrated above, the generated code can be used by any operating system and is not limited to a specific vendor. Additionally or alternatively, the generated code can be in any development language, such as C#, Java, C, C++, etc.

As noted, a generic hardware-software interface language is used to describe the hardware registers and host memory data structures (accessible via DMA) in a machine readable hardware specification. A code generator operates on the hardware-software interface description. The hardware-software interface description can be provided, validated and maintained by the hardware vendors. Hardware vendors can generate the machine readable hardware specification directly from a hardware design eliminating potential for any human error. This reduces or eliminates human intervention from software/hardware interface design and implementation paths, reduce development time, and provide uniformity and a better debugging experience.

Some embodiments implement capability based driver models with resource hardening. In particular, most drivers114interface with real hardware. To accomplish this, drivers114map part of the physical memory122that resides on the device102to the virtual address space of the computing system104or use a dedicated address space called the I/O space. The techniques illustrated previously are implemented to help ensure that driver code properly uses the mapped memory (or I/O port) for accessing the device102. In many common operating systems, device drivers114can freely attempt, through error or malice, to map and use any physical address in the system memory112. Because of the privileged nature of the driver software, the operating system typically has no way to ensure that a driver114does not allocate a port, interrupt, or other interface that does not belong to the driver or that is not needed for the driver to function properly to control a particular hardware device102. For example, a keyboard driver should typically have access to IRQ 1, but does not need access to port80. With access to port80, a nefarious keyboard driver could implement key-logging functionality including sending keystrokes across a network to a rogue website. This can jeopardize system safety.

Embodiments herein can implement drivers and system processes in managed code, such as C# or Java. Managed code is computer program source code that will only execute under the management of a sandboxed virtual machine. As such, any drivers or system processes so implemented contain a closed object space. Device memory and registers can only be accessed via a dedicated managed object that is provided to the driver when it is initialized. Thus, the driver will only be able to access system resources and I/O processes that are needed for the driver to function properly to control a device.

Referring now toFIG. 2, some embodiments implement an approach where the set204of all I/O resources (such as memory mapped registers206, I/O ports208, and DMA buffers210) are capabilities. These capabilities are exclusively owned by the kernel212and are assigned to the system's root bus driver214upon startup. The systems root bus driver214can allocate subsets204-1,204-2through204-nof the set204of all I/O resources to other system busses214-1,214-2through214-n. The subsets204-1through204-nare assigned in such a way that busses214-1through214-nare only assigned resources that they need for particular devices that will be attached to them.

When bus drivers214-1through214-nenumerate their devices, they assign a set of I/O resources to each child. For example, bus214-1has devices202-1and202-1attached to it. The bus214-1can assign a set204-1-1of I/O resources to device202-1and a set of resources204-1-2to the device202-2, where sets204-1-1and204-1-2are subsets of set204-1. A bus can only assign I/O resources that were assigned to it. This approach provides a hierarchical I/O resource allocation scheme that can be used to guarantee that a driver can only use or transfer resources that were assigned to it. This can greatly improve system reliability and allow the operating system to easily track and revoke any I/O resource at any time. When a driver is terminated or exits, its resources can be easily reclaimed by its parent bus driver. With an input/output memory management unit (IOMMU) hardware, this scheme can be enforced at the hardware level. For example, a driver developer trying to program a device with illegal memory addresses will not be able to jeopardize the system safety.

FIG. 3illustrates the structure of a typical bus driver302. The bus driver302(the PCI bus driver in this example) is linked with a user level library which provides all driver services (e.g. the DriverFramework library available from Microsoft Corporation of Redmond Washington in this example). The driver is also linked with the plug and play manager library306that enables a bus driver302to enumerate its child devices. For each enumerated device, the framework304creates an abstraction, called a bus slot (such as example, bus slot308-1), which holds the assigned device's resources. Each bus driver exports multiple bus slot interfaces, such as the example bus slot interface310-1(denoted as IBusSlot interface) which are attached to the child drivers (illustrated by the example,114-1) by the runtime. No other service or process can attach itself to the bus slot interface except the enumerated device driver. The bus slot interface is used by the child device driver to allocate its assigned I/O resources to a device, illustrated by the example device102-1. A driver can only allocate I/O resources that are specified on the bus slot at the parent driver.

This mechanism can be easy to implement and distributed in the sense that I/O resource management is executed locally at each bus driver instead of in the kernel or a single system service.

Besides I/O resources that are treated as capabilities, embodiments may implement an operating system that is able to control the connectivity of various services. As drivers are treated as services embodiments can control the set of services a driver can use/interact with. For example, unlike other operating systems, in some embodiments, a driver cannot send a message to another driver as it does not have a capability to do so (which is an interface to send a message to that service). The operating system, of some embodiments, is able to constrain, control, observe, and reason about the connection of a driver to other components in the system. The combination of a capability-based model and use of managed code provides various advantages as illustrated herein.

With reference toFIG. 4, a unique architecture is illustrated. In the example illustrated, a user mode402(e.g. Ring3, the least privileged, of the privilege rings of the x86 architecture) and kernel mode404are illustrated. A microkernel406may be implemented in the kernel mode404(sometime referred to as a supervisor mode). The microkernel406is a minimal amount of software that provides mechanisms, such as low-level address space management, thread management, and IPC communication. The microkernel406is responsible for reading basic hardware tables.

In user mode,402, address spaces are divided up into domains, such as the example, domain408-1(but referred to herein generically as408). The domains run various processes (such as the example process410-1-1but referred to generically as410), including one or more driver processes, on a runtime (such as the example runtime412-1-1). Embodiments may be implemented where drivers are user-mode402managed processes410(such as by coding the drivers in managed code, such as C# or Java) that can support high throughput and low latency devices. In some embodiments, all services including device drivers are developed using managed code libraries and are executed in user-mode402. In addition, isolation among processes410and the microkernel406can be further achieved via the statically verified type safety of the language. This mechanism enables the exchange of data over inter-process communication (IPC) channels without copying as all processes reside in a single address space or domain408. Such an approach is hard to make safe in traditional systems that are not based on type safe languages

User mode drivers implemented using managed code can greatly increase system safety and simplify driver development. In particular, the developer can utilize any user-mode library that is available in the system (including XML parsers, queue management, etc.). In traditional operating systems, driver developers could not use any existing library due to memory constraints and other limitations as drivers must share their address space with the kernel. Additionally, developers no longer need to worry about memory management. The same garbage collector that manages process memory is used for drivers. Improper memory management is one of the greatest sources of operating system failures. In some embodiment systems driver memory related bugs can be eliminated.

In some example embodiments, drivers implemented as one or more processes410, are single threaded. Thus the developer does not need to worry about synchronization, threads, and interrupt levels. Much of the driver complexity is gone and the developer is focused on the driver's functionality.

Drivers can be accessed via standard type-safe interfaces. Common operating systems restrict access to drivers to a few pre-defined functions, such as Open, Close, Read, Write and a general-purpose interface such as DeviceIoControl (known as ‘ioctl’). While in previous systems, drivers controlled a few well-known hardware components and the tasks they performed were limited, this is inefficient for modem systems where at least some hardware devices (e.g. hardware accelerators such as graphics accelerators) expose an expansive and complex interface to their host. The solution provided in some embodiment operating systems treats drivers as first class-citizens.

A driver implemented as a process410is accessed via type safe interfaces like any other system service. Such an implementation takes advantage of a language's type-safety features and catches erroneous method invocations at compile time. To provide compile-time type checking, the compiler needs to know the data type information for the variables or expressions in the code. Interfaces provide a contract between the interface consumer and the interface implementation. The method signature can be statically checked during compilation. Mismatches of differently-typed parameters simply cannot occur in a running system. Additionally, those errors are caught by the application developer at compile time, and do not require runtime checks by the driver developer in kernel mode404.

Besides, safety and ease of development, embodiments enable device drivers to achieve high-throughput and low latency comparable to common kernel mode device drivers. This can be achieved through the ability to implement zero-copy I/O paths. “Zero-copy” refers to the fact data entering the system is written to memory only once and then can be used directly by many layers of abstractions, both within the operating system and within application code, without the need to copy the data. Zero-copy I/O paths are ones in which the CPU does not perform copying from one memory location to another. Rather, the CPU can perform other tasks. This can save from having context switches to have the system switch between user mode402and kernel mode404to achieve the copying. The following now illustrates techniques that allow a managed, user-mode device driver to achieve such performance using zero-copy I/O paths.

Embodiments may be configured to perform efficient interrupt dispatching. The ability to efficiently deliver hardware interrupts to a user mode driver is novel. Interrupt dispatching is executed by a tight interaction between the operating system micro-kernel, the domain kernel and the drivers' framework library.

The mechanism to dispatch an interrupt uses a 3-tier architecture including an I/O interrupt manager, a driver framework library, and efficient microkernel interrupt handling.

As illustrated inFIG. 4, each domain408includes a domain kernel, an example of which is illustrated at414-1(but referred to herein generically as414). An I/O interrupt manager, an example of which is illustrated at416-1(but referred to herein generically as416) is part of the domain kernel414and bridges between the hardware device102and device driver processes410. It is responsible for managing registrations of device drivers on the IRQs418, dispatching interrupts to the driver processes410, and handle interrupt sharing when an IRQ is shared by multiple devices. As all device drivers run in processes, embodiments can enforce stronger isolation and fault containment for drivers than traditional monolithic OS kernel design where device drivers run in the kernel.

The driver framework library is responsible for registering an interrupt handler at the domain kernel414to receive notifications. When a hardware interrupt is received at the domain kernel414, the interrupt handler is triggered and a pre-registered driver routine is invoked. The overhead of invoking the method is very low as there is no context switch from user mode402to kernel mode404involved.

Embodiments implement efficient microkernel interrupt handling. In some embodiments, the microkernel406is interruptible but not preemptable. A logical processor, while running in the context of microkernel406, can receive interrupts but cannot block or switch its context. To minimize the interrupt dispatch latency, embodiments limit the amount of time a processor can spend inside of the microkernel406. Some embodiments implement a continuation execution scheme for system calls that potentially could take longer time than preset bounds. The bounds and continuations scheme enable the microkernel406to deliver interrupts to the domain kernel414with very low latency. All hardware interrupts (MSIs, IRQs and Virtual) are delivered to a user mode library which is part of the driver. Minimizing interrupt dispatch latency can be achieved in some embodiments by using zero-copy I/O paths.

One illustrative example of zero-copy I/O paths is now illustrated. With reference again toFIG. 1, system memory112is illustrated. A process410can allocate a portion of the system memory112. The microkernel406(seeFIG. 4) can allow the process410to allocate the memory, but once the memory is allocated to the process410, then the process410has control over the portion of system memory. In a hardware driver example, a hardware device102can write to the portion of memory. The driver process410will then mark this portion of memory as immutable. Memory that is immutable is memory whose content and/or address cannot be changed. Because the portion of memory is immutable, there are no real constraints on accessing the portion of memory. Thus, the system does not need to switch to kernel mode to allow different processes to read from the memory. Thus, a driver process410can access the portion of memory without requiring a context switch and thus can obtain data from the hardware device102that writes to the portion of memory quickly and efficiently such that high efficiency and low latency can still be achieved when a driver is implemented in user mode.

The data can be delivered to the different processes410in appropriate ways by providing different views of the immutable portion of the memory. Thus, rather than copying the portions of the data that are needed for a particular process410, pointers to the immutable portion of the memory can be used, and logical views of the data in the immutable portion of the memory can provide the appropriate data. Thus, from the perspective of a particular process410, the data appears to have been copied and provided in the appropriate format while in fact, no data copying has occurred.

Similar functionality can be used for a driver process410to send data to a hardware device102. In particular, a driver process410can write data to a portion of the system memory112. The portion can be marked by the same driver process410or another driver process as immutable. The memory can then be read by the hardware device102without needing the system to switch to kernel mode404.

In some embodiments, the immutable portion of memory can have a counter associated with it. Each time a process accesses the immutable portion of memory, the counter is incremented. When the process is done reading the immutable portion of memory, the counter decrements. Thus, after all processes that have been reading the immutable portion of memory finish with the immutable portion of memory, the counter is decremented to zero which allows the portion of memory to be freed up for other memory operations.

Another technique is related to the use of DMA channels for device control. A channel is a bi-directional message conduit having exactly two endpoints, called the channel endpoints. A DMA channel is a high performance mechanism to bridge the gap between applications and device drivers which exchange high volumes of packetized data via DMA. It is a specialization of a standard inter-process communication (IPC) channel, differing primarily by offering readable DMA operations and asynchronous retirement of messages in the channel. An IPC message has two parts, one mandatory and the other optional. The mandatory part is inline data copied into the channel's slot and the optional part includes handles that are transferred across (or shared over) the channel. DMA channels are unique in the following aspects:They are entirely executed in user-mode (where drivers and processes live).They provide back pressure. There is no memory allocation for each message passed between an application and network driver. Furthermore, data can stay in the channel until it's fully consumed, and messages behind this data can continue to be processed.They include zero-copy support. DMA can be executed from the ring buffer.They include support for arbitrary control messages. This enables optimizations like software segmentation offload.

Referring now toFIG. 5, a method500is illustrated. The method500may be practiced in a computing environment. The method500includes acts for automatically generating code used with device drivers for interfacing with hardware. The method500includes receiving a machine readable description of a hardware device (act502). The machine readable description includes at least one of hardware registers or shared memory structures of the hardware device. For example,FIG. 1illustrates an example of a machine readable description116of a hardware device102.

The method500further includes determining an operating system with which the hardware device is to be used (act504). For example, the code generation tool118may have access to, or may have information that sets the operating system for which a hardware interface layer115is being created.

The method500further includes processing the machine readable description on a code generation tool to automatically generate code for a hardware driver for the hardware device specific to the determined operating system (act506). For example,FIG. 1illustrates that the code generation tool118executes the machine readable hardware specification116

Various driver code portions may be generated. For example, some embodiments of the method500may be practiced where generating code for a hardware driver comprises generating hardware access methods for reading and writing to registers and interpreting fields of the registers. Alternatively or additionally, embodiments of the method500may be practiced where generating code for a hardware driver comprises generating methods for reading and writing to shared structures fields. Alternatively or additionally, embodiments of the method500may be practiced where generating code for a hardware driver comprises generating memory allocators for hardware interface entities expressed in the machine readable description of the hardware device. Alternatively or additionally, embodiments of the method500may be practiced where generating code for a hardware driver comprises generating log modules that interpret and trace hardware interface entities. Alternatively or additionally, embodiments of the method500may be practiced where debugger extensions that visualize hardware interface entities.

Some embodiments of the method500may be practiced where the machine readable description of a hardware device is provided by a hardware vendor.

Some embodiments of the method500may be practiced where the generated code for the hardware driver is generated as managed code.

Referring now toFIG. 6, a method600is illustrated. The method600may be practiced in a computing environment. The method600includes acts for enforcing limitations on hardware drivers. The method600includes from a system kernel, assigning I/O resources to the system's root bus (act602). For example,FIG. 2illustrates that I/O resources are assigned to a system's root bus by assigning the resources to a bus driver214.

From the root bus, the method600includes assigning a subset of the I/O resources to a device bus (act604). Assigning a subset of the I/O resources to a device bus includes limiting the device bus to only be able to assign I/O resources that are assigned to it by the root bus. For example, inFIG. 2, devices busses214-1through214-nhave resources assigned to them. Each of these device busses is only able to further assign resources which have been assigned to them.

The method600further includes, from the device bus, assigning I/O resources to a device through a device interface (act606).

Some embodiments of the method600may be implemented where limiting the device bus to only be able to assign I/O resources that are assigned to it by the root bus is accomplished by implementing bus drivers in managed code.

The method600may be practiced where assigning a subset of the I/O resources to a device bus comprises invoking a bus driver implemented in managed code.

The method600may be practiced where assigning I/O resources to a device comprises invoking a device driver implemented in managed code.

The method600may further include preventing other services and processes from attaching themselves to the device interface.

Referring now toFIG. 7, a method700is illustrated. The method700may be practiced in a computing environment. The method700includes acts for implementing a type safe driver that can support high throughput and low latency devices. The method700includes receiving data from a hardware device (act702). The method700further includes delivering the data to one or more driver processes executing in user mode using a zero-copy to allow the one or more driver processes to support high throughput and low latency hardware devices (act704).

The method700may be practiced where delivering the data is performed without pre-empting the kernel mode. Alternatively or additionally, the method700may further include limiting the amount of time a processor spends in kernel mode. Alternatively or additionally, the method700may be practiced where the driver process is implemented in managed code. Alternatively or additionally, the method700may further include an I/O interrupt manager implemented in user mode registering user mode device drivers on interrupts. In some embodiment, the I/O interrupt manager dispatches interrupts to driver processes. Alternatively or additionally, the method700may further include implementing drivers as single threaded processes. Alternatively or additionally, the method700may be practiced where the one or more driver processes are implemented without limitation on what user mode libraries can be used to implement the one or more driver processes.

Further, upon reaching various computer system components, program code means in the form of computer-executable instructions or data structures can be transferred automatically from transmission computer readable media to physical computer readable storage media (or vice versa). For example, computer-executable instructions or data structures received over a network or data link can be buffered in RAM within a network interface module (e.g., a “NIC”), and then eventually transferred to computer system RAM and/or to less volatile computer readable physical storage media at a computer system. Thus, computer readable physical storage media can be included in computer system components that also (or even primarily) utilize transmission media.