Выбрать главу

User Interaction

Boot loaders can support user interaction based on a menu that provides the user with different options to start the platform, which can be helpful during the development process and later on for maintenance and software updates. Figure 5-4 shows a standard boot loader menu. For sample source code, check out the Menu.c file located in the Src\Bootloader\Eboot directory of a reference BSP or in the %_WINCEROOT%\Platform\Common\Src\Common\Boot\Blmenu folder.

Figure 5-4 An example of a boot loader menu

Additional Features

Beyond the core functionality, you can also add convenience features, such as download progress indication, support for downloading multiple .bin files during the same download session (multi-bin image notification), or downloading only trusted images. Additionally, you can implement support for downloading run-time images directly from Platform Builder. To accomplish this task, the boot loader must prepare a BOOTME packet with details about the target device and send it over the underlying transport. If the transport is Ethernet then this packet is broadcasted over the network. The libraries provided by Microsoft support these features, and you can customize them to suit your needs.

NOTE
OEM boot loader functions

For detailed information about required and optional boot loader functions as well as boot loader structures, see the section "Boot Loader Reference" in the Windows Embedded CE 6.0 Documentation, available on the Microsoft MSDN® Web site at http://msdn2.microsoft.com/en-us/library/aa908395.aspx.

Adapting an OAL

A significant portion of the BSP adaptation revolves around the platform-specific part of the OAL. If the new platform uses a CPU that is not currently supported, then the OAL adaptation requires you to modify most of the OAL code to support the new processor architecture. On the other hand, if the new hardware is very similar to the reference BSP's platform, you might be able to reuse most of the existing code base.

OEM Address Table

The kernel performs specialized tasks, such as initializing virtual memory, and cannot rely on a boot loader for this because the kernel must be entirely self-contained. Otherwise, the operating system would depend on the presence of a boot loader and it would not be possible to bootstrap the run-time image directly. Yet, to establish virtual-to-physical address mappings through the Memory Management Unit (MMU), the kernel must know the memory layout of the underlying hardware platform. To obtain this information, the kernel uses an important table called OEMAddressTable (or g_oalAddressTable) that defines static virtual memory regions. The OAL includes a declaration of OEMAddressTable as a read-only section and one of the first actions taken by the kernel is to read this section, set up corresponding virtual memory mapping tables, and then transition to the virtual address where the kernel can execute code. The kernel can determine the physical address of the OEMAddressTable in linear memory based on the address information available in the run-time image.

You must indicate any differences in the memory configuration of a new hardware platform by modifying the OEMAddressTable. The following sample code illustrates how to declare the OEMAddressTable section.

;--------------------------------------------------------------

public _OEMAddressTable

 _OEMAddressTable:

 ; OEMAddressTable defines the mapping between Physical and Virtual Address

 ; o MUST be in a READONLY Section

 ; o First Entry MUST be RAM, mapping from 0x80000000 -> 0x00000000

 ; o each entry is of the format ( VA, PA, cbSize )

 ; o cbSize must be multiple of 4M

 ; o last entry must be (0, 0, 0)

 ; o must have at least one non-zero entry

 ; RAM 0x80000000 -> 0x00000000, size 64M

 dd 80000000h, 0, 04000000h

 ; FLASH and other memory, if any

 ; dd FlashVA, FlashPA, FlashSize

 ; Last entry, all zeros

 dd 0 0 0

StartUp Entry Point

Similar to the boot loader, the OAL contains a StartUp entry point to which the boot loader or system can jump in order to start kernel execution and initialize the system. For example, the assembly code for putting the processor in the correct state is usually the same as the code used in the boot loader. In fact, code sharing between the boot loader and the OAL is a common practice to minimize code duplication in the BSP. Yet not all code runs twice. For example, on hardware platforms that start from a boot loader, StartUp directly jumps to the KernelStart function, as the boot loader has already performed the intialization groundwork.

The KernelStart function initializes the memory-mapping tables as discussed in the previous section and loads the kernel library to run Microsoft kernel code. The Microsoft kernel code now calls the OEMInitGlobals function to pass a pointer to a static NKGLOBALS structure to the OAL and retrieve a pointer to an OEMGLOBALS structure in the form of a return value from the OAL. NKGLOBALS contains pointers to all the functions and variables used by KITL and the Microsoft kernel code. OEMGLOBALS has pointers to all the functions and variables implemented in the OAL for the BSP. By exchanging pointers to these global structures, Oal.exe and Kernel.dll have access to each other's functions and data, and can continue with architecture-generic and platform-specific startup tasks.

The architecture-generic tasks include setting up page tables and cache information, flushing TLBs, initializing architecture-specific buses and components, setting up the interlocked API code, loading KITL to support kernel communication for debugging purposes, and initializing the kernel debug output. The kernel then proceeds by calling the OEMInit function through the function pointer in the OEMGLOBALS structure to perform platform-specific initialization.

Table 5-5 lists the platform-specific funtions that Kernel.dll calls and that you might have to modify in your BSP to run Windows Embedded CE on a new hardware platform.

Table 5-5 Kernel startup support functions

Function Description
OEMInitGlobals Exchanges global pointers between Oal.exe and Kernel.dll.
OEMInit Initializes the hardware interfaces for the platform.
OEMGetExtensionDRAM Provides information about additional RAM, if available.
OEMGetRealTime Retrieves time from RTC.
OEMSetAlarmTime Sets the RTC alarm.
OEMSetRealTime Set the time in the RTC.
OEMIdle Puts CPU in idle state when no threads are running.
OEMInterruptDisable Disables particular hardware interrupt.
OEMInterruptEnable Enables particular hardware interrupt.
OEMInterruptDone Signals completion of interrupt processing.
OEMInterruptHandler Handles interrupts (is different for SHx processors).
OEMInterruptHandler Handles FIQ (specific for ARM processors).
OEMIoControl IO control code for OEM information.
OEMNMI Supports a non maskable interrupt (specific to SHx processor).
OEMNMIHandler Handler for non maskable interrupt (specific to SHx processor).
OEMPowerOff Puts CPU in suspend state and takes care of final power down operations.