The Minnowboard Chronicles Episode 4: UEFI Source Code

Success! This week, I managed to compile a debug version of the UEFI, load it into the Minnowboard, and see UEFI source code in SourcePoint for the first time.

Last week, in the Minnowboard Chroncles Episode 3, I did a source build for the release BIOS of the Minnowboard Turbot (also known somewhat interchangeably as the Minnowboard MAX). With ASSET’s JTAG-based hardware-assisted x86 debugger, SourcePoint, I was able to see disassembled code for the UEFI shell. This was interesting, but it only whet my appetite for more investigation. By downloading the UEFI source tree, I had access to the source code, and wanted to see it within our debugger in a meaningful code execution context. Making the source code visible to the SourcePoint debugger took some extra steps.

The linker .map files contain information on the absolute (or relative) addresses for the code that is part of the object build. When loaded into the target, the UEFI firmware on the target contains strings that hold the paths to the program symbol files on your hard drive. SourcePoint macros can be executed to read target memory, find these strings, then load the symbol files specified in these paths. The symbol files must be located in the same path specified in the UEFI firmware. So, it was a relatively straightforward matter to rebuild a Debug image with the symbol information, and then run the EFI.mac macro file located in the SourcePoint Macro\UEFI directory. This creates six custom toolbar buttons and associates each with a corresponding UEFI procedure:

  • The StartPEI icon resets the target, then runs to PeiMain and loads the PEI symbols. 
  • The PEIMs (Pre-UEFI Initialization Modules) icon loads the symbol files for the PEI modules found in target memory. 
  • The DXEs (Driver Execution Environments) icon loads the symbol files for the DXE modules found in target memory. 
  • The HOBs (Hand-Off Blocks) icon displays a list of UEFI HOBs found in target memory. 
  • The SysConfigTable icon displays the contents of the UEFI system configuration table. 
  • The DumpMemMap icon displays the UEFI Memory Map. 

After clicking on the DXE icon within SourcePoint, I loaded much of the DXE source code and symbols. It took a few minutes, with clear progress bar indicators along the way:

DXE symbol loading

Ultimately, I got all the symbols and source code loaded and displayed, and could easily click on Globals, Locals, a view of the Stack, and all Classes:

Source code

The Globals tab displays a hierarchy of loaded programs. Programs can be expanded to show modules, procedures, and symbols. 

The Locals tab shows the variables accessible in the current stack frame. 

The Stack tab shows the stack as a list of stack frames. 

The Classes tab lists structure and class definitions in a hierarchy similar to that under the Globals tab. 

Very impressive!

In my next episode of the Minnowboard Chronicles, I’ll be exploring the PEI, looking at HOBs and the UEFI System Configuration table, and loading symbols just before the DXE modules run instead of running to the UEFI shell.