One of the reasons I started this blog is to take some of the mystery out of BIOS, which is often portrayed as arcane computing … some combination of technology and black magic. I think it’s valuable to take time in this forum to expose the type of tools available to the BIOS developer. Today’s article focuses on how an Independent BIOS Vendor (IBV) handles debugging BIOS issues.

 

The goal for any BIOS vendor is to deliver a product that doesn’t require extensive debugging. Of course, things don’t always go the way we plan … just like I didn’t plan to spend last weekend having my car repaired, or wait on that tow truck in the rain …

 

Anyway, let’s look at three different scenarios for debugging BIOS on an embedded Intel Architecture system:

  1. Debugging BIOS on a deployed system: determine where the BIOS hangs in the boot process and view extended error codes
  2. Debugging BIOS during development without source code: view verbose debug and trace messages as the BIOS executes
  3. Debugging BIOS during development with source code: analyze, stop and step-through BIOS source code on a debug target system

Deployed Systems

For this example, assume a “deployed system” is setup to work as the customer would receive it. This can be a system in the field or one submitted to quality assurance for integration testing.

 

Debugging BIOS on this system uses checkpoints to show progress through the boot process. BIOS checkpoints are also useful for quality assurance processes, helping to identify where the BIOS may be hanging in the boot process. Think of like the diagnostic module they attach to a car when the “check engine” light comes on (you think that light would come on before the engine starts to smoke).

 

The important thing about debugging BIOS in a deployed system is that it shouldn’t be too intrusive … this is a solution that has to work in the field. In the past checkpoints were viewed on a “checkpoint card” (also known as a “port 80 card” since the checkpoints go to I/O port 0x80). Adding such a card requires an open PCI slot (not common in today’s systems) or a LPC bus header (somewhat proprietary). Both require opening the case, which is tough to do on today’s systems … just look at small form factor platforms like Qseven or the Intel® Embedded Development Board 1-N450.

 

Some board vendors create proprietary methods for displaying BIOS checkpoints, but there are solutions that solve the “open case problem.”  AMIDebug™ Rx is one example, using the USB debug port functionality on Intel USB 2.0 controllers. This solution uses a commodity port that doesn’t require the case to be opened, and lets the USB port to operate normally when AMIDebug Rx is disconnected.

 

Advanced Debug Without Source Code

Development debugging without source code used to rely only on checkpoints, but that has changed with the introduction of UEFI. I discussed the user advantages of UEFI in my previous blog article, but there are numerous developer advantages as well. UEFI defines a set of debug strings, displaying verbose information about the boot flow. Debug strings are enabled when the BIOS is compiled and are routed to a secondary output (keeping them separate from the main system display).

 

[AmiDbg]NBPEI.Entry(FFFF495B)

[AmiDbg]SBPEI.Entry(FFFF1AED)

[AmiDbg]>>> PM Registers Before GPIO Init <<<

[AmiDbg]+===================== PM Registers dump =====================+

[AmiDbg]  PM1a_EVT_BLK.PM1_STS      : Addr = 0400 => Val = 0001

[AmiDbg]  PM1a_EVT_BLK.PM1_EN        : Addr = 0402 => Val = 0000

[AmiDbg]  PM1a_CNT_BLK.PM1_CNT      : Addr = 0404 => Val = 00001C00

[AmiDbg]  PMTMR_BLK.PM1_TMR          : Addr = 0408 => Val = xx9E5F20

[AmiDbg]  P_BLK.PROC_CNT            : Addr = 0410 => Val = 00000000

[AmiDbg]  GPE0_BLK.GPEO_STS          : Addr = 0428 => Val = BDFF0000

[AmiDbg]  GPE0_BLK.GPEO_EN          : Addr = 042C => Val = 00000000

[AmiDbg]+==================== SMI Registers dump =====================+

 

That sequence may look like nonsense to the average user, but it’s great information for debugging UEFI platforms. UEFI debug strings are the equivalent of verbose messages in the Linux kernel, more detailed than basic checkpoints and far more informative than what that so-called mechanic told me about my transmission.

 

[AmiDbg]Register PPI Notify: 605ea650-c65c-42e1-ba80-91a52ab618c6

[AmiDbg]PEIM 8401a046-6f70-4505-8471-7015b40355e3 was not started!!

[AmiDbg]PEIM e008b434-0e73-440c-8612-a143f6a07bcb was not started!!

[AmiDbg]PEIM 32505be8-6469-4f79-9b01-66b3f9617e7d was not started!!

[AmiDbg]PEIM a47438d5-94e9-49b3-bc31-7e6bc9363814 was not started!!

 

I know, it’s hard to believe any of that makes sense … just trust me.

 

That stream of technical nonsense doesn’t get built into a production BIOS, but developers can enable it during development for advanced debugging. These strings can be piped to a RS-232 serial port or captured by USB debug devices like AMIDebug Rx (for systems that do not include a legacy serial port).

 

Advanced Debug With Source Code

Development debugging with source code is the most detailed level of BIOS debugging, adding the ability to step and trace through code in real-time. It’s the best way to see “under the hood” of the BIOS while it runs, assuming the hood isn’t in flames on the side of the highway. You would think something wouldn’t burn like that in a rain storm …

 

Sorry, where was I? Right, source level debugging.

 

Compiling BIOS in debug mode generates a MAP file, used to connect the execution of BIOS on a debug target back to the exact line of source code on the debug host system. If your boss asks, tell them it’s like a GPS that understands processor instructions. The trick is connecting the two systems so the target BIOS can be controlled by an application on the host system. There are two common methods … one connects to the processor, the other connects to the BIOS.

 

A direct processor connection uses a JTAG port, allowing a processor emulator to be connected to the system. Companies like Arium,  market devices that connect to the Intel XDP connector, enabling direct control of the processor at the reset vector. (Arium is an Affiliate member of the Intel® Embedded Alliance).

 

Connectors like Intel XDP are common on development boards, but rarely seen on production platforms. For this reason, BIOS developers market alternatives that give the same level of debug control to systems without XDP or JTAG ports. Each BIOS vendor has a variation of this tool. At AMI, the AMIDebug Rx is used as a host-to-target connection enabling the AMI Debug suite to run prior to memory detection. This type of BIOS debug tool allows JTAG-style debugging on production level hardware.

 

Debug, Debug and Debug Some More

BIOS development isn’t as widely understood as driver or application development, but a variety of debugging methods exist. Platform developers can do everything from diagnose systems in the field to trace source code.

 

I wonder if my car had a USB debug port. I’ll ask the insurance company about that once the fire department gets done with my car …

 

Brian Richardson
Senior Technical Marketing Engineer
American Megatrends, Inc.

 

American Megatrends, Inc. (AMI) is an Affiliate member of the Intel® Embedded Alliance.

 

Got a question about BIOS? … then it’s time to Ask a BIOS Guy! Find Brian on Twitter (@askabiosguy) or leave your question in the comments. Your BIOS question may be featured in an upcoming ‘Ask a BIOS Guy’ article.