The Minnowboard Chronicles Episode 5: PEIM and DXE

This week, I explore DXE, and do a deeper dive into the PEI.

Last week in the Minnowboard Chronicles, Episode 4, I achieved a significant milestone: compiling a debug version of the UEFI, loading it into the Minnowboard, and seeing UEFI source code within the SourcePoint JTAG debugger for the first time.

But this, of course, has only whet my appetite for further exploration. I’m fortunate enough to have the Minnowboard available as an open source hardware and software platform that boots into the UEFI shell. So, the sky’s the limit in terms of what I can learn about this x86-based platform and the UEFI software which is at the heart of almost all Intel-based PCs, workstations and servers. The fact that I also have available SourcePoint, which allows me to see all architecturally visible aspects of the Intel hardware and firmware, creates a very powerful learning environment.

Last week, I booted the Minnowboard into the UEFI Shell, where it simply sits and waits for keyboard input. Then I Halted the target to put it into debug mode (also known as probe mode); after which the SourcePoint DXE macro loads the source symbols. After that, it’s a very simple matter of opening the Symbols window to see the Globals, Locals, the Stack, and Classes.

If you want to poke around, it helps that Symbol Search on SourcePoint is screamingly fast. The UEFI build is prodigiously large, and for example doing a “Find Symbol” wildcard search on everything prefaced with “DXE” could in principle take a significant amount of time, given that the database is so large. With SourcePoint, the search is displayed in real time!

Symbol search is screamingly fast

There are also pre-built EFI macros available within SourcePoint to view the HOBs, System Configuration Table, the System Memory Map, and other interesting structures. The debugger is “UEFI-aware”.

HOBs

System Configuration Table

UEFI System Memory Map part 2

I want to come back to DXE again sometime soon, but for this week, the PEI beckoned. I have a deep interest in exploring the code executing as close to system reset as possible – and maybe one day, before reset. But, for now, exploring early PEI was on the agenda.

First, I tried to take control of the target by initiating a PowerCycleReset out of SourcePoint, but that seemed to put the Minnowboard into a strange state, and the only way to recover was to manually power cycle the board. I’m wondering if there’s a rogue watchdog coming from somewhere, or if there’s something wrong with the emulator’s access to some of the key XDP pins. I know that HOOK0 (PWRGOOD) is hooked up, because SourcePoint detects and displays that when there is No Power on the board. HOOK6 (RESET_IN#) is hooked up, but I’m not sure about HOOK7 (RESET_OUT#). This is something I need to check on the Minnowboard schematics when I have a little time. There might also be a flaw I guess in the Debugger Lure design from Tin Can Tools, but unfortunately, the schematics are not available – I get the dreaded 404 Page Not Found message – hopefully they’ll fix that soon, or steer me in the right direction!

In the meantime, it’s easy enough to power cycle the target, turn on the emulator, and launch SourcePoint to halt the target before it gets too far into the boot cycle. Then running the LoadPeims macro (just by clicking on the PEIMs button) loads all the program symbols and points the code view window back to the beginning of the code block where the processor was stopped:

PEI

You can see from the Instruction Pointer on the left that the code is stopped at address 0x’000000007A3F7EBE’, different than where we stopped at the UEFI shell before at 0x’000000007849B171’, for example, within Episode 2 of the Minnowboard Chronicles. We’re also within PiSmmCore.

Scrolling back a little, we see that we are in the function IoRead8(). It’s also clear on the Stack tab within the Symbols window:

IoRead8

This routine is called from SerialPortReadRegister() which is called from SerialPortWrite() which in turn is called from DebugPrint(). So, we’ve caught the code in the middle of a “printf” statement out to the console. I haven’t hooked a serial out console up to the Minnowboard yet (there’s another Lure available for that – a future purchase).

Well, that’s it for now. There’s a lot to digest. If you have any questions about getting started using SourcePoint on the Minnowboard to delve into the BIOS, drop me a note.