Hardware-assisted Debugging with Platform Builder 4.2

 

by James Stulz

Updated January 2004

    Applies to: Microsoft® Platform Builder 4.2

Summary: This paper describes differences between software-assisted and hardware-assisted debugging. It also describes how to set up hardware-assisted debugging using the Platform Builder kernel debugger, how to debug the Windows CE boot loader, and how to overcome debugger limitations.

In Platform Builder, hardware-assisted debugging enables debugging that is otherwise not supported by software-assisted debugging, which is default debugger for the Platform Builder IDE. Specifically, you can do hardware-assisted debugging to debug code used during hardware bring-up, OEM Adaptation Layer (OAL) initialization, boot loading, and execution prior to start of the kernel. However, debugging the operating system (OS) while components such as device drivers and applications are loaded might require workarounds to be successful.

Contents

Hardware-assisted Debugging with eXDI
Software-assisted Debugging
Comparison of Hardware-assisted and Software-assisted Debugging
Setting Up Hardware-assisted Debugging
Overcoming the Limitations of Boot Loader Naming Conventions
Using Third-Party Add-ins
For More Information

Hardware-assisted Debugging with eXDI

With Platform Builder and the Extended Debugging Interface (eXDI) driver, you can do hardware-assisted debugging to control the execution of a target device and to examine and modify the state of the device. Third-party vendors provide the required hardware and software, which includes, at a minimum, a driver and either a probe or an emulator. Vendors may also provide a target device or a combined target device and probe. These add hardware-specific functionality to the debugging interface, with one piece of hardware and a software plug-in. Platform Builder provides an Integrated Development Environment (IDE) interface to the third-party components.

Hardware-assisted debugging extends the capabilities of Platform Builder beyond that of software debugging. Because hardware-assisted debugging is independent of the OS, you can isolate complex embedded design problems. You can set breakpoint conditions that are not limited to software, and can take into account any combination of logic signals from target devices. You can focus on a point-of-interest in a real-time, non-intrusive manner to gain a thorough and complete understanding of the system's behavior, including high-resolution time stamps to support benchmarking and application profiling.

An eXDI driver works solely with the debugging support available on the hardware and does not rely on an OS for this support. The hardware debugger can work even if the OS is not fully functional or if there is no OS on the target device. The hardware-assisted debugger can debug code used during initialization, such as hardware setup, boot loading, and OAL initialization, as well as OAL routines and the kernel itself. You can also use hardware-assisted debugging to debug other kinds of code, such as drivers and applications. For drivers and applications, the kernel debugger may be more appropriate and easier to use due to limitations of the current support of hardware-assisted debugging in Platform Builder.

To use hardware-assisted debugging, you must install a third-party eXDI driver on a development workstation running Platform Builder and connect a probe or emulator between the development workstation and the target device. The driver multiplexes all communication between the probe or emulator and all clients, including Platform Builder and debugger plug-ins. Depending on the hardware-specific characteristics, such as register usage, of the debugging target, the same driver can sometimes support multiple CPUs, even those from different CPU families.

Software-assisted Debugging

Platform Builder provides a software-assisted debugging solution as the default debugger. In software-assisted debugging, a special OS image contains a module in the kernel called Kdstub. The OS kernel assists the debugger in controlling the execution of a target device and in examining and modifying the state of the device. Software-assisted debugging requires no additional hardware, and is easy to install and use as part of Platform Builder.

Software-assisted debugging requires the kernel to be running because the debugging functionality relies on kernel services for control of execution and for access to memory. As a result, software-assisted debugging applies only to code that does not support the debugging routines. Code that executes before Kdstub is running misses the opportunity to be debugged. For example, in this mode you cannot debug the memory routines that the debugger uses to read and write memory.

Comparison of Hardware-assisted and Software-assisted Debugging

The following table shows the differences between eXDI hardware-assisted debugging and software-assisted debugging with the Platform builder kernel debugging stub, ddstub.

eXDI hardware-assisted debugging Software-assisted kernel debugging
Does not rely on target-side debugging routines. Can debug in every situation, immediately after device reset. Operates non-intrusively and independently of the kernel state. Relies on a special kernel debugging module to capture exceptions and breakpoints, access kernel information, request some kernel operations, communicate with the debugger, and restart the debugged code. Operates relatively intrusively and dependently.
Has no knowledge of where symbols are loaded at run time. Gets module information from the .bin file that is downloaded to the target device. Gets the first module, usually Nk.exe, for the kernel module file, load address, and data relocation address. Finds the location of symbols dynamically, at run time through kernel-generated load and unload notifications.
May be able to read or write memory, registers, or breakpoints while running, depending on the type of target and probe being used. Cannot read or write memory, registers, or breakpoints while running.
Choosing Break from the Debug menu results in an asynchronous break at the exact current execution location. Choosing Break from the Debug menu results in calling DebugBreak() in Shell.exe, a process on the target device. This implies that the Shell.exe threads are running. DebugBreak() contains a software breakpoint that is trapped by the Windows CE kernel.
When the target device is running, the Process and Thread windows can be populated by querying the Shell.exe process on the target device. However, the Process and Thread windows might not be available when the target device is halted. When the target device is running, the Process and Thread windows are populated by querying the Shell.exe process on the target device. When the target device is halted, those windows are populated by querying the kernel debugging module. Therefore, these windows are always available.
The reduced intrusiveness of the eXDI hardware debugger has some side effects. The debugger cannot always read or write memory, or set software breakpoints, on any locations of a process space that has page-on-demand enabled. The kernel debugging module calls kernel routines, even when halted, to page in any virtual memory pages it needs to access.

Benefits Of Hardware-assisted Debugging

  • Low intrusiveness and low-level control of the target CPU, and possibly other peripheral devices.

    For example, you can freeze the CPU state when it stops at an exception or a breakpoint, after a single step, or by an asynchronous break.

  • The potential to debug almost any code because of a lack of reliance on kernel support.

    For example, you can use hardware-assisted debugging to debug the boot loader, initialization code, and critical kernel routines.

  • Use of the hardware-assisted debugging register for enhanced code breakpoints, data breakpoints, and stepping when in kernel debugger mode.

    For example, you can step or set breakpoints in ROM. Use of the hardware-assisted debugging register also causes a dramatic improvement in the execution time when data breakpoints are set.

  • Extensibility through the use of plug-ins.

    Third-party vendors provide additional software plug-ins for associated probes and emulators. Plug-ins provide the following kinds of extensions to the hardware debugger:

    • Execution trace
    • Complex data breakpoint and code breakpoint triggering
    • Flash programming utility or RAM downloader
    • Peripheral registers browser
    • Probe and target configuration

Limitations Of Hardware-assisted Debugging

  • Some exceptions are not caught.

    This issue varies by exception, different CPU architectures, and different implementations of the hardware emulator architecture. To work around this limitation, you can set a breakpoint in the kernel code that processes all exceptions, as shown in the following procedure.

    1. Edit the \wince420\private\winceos\coreos\nk\kernel\<TargetArchitecture>\md<TargetArchitecture>.c kernel source file that is part of the public source provided by Platform Builder.

      Note   The source files to set breakpoints in kernel code are slightly different for each target architecture that Windows CE supports. The source file for each target architecture is contained in in the related directory. For example, source code to set breakpoints for SH4 microprocessors is in the SH directory.

    2. Set a code breakpoint in the routine ExceptionDispatch.

      When this breakpoint is triggered, you will be able to step out of the kernel exception processing routines and into the function that actually caused the exception and debug it. Inspect the call stack to identify the transition from these kernel routines to one that has the exception. For example, the exception that is raised for DebugBreak() is not commonly caught by hardware-assisted debugging.

  • No notification when modules are loaded.

    Windows CE 4.2 and earlier versions that support hardware-assisted debugging provide only Nk.exe or boot loader debugging. Therefore, in these versions, if an exception is raised in a loaded module, the debugger cannot associate source code with an instruction pointer. The exception will result in the debugger displaying the code in assembly mode. This happens when the module table is not populated.

    To work around this limitation, manually update the module table. After the debugger stops at the exception, open and refresh the module table window. This causes the debugger to read the module information from the specific kernel's data structures and fill the module table. You can then request the debugger to switch the view to source mode.

    Because the module table will not stay current, the user must manually refresh the module table when modules are loaded or unloaded.

  • Cannot set breakpoints in modules that are not loaded.

    You can override this behavior by entering subkeys and values in the registry under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Platform Builder\3.00\Hardware Debug\BinImage registry key. You must use the 3.00 subkey and not a subkey corresponding to the current version of Platform Builder.

    For each additional module to be loaded, you must specify a subkey that corresponds to the module. For example, for the Coredll.dll module, you must specify a Coredll.dll subkey that contains the following values:

    • LoadOffset (REG_DWORD)

      This is the address at which the module is loaded in virtual memory space.

    • UseRegKey (REG_DWORD)

      This is the individual module-enable flag

      Note   You can specify the ForceUseAllSubRegKey flag to bypass individual flags.

  • Reading or writing memory and setting software breakpoints does not commit pages.

    The hardware-assisted debugger does not commit virtual memory pages that have not already been committed by the OS. This does not influence debugging Nk.exe. If you need to debug other processes, you can build an image that disables page-on-demand. However, this may have side effects that alter the behavior, masking the problem you are trying to debug.

  • Breakpoints are not reloaded when the memory page is freed.

Setting Up Hardware-assisted Debugging

In Platform Builder 3.0, hardware-assisted debugging software and hardware products provided by third-party probe vendors overwrote existing drivers. For Platform Builder 4.0 and later, the drivers for third-party software are updated to link to a list of available drivers. The registry key that holds the list of drivers is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\eXdi\DriverList.

If you install a third-party eXDI driver to add hardware-assisted debugging support, Platform Builder activates the user interface elements that allow users to easily switch between different hardware-assisted products. The user interface elements present the option to select hardware-assisted debugging in the Target\Configure Remote Configuration dialog box. This dialog box lists the eXDI drivers installed in installation order; that is, the most recently installed driver appears first in the list of available drivers.

Although hardware-assisted debugging is less intrusive than software-assisted debugging and requires no special software on the device, hardware-assisted debugging requires access to the image file, Nk.bin. In addition, for a better debugging experience, hardware-assisted debugging requires access to the flat release directory that contains the binary files and debugging symbols that match the image you are debugging.

Overcoming the Limitations of Boot Loader Naming Conventions

Debugging the boot loader requires initial setup to overcome the name changes that occur during the boot loader and OS image building phases. Platform Builder builds the boot loader binary files and copies them into the flat release directory.

The following procedure shows how to allow boot loader debugging:

  1. In Platform Builder, after you have completed building your platform, open a Build\Open Build Release Directory window and list the EBOOT files using the following command:

    Dir eboot.*
    

    If everything built successfully, you will have the following files in your flat release directory:

    • Eboot.bin
    • Eboot.exe
    • Eboot.map
    • Eboot.pdb
    • Eboot.rel
  2. Create a new subdirectory in the flat release directory to hold the boot loader files:

    Mkdir eboot
    
  3. Copy the Eboot files into the new directory and rename the files to correct names for debugging:

    Copy eboot.* eboot\nk.*
    
  4. Using Platform Builder, open Nk.bin in the EBOOT directory as a workspace.

  5. Set the Use Hardware Debugger check box in the Configure Remote Connection dialog box.

  6. Using the Platform Builder Breakpoints dialog box, set a hardware breakpoint at the BootloaderMain() function entry point.

  7. Start the debugger manually by pressing F5.

    You can omit this step if the third-party eXDI driver starts the debugger when the probe or emulator is started or powered on.

  8. Start the probe or emulator.

  9. Start the device so the boot loader code is executed.

    Note   The boot loader on the device must match the one that the debugger opened debugging symbols for, eboot\nk.pdb. This might require that you to download the eboot\eboot.bin version to the device before starting the debugger.

Using Third-Party Add-ins

The Platform Builder debugger is built on the Microsoft Visual C++® 6.0 development system. Although the debugger provides a rich software debugging experience, many hardware-assisted debugging capabilities are not included. To add these capabilities, third-party vendors provide eXDI plug-ins for Platform Builder. These plug-ins provide the following functionality:

  • Complex data breakpoint triggers
  • Memory download and execution
  • Execution trace

To use a third-party probe or emulator, install the plug-in shipped by the vendor.

Probe Vendors That Support Platform Builder

The following table shows some of the third-party vendors that provide probes or emulators suitable for hardware-assisted debugging with Platform Builder.

Vendor Probe CPU URL for more information
ARM Multi-ICE** ARM, XScale http://www.arm.com/products/DevTools/MultiICEDriver.html
EPI Majic** ARM, XScale, MIPS http://www.epitools.com/pdf/EPI_eXDI.pdf
Hitachi E10A** SH4 http://www.hitachi.com/New/cnews/E/1998/980413B.html
Macraigor OCDemon Raven** XScale http://www.ocdemon.net/pxa_210_250.pdf
Microtek PowerPack** Pentium X86 http://www.microtekintl.com/MainSite/Microsoft.htm

**The non-Microsoft software and hardware referenced in this document are included for illustrative purposes only. Illustrations that use such third-party software and hardware as examples are not intended to be an endorsement or recommendation of any of these products. We provide this information only as a convenience for our customers for purposes of explaining a practical application and do not provide warranties of any kind, whether express, implied, or statutory, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

For More Information

About the Author

James Stulz has been with Microsoft over 10 years as a Software Design Engineer and Program Manager. Currently, he is the Program Manager responsible for Windows CE compilers and the Platform Builder kernel debugger. James was instrumental in designing and developing all of the Windows CE debuggers in use today. He has a degree in Computer Science from the University of California at Santa Cruz.