Compartilhar via


KITL and OAL debug messages in Windows CE6.0

Posted by Travis Hobrla

 

KITL and OAL debug messages in Windows CE6.0

Introduction

Last time we talked, we learned about debug messages and debug zones in Windows CE. Today we’ll continue that topic (read the first part if you haven’t already) and talk about some modules that behave a bit differently than others when it comes to debug messages and debug zones. These modules are KITL (Kernel Independent Transport Layer) and the OAL (OEM Abstraction Layer). I’m not going to go into the details of what KITL and the OAL are in this article, so if you’re not familiar with their basic functions I’d recommend checking out the Platform Builder docs. Suffice to say, debug messages in these modules are very relevant to a BSP developer such as myself.

Debug messages are particularly important in these modules. Much of the OAL and KITL code runs very early in the boot process, before the debugger is available. Thus, there are limited means to debug problems in these modules. Hardware debugging solutions like JTAG and debug messages are the most common ways to get debugging information.

Why are these modules different?

Most Windows CE follow the paradigm outlined in my last post. But before CE 6.0, the kernel, KITL, and OAL were linked together as one module - which meant that only one instance of dpCurSettings could exist between them. This one instance was not sufficient since someone interested in debugging the OAL often had different aims than someone debugging the kernel. Moreover, the DEBUGREGISTER API described in the last article might not even be initialized at the time we wanted to see messages. So the OAL and KITL developed their own macros to work around this: OALMSG and KITL_DEBUGMSG.

CE5.0 messages – OAL

In CE5.0, the OAL used OALMSG to output debug messages in OAL code. The OAL maintained a separate variable called g_oalLogMask. This variable is similar to the ulZoneMask of dpCurSettings, though it is defined for both retail and debug builds. Similar to the DEBUGZONE macros, the OAL used OALZONE macros (see platform\common\src\inc\oal_log.h for the macro definitions). OALMSG acted like a DEBUGMSG. The OALLogSetZones function was used for changing the zone mask. By default, OALMSG output went to the debug serial port of the device until the debugger WAS connected. OALMSGS forced a message to the serial port regardless of a debugger connection.

CE6.0 messages – OAL

In CE6.0, the OAL is its own separate module, so g_oalLogMask has been replaced with the more consistent dpCurSettings variable, and the macros adapted accordingly. OALMSG and OALMSGS are still the easiest way to output debug messages.

CE5.0 messages – KITL

In CE5.0, KITL code used two methods to output debug messages. The first was KITL_DEBUGMSG – a private API used in the kernel-side KITL implementation. This macro behaved differently from the typical debug zone macros. First, the macro did not support the usage of && and || when evaluating zones. Second, KITL_DEBUGMSG called the KitlOutputDebugString function which always printed to serial debug output, took a char* argument as opposed to a Unicode character, and supported a smaller subset of printf conventions.

The second method was to simply use the OAL’s mechanism: OALMSG. Most public code used this mechanism. This meant that g_oalLogMask / OALLogSetZones actually controlled KITL debug zones in addition to OAL debug zones.

CE6.0 messages – KITL

In CE6.0, we moved the KITL_DEBUGMSG API into the public API set and added a KITL_RETAILMSG that offered similar functionality for retail builds. Most KITL-related OALMSG statements were converted to KITL_RETAILMSGs to get similar functionality. Note that the KITL_RETAILMSG macro carries the same differences (mostly limitations) that that came with the KITL_DEBUGMSG in CE5.0. Probably the most important distinctions are that OALMSG takes Unicode arguments and supports many printf conventions whereas KITL_RETAILMSG does neither.

In general, KITL_RETAILMSG and KITL_DEBUGMSG are the easiest macros to use for KITL debug output. It is still possible to use the OALMSG macros with KITL’s dpCurSettings if you need broader message functionality. If you need OALMSG at all, I recommend using OALMSGS, since when you are debugging KITL code you shouldn’t rely on a connected debugger (after all the debugger is dependent on working KITL code!)

Changing debug zones for OAL / KITL

Most of the mechanisms we covered for changing a modules’ zones relied on checks during module load using the DEBUGREGISTER API. However, as the OAL and KITL are loaded quite early in the boot process, this API isn’t available to us. Thus, changing the debug zones is more limited than it is for most modules. Here are the ways you can change it:

1. The initial (hard-coded) state of dpCurSettings (or g_oalLogMask for CE5.0).

To change this, you need to modify the module code, recompile, and Make-Run Time Image.

 

2. A fix-up variable in config.bib

You can architect your OAL / KITL to override the compiled value with the value from a fix-up variable. Fix-up variables are just 32-bit values that are declared at compile time (and must be initialized to a nonzero value) and then get substituted a new value during the makeimg process. For a good example of this, check out CEPC’s config.bib in CE6.0 and the corresponding code in OEMInit:

From platform\CEPC\files\config.bib:

; This fix-up variable is a bitfield that can be used to initialize

; the OAL debug zones per oal_log.h. Uncomment the line and

; change the hexadecimal bits to enable the desired zones. The

; default value (0x0000000B) enables the OAL_LOG_ERROR,

; OAL_LOG_WARN, and OAL_LOG_INFO zones, and will be used by

; OEMInit if the line remains commented out.

;

; nk.exe:initialOALLogZones 00000000 0x0000000B FIXUPVAR

From platform\common\src\x86\common\startup\oeminit.c:

// Set up the debug zones according to the fix-up variable initialOALLogZones

OALLogSetZones(initialOALLogZones);

3. The value of dpCurSettings in RAM.

There are a few ways to modify dpCurSettings dynamically in RAM.

   In run state:

The CE Debug Zones in Platform Builder (Target->CE Debug Zones) will give you a list of modules and zones which you can change. You can also use the ‘zo’ command in the shell (Target->Target Control) to modify the zones. Running ‘?’ in the shell gives you a good description of how the ‘zo’ command works.

   You could also call OALLogSetZones directly or modify dpCurSettings (or g_oalLogMask for CE5.0) from OAL/KITL code.

    In break state:

    When execution is halted you can modify the value of dpCurSettings right in the debugger. The easiest way to do this is to open a watch window (Debug->Windows->Watch) and set a Watch for {,,mymodule.dll}dpCurSettings. In CE6.0, the OAL module is nk.exe and the KITL module is kitl.dll.

Adding debug zones to your CE6.0 OAL / KITL code

Supporting debug zones in OAL / KITL Code is quite simple. All you need to do is link with oal_log.lib or kitl_log.lib from the platform\common tree and include the appropriate headers (oal_log.h for OAL, kitlprot.h for KITL).

Conclusion

Hopefully you now have a good understanding of the quirks of debug zones in the OAL and KITL. I find that familiarizing yourself with your platform’s OAL and KITL debug messages goes a long way in diagnosing OAL and KITL problems, even those that don’t surface until later in the boot process. I’d encourage you to take a look at your output and see if it gives you any bright ideas.

Comments