Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

How to Develop an OEM Adaptation Layer (Windows Embedded CE 6.0)


An OEM adaptation layer (OAL) is a layer of code between the Windows Embedded CE kernel and the hardware of your target device.

You develop an OAL to communicate data between your OS and your device and include code to handle interrupts, timers, and so on. For more information about the OAL, see OEM Adaptation Layer.

If you have already implemented a boot loader, you may be able to reuse some code for the startup code of your OAL. For example, you can reuse parts of the StartUp function and debug routines that you created during the boot loader development process.

Conversely, if you have not developed a boot loader, the steps in the table below cover implementation of stand-alone OAL startup code.

For more information about developing a boot loader, see How to Develop a Boot Loader.

For the steps below, assume that the following hardware and software conditions exist:

  • 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 SOC (system-on-chip) OAL code. You are using SOC libraries and a driver if they exist for your hardware. The libraries and driver help speed up the development and test phases.
    The SOC directory is new for Windows Embedded CE 6.0. The contents of the Windows CE 5.0 CSP directory have been restructured and migrated to the SOC directory.

The following steps provide only a basic kernel with a file system and debug network support; there is no support for drivers. To develop an OAL, follow the steps in the table below.

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

Step Topic

1. Create a hardware platform directory and a subdirectory for the OAL on your development computer.

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

  • Hardware platform directory: %_WINCEROOT%\Platform\MyPlatform
  • OAL directory: %_WINCEROOT%\Platform\MyPlatform\Src\Kernel\OAL

Include the directories in the dirs file if you want the directories to build as part of a run-time image. For more information about the dirs file, see Dirs File.

Not applicable

2. Implement the Startup function for the OAL.

Typically, StartUp initializes the CPU core, including the SDRAM controller, memory management unit (MMU), and caches. The function performs these actions in preparation for running the Windows Embedded CE kernel.
Parts of this code can be shared with your hardware 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 OAL 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

6. Create stub versions of the following CPU-specific OAL functions:

For ARM-based hardware platforms only:

For x86-based hardware platforms only:

For SHx-based hardware platforms only:

Create the source file with these stub routines in the %_WINCEROOT%\Platform\MyPlatform\Src\Kernel\OAL directory.
In this step and in the following steps, you must create stub versions to resolve link-time dependencies so an OAL and a kernel image can 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.

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

Additional variable for MIPS-based hardware platforms only:

Not applicable

14. After creating Kernkitl.exe, you can start adding functionality to the run-time 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

15. Implement the following CPU-specific pre-OEMInitDebugSerial functions and global variables:

For ARM-based hardware platforms only:

For MIPS-based hardware platforms only:

For x86-based hardware platforms only:

For SHx-based hardware platforms only:

The code for these functions can be copied from the OAL for a hardware platform that uses the same CPU or by linking in the SOC library for your CPU.

Microprocessor-specific Issues

16. Implement the OEMCacheRangeFlush function.

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

OEMCacheRangeFlush Function Implementation

17. Stop and ensure that the run-time image builds.

Not applicable

18. 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 hardware platform and then specify the MEMORY and CONFIG section information for your hardware platform.

At a minimum, Config.bib should 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).

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

For more information, see the following topics:

Not applicable

19. Create a %_WINCEROOT%\Platform\MyPlatform\Cesysgen directory and copy the makefile file from a similar hardware platform into that directory.

For more information about makefile files, see Makefile File.

Not applicable

20. Ensure that all appropriate hardware platform directories have dirs files.

For more information, see Dirs File.

Not applicable

21. From the command line, build an Nk.bin image by entering the following command.

blddemo clean -q

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

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

Not applicable

22. 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.

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

After 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

23. 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.

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

24. 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 universal asynchronous receiver-transmitter (UART).

Not applicable

25. Implement the OEMInit function.

Implementing the OEMInit Function

26. Implement the interrupt-related code.

For all hardware platforms:

For ARM-based hardware platforms only:

For non-ARM hardware platforms:

  • An interrupt service routine (ISR) that handles the 1-millisecond (ms) system tick interrupt

Implementing an ISR

27. Implement the power management functions:

  • OEMIdle
  • OEMPowerOff
    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 topic. You may leave the OEMPowerOff function stubbed out.

Enabling Power Management

28. Rebuild the Nk.bin image and verify that it boots successfully.

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

Not applicable

29. Add KITL initialization code to OEMInit.

Adding KITL Initialization Code

30. Add the Windows Embedded CE Target Control Shell to your run-time image. At the build shell prompt, enter the following command:


Not applicable

31. 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 Embedded 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, which make up most of the tiny kernel or minkern functionality.

Not applicable

32. Implement the following RTC functions:

Implementing the Real-Time Clock and System Timer

33. 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

34. Implement the OEMIoControl function.

Implementing the OEMIoControl Function

Community Additions

© 2015 Microsoft