Boot Driver Code (Compact 2013)
3/26/2014
In CE Boot, boot drivers use an interface similar to that of a Windows Embedded Compact 2013 stream driver. They are similar in that after a boot driver is created, it is accessible to the boot loader only by using a set of IOCTLs for the particular capabilities of the driver’s device. After the boot loader is finished with the boot driver, it closes the driver by using a deinitialization function. The common IOCTL and deinitialization functions call hardware-specific boot driver code (see Boot Driver Examples for more information).
A boot driver must be implemented as a singleton. It can be created multiple times, but each call returns a handle to the same instance of the driver. Therefore, we recommend that boot drivers support reference counting to control their use.
The illustration below shows an example of the life cycle of a boot driver. In this example, the user chooses to change the resolution of the display. To do so, the boot loader uses a display driver to query the capabilities of the display device, presents the options to the user, and saves the user’s choice to the boot loader context. When it is finished, it deinitializes the display driver.
Example of a Boot Device Driver Life Cycle
In the illustration, the user selects Change Display Resolution from the boot configuration menu. This selection triggers a call to the DisplayResolution function, which sets into motion the following sequence of function calls:
- Initializing the driver. The boot display driver is created and initialized during the steps below.
- DisplayResolution calls OEMBootCreateDriver, which is the boot driver factory. The input parameters are a handle to the boot loader context, the class ID (BOOT_DRIVER_CLASS_DISPLAY), and an index of 0 (zero) because it is the first driver of this class to be created.
- Because the class ID is BOOT_DRIVER_CLASS_DISPLAY, OEMBootCreateDriver calls the CreateDisplay function with a handle to the boot loader context and the index (0).
- CreateDisplay calls the BootDisplayBiosInit function with no parameters. BootDisplayBiosInit initializes the boot display driver and returns a handle to it. This handle to the display driver is then returned by both CreateDisplay and OEMBootCreateDriver back to DisplayResolution.
- Using the driver. Because the user chose to change the display resolution, the following events occur.
- DisplayResolution makes repeated calls to the BootDisplayModeQuery function to query the settings that the display device supports. To do this, BootDisplayModeQuery creates a structure to hold display mode settings (such as height and width), and passes the address of that structure in addition to a handle to the display driver and the IOCTL code (BOOT_DISPLAY_IOCTL_MODE_QUERY) to the BootDriverIoCtl function.
- BootDriverIoCtl looks up the address of the display driver’s IOCTL function in the BootDriverVTable_t element of the display driver’s handle. This IOCTL function, which is BootDisplayBiosIoCtl for the display driver, is then called by BootDriverIoCtl, passing a handle to the display driver, the IOCTL, a pointer to the display mode setting structure, and the size of the display mode structure as parameters.
- BootDisplayBiosIoCtl calls the DisplayModeQuery function, with a handle to the display driver and pointers to a number of display settings, which it uses to pass supported display modes to the user in DisplayResolution.
- After the user chooses the resolution settings, DisplayResolution saves the settings to the boot loader’s BootLoader_t structure, which contains information about different aspects of the boot loader.
- Deinitializing the driver. Because DisplayResolution is finished using the handle to the display driver, it releases the driver by performing the following actions.
- DisplayResolution calls the BootDisplayDeinit function with a handle to the display driver. BootDisplayDeinit is defined in the boot display code to be the BootDriverDeinit function.
- BootDriverDeinit looks up the address of the display driver’s deinitialization function in the BootDriverVTable_t element of the display driver’s handle. The address that it finds is the address to the BootDisplayBiosDeinit function, which releases any memory that it allocated and deletes the display driver by clearing its handle from memory.
The common boot driver code is implemented using inline functions in:
%_WINCEROOT%\Platform\Common\Src\Common\Bldr\Inc\Bootdriver.h
The boot driver base class is BootDriver_t; the boot driver functions are BootDriverDeinit and BootDriverIoCtl.