How to Develop an OEM Adaptation Layer

An OEM adaptation layer (OAL) is a layer of code between the Windows CE kernel and the hardware of your target device. You develop an OAL to communicate data between your operating system (OS) and your target device and include code to handle interrupts, timers, and so on. For more information about the OAL, see OEM Adaptation Layer.

Some of the startup code for your OAL may already be completed if you already implemented a boot loader. For example, you can reuse parts of the StartUp function and debug routines that were created during the boot loader development process. Conversely, if you have not already developed a boot loader, the following steps cover implementation of stand-alone OAL startup code. For more information about developing a boot loader, see How to Develop a Boot Loader.

Hardware and Software Assumptions

  • You developed and built your boot loader code; public headers and libraries have gone through the Sysgen phase.
  • You are developing the OAL without assistance from CSP OAL code. If CSP libraries and a driver exist for your hardware, use them. The libraries and driver help shorten the time during development and test phases.

If you already have an existing OAL and want to migrate from a previous version of 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.

The set of procedures presented in following steps provides only a basic kernel with a file system and debug network support, and offers no support for drivers. To track your progress in the following table, select the check box next to each step.

Note   You need to create or modify other files outside of the OAL in order to create a tiny kernel board support package (BSP). For example, you need to modify Config.bib, which contains information about the RAM regions used by the OS.

  Step Topic
1. Create a new platform directory and a subdirectory for the OAL on your development workstation.

The following example shows the basic naming convention for a platform called MyPlatform.

  • Platform directory: %_WINCEROOT%\Platform\MyPlatform
  • OAL directory: %_WINCEROOT%\Platform\MyPlatform\Kernel\Hal

You need to include the directories in the dirs file if you want the directories to build as part of a platform build. For more information about dirs file, see Dirs File.

Note   To comply with directory naming conventions, include CPU-specific or assembly language files in a further subdirectory based on the CPU name. For example, if the example platform is ARM-based, then the StartUp code described in the next step would be located in %_WINCEROOT%\Platform\MyPlatform\Kernel\Hal\ARM.
Not applicable
2. Implement the Startup function for the OAL.
Note   In general, StartUp initializes the CPU core, including the SDRAM controller, memory management unit (MMU), and caches. The function performs this in preparation for running the Windows CE kernel.
Parts of this code can be shared with your platform's boot loader. Be careful not to initialize hardware twice in this situation. OAL StartUp should function whether or not the boot loader has run. For example, the OAL should not attempt to enter x86-protected mode if the boot loader has already done so.
You can typically obtain this function from a sample platform using the same CPU core.
OAL StartUp Function Implementation
3. Create a sources file and a makefile to assemble and compile the file containing the StartUp function. Creating the OAL Sources and Makefile Files
4. Build the StartUp source file.

This step verifies that the build files are correct and in place. This step creates a Hal.lib binary in your hardware platform's Lib directory.

Building the OAL Source Code
5. Create the kernel Buildexe directories and create a dirs file to direct the build process.

The Windows CE kernel, of which the OAL is a part, is an .exe file that is created as part of the BSP build process.

There are typically three different kernel variants: basic kernel, kernel with KITL, and a profiling kernel. The focus of this OAL development process is on the kernel with KITL. You will need to create additional build directories and sources files if you want to create the remaining kernel images.

Note   If you try to build the Kernkitl.exe image at this stage, you will receive a number of unresolved externals because a number of required functions have not yet been implemented.
Creating the Kernel Buildexe Directory
6. Create stub versions of the following CPU-specific OAL functions:

For ARM-based platforms only:

For MIPS-based platforms only:

For x86-based platforms only:

For SHx-based platforms only:

  • Not applicable
Note   Create the source file with these stub routines in the %_WINCEROOT%\Platform\MyPlatform\Kernel\Hal\<CPU> directory.
In this step and in the following steps, you will need to create stub versions to resolve link-time dependencies, and thus allow for an OAL and a kernel image to be built. You can then add implementation details to each of the functions in an ordered approach. The routines that follow are roughly divided into functional areas. These areas may lend themselves to being organized into different source files. Any new source files should be added to the sources file to ensure that they are compiled and included in the OAL library.
Creating Stubs for OAL Functions
7. Create stub versions of the following required OAL functions: Creating Stubs for OAL Functions
8. Create stub versions of the following functions: Creating Stubs for OAL Functions
9. Create stub versions of the following functions: Creating Stubs for OAL Functions
10. Create stub versions of the following interrupt functions: Creating Stubs for OAL Functions
11. Create stub versions of the following real-time clock (RTC) functions: Creating Stubs for OAL Functions
12. Create a stub versions of the following function: Creating Stubs for OAL Functions
13. Define the following global variables required by Nk.lib.

Required for all platforms:

Additional variable for ARM-based and x86-based platforms only:

Additional variable for MIPS-based platforms only:

Additional variables for SHx-based platforms only:

Not applicable
14. Build the kernel executable image, Kernkitl.exe, when stub versions of all the functions and global variables are defined.
Note   At this point, the kernel image is not yet very useful, but if you successfully create the resulting Kernkitl.exe image, this establishes the OAL framework and verifies that the build-related files are configured properly.
Building the Kernel Executable Image
15. After creating Kernkitl.exe, you can start adding functionality to the image in stages.

For the remainder of the OAL development process, each stage is implemented incrementally. However, because there is no support for the kernel debugger, you must perform debugging and verification at this point using any of the following forms of debugging: a hardware probe or debugger, serial prints, LED blinks, or another form of debugging.

Not applicable
16. Implement the following CPU-specific pre-OEMInitDebugSerial functions and global variables:

For ARM-based platforms only:

For MIPS-based platforms only:

For x86-based platforms only:

For SHx-based platforms only:

  • SH3CacheLines or SH4CacheLines
  • The code for these functions can be copied from the OAL for a platform that uses the same CPU, or by linking in the CSP library for your CPU.
Microprocessor-specific Issues
17. Implement the OEMCacheRangeFlush function.

The code for this function can be copied from the OAL for a platform that uses the same CPU, or by linking in the CSP library for your CPU.

OEMCacheRangeFlush Function Implementation
18. Stop and ensure that the image builds. Not applicable
19. Create a %_WINCEROOT%\Platform\MyPlatform\Files directory and create the following empty files in the new directory: Platform.bib, Platform.reg, Platform.db, and Platform.dat.

Copy and edit a Config.bib file from a similar platform, and then specify the MEMORY and CONFIG section information for your platform.

Config.bib should minimally specify the NK and RAM section address information. Romimage.exe uses this address information to know how to organize the OS to fit the hardware resources available on your standard development board (SDB).

Note   The addresses in Config.bib must be virtual, not physical. ROMOFFSET should be used to ensure that the OS image downloads to the correct physical RAM or flash memory location.

For more information, see the following topics:

Not applicable
20. Create a %_WINCEROOT%\Platform\MyPlatform\CESYSGEN directory and copy the makefile file from a similar platform into that directory.

For more information about makefile files, see Makefile File.

Not applicable
21. Ensure that all appropriate platform directories have dirs files.

For more information, see Dirs File.

Not applicable
22.From the command line, build an Nk.bin image by entering the following command.
blddemo clean -q

The .bin file contains the Windows CE kernel, and depending on the build flags, it can also contain other executables and support files.

For more information about the Windows CE build tool, see Build Tool.

Not applicable
23. Verify that you can download the Nk.bin image and that you can boot up to at least the OEMInitDebugSerial function in the OAL using any of the following debugging tools: hardware debugger or probe, LED write, or serial debug prints.

Put while(1); in your code to stop the boot.

Note   Once OEMInitDebugSerial is reached, the CPU is executing in virtual address mode. Do not use physical addresses from this point forward, for example, when writing to the debug serial port or LEDs.
If OEMInitDebugSerial is never reached, you may have incorrectly specified OEMAddressTable or are otherwise causing unmapped memory to be accessed, triggering an abort or exception.

After completing this step, you have confirmed that the kernel has set up its virtual memory structures or tables and that caches, translation look-aside buffers (TLBs), and write buffers are enabled.

Not applicable
24. Implement the following serial debug functions. These are the same routines used by the boot loader so you can share the code with the OAL.
Note   Sharing these functions between the boot loader and OAL may require minor changes. For more information, see Sharing Code Between the Boot Loader and the OAL.
Enabling the Debug Serial Port

Implementing the Serial Debug Functions

25. Rebuild Nk.bin and verify that the boot process proceeds through OEMInit.

You should also verify that the kernel calls OEMInitDebugSerial before it calls OEMInit and that serial text is written to the initialized UART.

Not applicable
26. Implement the OEMInit function. Implementing the OEMInit Function
27. Implement the interrupt-related code.

For all platforms:

For ARM-based platforms only:

For non-ARM platforms:

  • An interrupt service routine (ISR) that handles the 1-millisecond (ms) system tick interrupt
Implementing an ISR
28. Implement the power management functions:
  • OEMIdle
  • OEMPowerOff

    Note   Implementation of the OEMPowerOff function is highly device-dependent and often requires changes to the boot loader to resume from the suspend state. Implementing suspend and resume is beyond the scope of this how-to topic. You may leave the OEMPowerOff function stubbed out.
Enabling Power Management
29. Rebuild the Nk.bin image and verify that it boots successfully.

Using a hardware debugger or probe, serial prints, or LEDS, verify that OEMInit returns and that OEMIdle is eventually called.

Not applicable
30. Add KITL initialization code to OEMInit. Adding KITL Initialization Code
31. Add the Windows CE Target Control Shell to your OS image. At the build shell prompt, enter the following command:
set SYSGEN_SHELL=1
Not applicable
32. Rebuild the Nk.bin image and verify that it boots successfully. Ensure that Platform Builder can connect over KITL to the target using the Windows CE Target Control.

Verify that the gi [proc | thrd | mod | delta | all] commands work.

After this step, you have the basic kernel in place. The basic kernel has interrupts enabled and uses virtual memory, caches, TLB, and write buffers. These features make up most of the tiny kernel or minkern functionality.

Not applicable
33. Implement the following RTC functions: Implementing the Real-Time Clock and System Timer
34. Customize memory usage by doing the following tasks:
  • Override MainMemoryEndAddress if you want to include additional contiguous memory than is described in Config.bib.
  • Implement OEMGetExtensionDRAM if you want to include additional noncontiguous memory.
Customizing Memory
35. Implement the OEMIoControl function. Implementing the OEMIoControl Function

See Also

Completing an OAL | Testing an Enhanced OAL | How to Create a Board Support Package | How to Bring Up a Device by Creating a New BSP | Hardware Adaptation How-to Topics

Last updated on Wednesday, April 13, 2005

© 2005 Microsoft Corporation. All rights reserved.