DWORD dwEdbgDebugZone; // Which debug messages are enabled?<\/code> <\/p>
// The following addresses are only valid if LDRFL_JUMPIMG is set and<\/code> <\/p>
// the corresponding bit in ucEshellFlags is set (configured by Eshell, bit<\/code> <\/p>
// definitions in Ethdbg.h).<\/code> <\/p>
EDBG_ADDR EshellHostAddr; // IP/Ethernet addr and UDP port of host<\/code> <\/p>
// running Eshell.<\/code> <\/p>
EDBG_ADDR DbgHostAddr; // IP/Ethernet address and UDP port of host<\/code> <\/p>
// receiving debug messages.<\/code> <\/p>
EDBG_ADDR CeshHostAddr; // IP/Ethernet addr and UDP port of host<\/code> <\/p>
// running Ethernet text shell.<\/code> <\/p>
EDBG_ADDR KdbgHostAddr; // IP/Ethernet addr and UDP port of host<\/code> <\/p>
// running kernel debugger.<\/code> <\/p>
ETH_HARDWARE_SETTINGS Edbg; // The debug Ethernet controller.<\/code> <\/p>
} BOOT_ARGS, *PBOOT_ARGS;<\/code> <\/p>
// Definitions for flags set by the boot loader.<\/code> <\/p>
#define LDRFL_USE_EDBG 0x0001 // Set to attempt to use debug Ethernet.<\/code> <\/p>
// The following two flags are only looked at if LDRFL_USE_EDBG is set.<\/code> <\/p>
#define LDRFL_ADDR_VALID 0x0002 // Set if EdbgAddr member is valid.<\/code> <\/p>
#define LDRFL_JUMPIMG 0x0004 // If set, do not communicate with Eshell<\/code> <\/p>
// to get configuration information,<\/code> <\/p>
// use ucEshellFlags member instead.<\/code> <\/p>
typedef struct _DRIVER_GLOBALS {<\/code> <\/p>
//<\/code> <\/p>
// TODO: Later, fill in this area with shared information between<\/code> <\/p>
// drivers and the OS.<\/code> <\/p>
//<\/code> <\/p>
BOOT_ARGS bootargs;<\/code> <\/p>
} DRIVER_GLOBALS, *PDRIVER_GLOBALS;<\/code> <\/p>
StartUp Entry Point and Main Function<\/p> <\/div>
The StartUp entry point of the boot loader must be located in linear memory at the address where the CPU begins fetching code for execution because this routine carries out the initialization of the hardware. If the adaptation is based on a reference BSP for the same processor chipset, then most of the CPU-related and memory controller-related code can remain unchanged. On the other hand, if the CPU architecture is different, you must adapt the startup routine to perform the following tasks:<\/p>
1. Put the CPU in the right mode.<\/p>
2. Disable all interrupts.<\/p>
3. Initialize the memory controller.<\/p>
4. Setup caches, Translation Lookaside Buffers (TLBs), and Memory Management Unit (MMU).<\/p>
5. Copy the boot loader from flash memory into RAM for faster execution.<\/p>
6. Jump to the C code in the main function.<\/p>
The StartUp routine eventually calls the main function of the boot loader, and if the boot loader is based on BLCOMMON, then this function in turn calls BootLoaderMain, which initializes the download transport by calling OEM platform functions. The advantage of using the standard libraries provided by Microsoft is that the modifications required to adapt a BSP to a new hardware platform are componentized, isolated, and minimized.<\/p>
Serial Debug Output<\/p> <\/div>
The next step in the boot loader adaptation is the initialization of the serial debug output. This is an important part of the boot process because it enables the user to interact with the boot loader and the developer to analyze debug messages, as discussed in Chapter 4, "Debugging and Testing the System."<\/p>
Table 5-2 lists the OEM platform functions required to support serial debug output in the boot loader.<\/p>
Table 5-2 Serial debug output functions<\/strong> <\/p>
Function<\/th> |
Description<\/th> <\/tr> |
OEMDebugInit<\/td> |
Initializes the UART on the platform.<\/td> <\/tr> |
OEMWriteDebugString<\/td> |
Writes a string to the debug UART.<\/td> <\/tr> |
OEMWriteDebugByte<\/td> |
Writes a byte to the debug UART, used by OEMWriteDebugString.<\/td> <\/tr> |
OEMReadDebugByte<\/td> |
Reads a byte from the debug UART.<\/td> <\/tr> <\/table>
Platform Initialization<\/p> <\/div>
Once the CPU and the debug serial output are initialized, you can turn your attention to the remaining hardware initialization tasks. The OEMPlatformInit routine performs these remaining tasks, including:<\/p>
■ Initializing the real-time clock.<\/p>
■ Setting up external memory, particularly flash memory.<\/p>
■ Initializing the network controller.<\/p>
Downloading via Ethernet<\/strong> <\/p> <\/div>
If the hardware platform includes a network controller, then the boot loader can download the run-time image over Ethernet. Table 5-3 lists the functions that you must implement to support Ethernet-based communication.<\/p>
Table 5-3 Ethernet support functions<\/strong> <\/p>
Function<\/th> |
Description<\/th> <\/tr> |
OEMReadData<\/td> |
Reads data from the transport for downloading.<\/td> <\/tr> |
OEMEthGetFrame<\/td> |
Reads data from the NIC using function pointer pfnEDbgGetFrame.<\/td> <\/tr> |
OEMEthSendFrame<\/td> |
Writes data to the NIC using function pointer pfnEDbfSendFrame.<\/td> <\/tr> |
OEMEthGetSecs<\/td> |
Returns number of seconds passed relative to a fixed time.<\/td> <\/tr> <\/table>
The Ethernet support functions use callbacks into network controller-specific routines. This means that you must implement additional routines and set up appropriate function pointers in the OEMPlatformInit function if you want to support a different network controller, as demonstrated in the following sample code:<\/p>
cAdaptType=pBootArgs->ucEdbgAdapterType;<\/code> <\/p>
// Set up EDBG driver callbacks based on<\/code> <\/p>
// Ethernet controller type.<\/code> <\/p>
switch (cAdaptType) {<\/code> <\/p>
|
|
Читать дальше