How to Develop a Boot Loader
A boot loader manages the boot process of the target device by initializing the target device, downloading the operating system (OS) image, and booting the OS image on the target device. Once you have developed a boot loader, you can use the boot management capabilities of your boot loader to save time during the OS development process. Without a boot loader, you must transfer an OS image to your target device through a slow, manual process. With a boot loader, you can quickly download a new development OS image to your target device. For more information about boot loaders, see Boot Loaders.
Hardware and Software Assumptions
- The boot loader described in this topic is developed for an example platform containing the following hardware specifications:
- ARM V4I CPU
- 64 MB RAM
- 32 MB Intel Strataflash (28F128)
- A supported Ethernet controller, such as NE2000 or SMC9000. As a simplification for this boot loader development process, the controller is built-in and not a PCI or PCMCIA device.
The following table shows the memory map for this platform.
Physical address Length Description 0000.0000 - 01FF.FFFF 32 MB Flash A000.0000 - A3FF.FFFF 64 MB RAM
The boot loader design assumes that the CPU begins fetching code at physical address 0 following a reset.
- You are developing a new boot loader, using as much from the included support libraries as possible.
Note If you already have an existing boot loader and want to migrate from a previous version of Microsoft Windows CE to Windows CE .NET 4.2, see Migration Issues and How to Migrate a Board Support Package to Windows CE .NET 4.2.
- Your reference OS is Windows CE .NET 4.2.
- You have access and familiarity with Microsoft Platform Builder 4.2 and the build process. Platform Builder includes with all the sources and libraries needed to support boot loader development.
- You have available documentation, such as databooks or datasheets and the latest errata, on the hardware platform, CPU, peripheral chips, and other hardware on which your boot loader will run.
- This procedure used a sample boot loader with the following design simplifications:
- The boot loader resides in system flash memory and runs at every hardware reboot.
- Use Ethernet for the download transport. This is built in with no PCMCIA or PCI interface.
- Download a Windows CE .bin file, for example, Nk.bin, to RAM.
- There is no support for booting a local OS image, although the flash memory routines are covered. Memory management unit (MMU) or caches are not used. The ROMOFFSET configuration option in the OS image Config.bib file should reflect the fact that all addresses are physical.
When designing your own boot loader, you can implement enhancements within the framework presented in this topic. For example, you may support a removable Ethernet adapter using PCMCIA or Compact Flash memory or use USB as your download transport. You may want to store the OS image in NAND flash memory. For more information about memory design tradeoffs, see the article System Memory Management in Windows CE .NET at this Microsoft Web site.
For more information about the hardware platform description and design of the boot loader described in this process, see Boot Loader Design.
Although the boot loader and the OEM adaptation layer (OAL) typically share hardware platform initialization code, the steps in the following procedure focus on the boot loader. You should keep code sharing in mind, though, when organizing the source files.
The steps in the following procedure walk you through the boot loader development process from the beginning. However, you can save development time by modifying an existing boot loader OS image for a platform of similar design. Platform Builder includes tested boot loader source code for a variety of hardware platforms, which you can use as the basis for further development.
To track your progress in the following table, select the check box next to each step.
Note In the following steps, code examples are used to demonstrate each step. In some cases, these examples are code fragments and may be brought together from different parts of the boot loader development process. Because of this, not all the code examples compile.
|1. Create a directory for your new boot loader code.
For example: %_WINCEROOT%\Platform\MyPlatform\Eboot.
The boot loader code directory is typically under a platform directory. You need to include the directory in the platform dirs file if you want to build it as part of Platform Builder.
|2. Set up a command-line build shell to create and build the boot loader.
Note All further steps rely on the assumption that the boot loader development process takes place in a build shell environment.
|Setting Up a Command-Line Build Shell|
|3. Generate all static libraries required by the boot loader image.
For more information about Sysgen.bat, see Sysgen Tool.
|4. Create a file for your boot loader's StartUp function, and then establish a function framework as a starting point.||Creating a File for the Boot Loader StartUp Function|
|5. Create a sources file and makefile file in the boot loader directory.||Creating the Boot Loader Sources and Makefile Files|
|6. Build your first boot loader executable (.exe) file.||Building the Boot Loader Source Code|
|7. Implement the boot loader's StartUp function.||Implementing the Boot Loader StartUp Function|
|8. Create a boot loader main function.
This is typically using C programming language.
Starting with this step, all boot loader code should be able to operate in C instead of assembly language.
Note If you build during this step, you receive a number of undefined values, because BLCOMMON expects to call a number of functions that have not yet been implemented. Therefore, you need to at least implement stub versions of these functions.
|Creating the Boot Loader Main Function|
|9. Create stub versions for a number of OEM functions, including generic platform routines and flash memory operations.||Creating Stubs for the Boot Loader OEM Functions|
|10. Add the new source files, Main.c. and Flash.c, created in the previous step to the SOURCES line in the sources file.
||Editing the Boot Loader Sources File|
|11. Create the .bib file, which will be used by Romimage.exe to convert the boot loader .exe file into .bin and .nb0 files.||Creating the Boot Loader .bib File|
|12. Rebuild the boot loader.
Note After this point, the basic boot loader source infrastructure is in place.
To complete the remaining steps of this procedure, you must fully implement the routines that were stubbed, add incremental features to the boot loader, rebuild the boot loader, and then test the functionality of the loader up to that point.
|Rebuilding the Boot Loader|
|13. Implement the following serial debug functions in your boot loader code:
These functions are required BLCOMMON callback functions and you must implement them in your boot loader code. You can use other libraries to help implement the functions. You can copy and possibly modify much of the code from existing platforms. You should choose a platform that is as similar to your own as possible to minimize the need for changes.
|Implementing the Serial Debug Functions|
|14. Rebuild the boot loader and verify that your code works by testing it on the target device.
You should now be able to verify that the startup code initializes the CPU and that the debug routines initialize and write debug text to the serial universal asynchronous receiver-transmitter (UART).
If you encounter any problems, verify again that you correctly implemented the serial debug functions.
|Rebuilding the Boot Loader|
|15. Create the driver globals and boot args shared data areas.||Creating Driver Globals and Boot Args|
|16. Implement the remaining platform initialization code by implementing the OEMPlatformInit function.||Implementing the OEMPlatformInit Function|
|17. Add any Ethernet debug libraries that have routines referenced in OEMPlatformInit to the TARGETLIBS entry in the boot loader sources file.
Note After this point in the development process, the CPU, board-level logic, and network controller are all initialized.
To complete the remaining steps in this procedure, you must obtain an IP address, either statically or through Dynamic Host Configuration Protocol (DHCP) from a server, connect to Platform Builder and establish a Trivial File Transfer Protocol (TFTP) connection, add code to act as a bridge between BLCOMMON callbacks and the Ethernet controller access primitives, and then handle flash memory images, which are images built to reside in flash memory after being downloaded from the development workstation.
|Editing the Boot Loader Sources File|
|18. Implement the following Ethernet controller-related functions:
||Implementing the Ethernet Controller-Related Functions|
|19. Implement the OEMPreDownload function.||Implementing the OEMPreDownload Function|
|20. Test boot loader communications.
Verify that the code can obtain an IP address from the DHCP server and can retrieve the user settings from Platform Builder. Also verify that your device name appears in Platform Builder.
|21. Create a test .bin file to download from Platform Builder.||Creating a Test .bin File for Download|
|22. Verify that the boot loader can use Platform Builder to download a .bin file.||Verifying .bin File Download|
|23. Implement the OEMLaunch function.
Note After you complete this step, you have essentially completed development of the boot loader. The boot loader should now be able to initialize the hardware platform, obtain an IP address from a DHCP server, establish contact with Platform Builder, download a .bin file, obtain user preferences from Platform Builder, and then execute the downloaded OS image.
To complete the remaining steps in this procedure, you must add support for writing the downloaded image to flash memory. By doing so, the boot loader will be able to update its own saved image. You can also save user settings, such as a static IP address and subnet mask, in flash memory and then restore these settings after a reset. You can also add optional features such as memory range verification, image signature checking, and NAND flash memory support.
For more information about design tradeoffs, particularly NOR versus NAND flash memory, see this Microsoft Web site.
|Implementing the OEMLaunch Function|
|24. Implement the OEMIsFlashAddr function.||Implementing the OEMIsFlashAddr Function|
|25. Implement the OEMMapMemAddr function.||Implementing the OEMMapMemAddr Function|
|26. Implement the following flash memory erase functions:||Implementing the Flash Memory Erase Functions|
|27. Implement the OEMWriteFlash function.||Implementing the OEMWriteFlash Function|
|28. Modify the .bib file to produce a boot loader image that will download to flash memory.
Note After you complete this step, you have completed development of a basic Ethernet boot loader that can download an image to RAM or to flash memory. You can now add additional features to enhance the basic boot loader.
The following list shows some of the additional features that you can include in an enhanced boot loader:
|Modifying the .bib File to Produce a Downloadable Image|
|29. If you want to add support for download progress indication, implement the OEMShowProgress function.
You do not need to add functionality to the OEMShowProgress function, but you must leave the stub version in your boot loader code in order to prevent errors when the compiler compiles the code.
|Adding Support for Download Progress Indication|
|30. If you want to verify the RAM or flash memory used by the OS image before the OS image is downloaded completely, add support for memory verification.||Adding Support for Memory Verification|
|31. If you are developing a multiple-BIN OS image and you would find multiple-BIN OS image notification useful, add support for multiple-BIN OS image notification.||Adding Support for Multiple-BIN Image Notification|
|32. If you want your boot loader to validate the OS image before downloading or running it, add support for OS image signatures.||Adding Support for Image Signatures|
Last updated on Wednesday, April 13, 2005
© 2005 Microsoft Corporation. All rights reserved.