When developing or porting U-Boot to a new board, it is common to encounter boot failures that provide only a cryptic error message and a memory address.
For example, while bringing up an AM57xx-based board, you may encounter:
1initcall sequence 7ffdb800 failed at call 0x8080bd78 (err=-1)
2### ERROR ### Please RESET the board ###
At first glance, this message does not reveal much. However, the reported address contains enough information to identify the exact function responsible for the failure.
This article demonstrates how to trace such addresses back to the corresponding source code using addr2line and nm.
#Understanding the Error
The key part of the message is:
10x8080bd78
This is the address of the function that returned an error during U-Boot initialization.
The goal is to determine which source file and line correspond to this address.
#Using addr2line
The fastest way to identify the location is:
1${CROSS_COMPILE}addr2line -e u-boot -f -p 0x8080bd78
Example output:
1omap_gpio_probe at drivers/gpio/omap_gpio.c:312
This immediately identifies the function and source line involved in the failure.
#If the Address Does Not Resolve
Sometimes the reported address is a runtime address and must be converted into an offset relative to CONFIG_TEXT_BASE.
For example:
1Runtime Address : 0x8080bd78
2CONFIG_TEXT_BASE: 0x80800000
3Offset : 0x0000bd78
Then run:
1${CROSS_COMPILE}addr2line -e u-boot -f -p 0xbd78
#Using nm to Find the Function
Another useful tool is nm, which lists all symbols in the U-Boot image.
1${CROSS_COMPILE}nm -n u-boot | less
Example:
18080bc40 T omap_gpio_probe
28080be20 T omap_gpio_direction_input
Since the failing address:
10x8080bd78
falls between these symbols, the crash occurred inside:
1omap_gpio_probe()
This is often enough to identify the subsystem responsible for the failure.
You can also search for a specific address:
1${CROSS_COMPILE}nm -n u-boot | grep -i omap_gpio
#Using objdump for Detailed Analysis
If additional investigation is required, disassemble the relevant section:
1${CROSS_COMPILE}objdump -d u-boot > u-boot.dis
Search for the failing address:
1grep -A20 -B20 8080bd78 u-boot.dis
This allows you to identify the exact instruction being executed.
#Adding Debug Prints
Once the function is known, add debug statements around the suspected code:
1printf("DEBUG: entering omap_gpio_probe\n");
2
3ret = gpio_request_by_name(dev, "gpios", 0, &desc, 0);, &desc, 0););
4printf("DEBUG: gpio_request_by_name ret=%d\n", ret);
Rebuild U-Boot and observe the last message printed before the failure.
#Verifying the Device Tree
Many initialization failures are caused by missing or incorrect Device Tree properties.
Always inspect the final generated DTB:
1dtc -I dtb -O dts -o u-boot.dts u-boot.dtb
Locate the node involved in the failure:
1grep -A20 gpio@4804c000 u-boot.dts
For an AM57xx GPIO controller, verify that required properties are present:
1gpio1: gpio@4804c000 {
2 compatible = "ti,omap4-gpio";
3 reg = <0x4804c000 0x1000>;
4 gpio-controller;
5 #gpio-cells = <2>;
6 ti,ngpio = <32>;
7 status = "okay";
8};
Missing properties frequently lead to probe failures during the initcall phase.
#Enable Additional Debugging
To obtain more detailed information during boot, enable:
1CONFIG_LOG=y
2CONFIG_LOG_MAX_LEVEL=7
3CONFIG_DEBUG_UART=y
4CONFIG_DEBUG_UART_ANNOUNCE=y
5CONFIG_DM_DEBUG=y
These options provide valuable insight into driver initialization and Device Model probing.
#Recommended Workflow
Whenever U-Boot reports a failure at a specific address:
1initcall sequence ... failed at call 0xXXXXXXXX
follow these steps:
- Resolve the address:
1${CROSS_COMPILE}addr2line -e u-boot -f -p 0xXXXXXXXX
- Find the surrounding symbols:
1${CROSS_COMPILE}nm -n u-boot
- Optionally inspect the assembly:
1${CROSS_COMPILE}objdump -d u-boot
-
Add debug prints inside the identified function.
-
Verify the generated Device Tree.
-
Rebuild and repeat until the failing statement is identified.
#Conclusion
If you get stuck during U-Boot development or board porting, learning how to translate crash addresses back into source code is one of the most effective debugging techniques available. Tools such as addr2line, nm, and objdump allow you to quickly pinpoint the exact function involved, significantly reducing the time required to diagnose and fix boot-time issues.