setenv fdt_addr 0x45000000 # Memory address to load DTB fatload mmc 0:1 $kernel_addr_r uImage fatload mmc 0:1 $fdt_addr my-board.dtb bootm $kernel_addr_r - $fdt_addr This command tells U-Boot to boot the kernel and pass the DTB firmware blob at 0x45000000 . Despite its elegance, DTB firmware is a frequent source of boot failures. Here are the most common issues and how to resolve them. 1. The "Uncompressed DTB" Error Symptom: Kernel prints "No FDT memory address provided" or "FDT and ATAGS support not compiled in." Cause: The firmware (U-Boot) did not pass a valid DTB address to the kernel, or you are using an older kernel that expects ATAGS (the older ARM boot method). Fix: Rebuild the kernel with CONFIG_ARM_APPENDED_DTB set, or update U-Boot to explicitly set fdt_addr . 2. Machine Model Mismatch Symptom: Kernel panic: "Unable to handle kernel NULL pointer dereference" early in boot, or "No machine model found." Cause: The DTB contains a compatible string (e.g., "my,board" ), but the kernel does not have a machine descriptor or SoC support that matches. Fix: Ensure your kernel is compiled for the correct SoC family (e.g., CONFIG_ARCH_MXC for i.MX). Examine the DTB with:
dtc -I dtb -O dts my-board.dtb | grep compatible Symptom: U-Boot loads the DTB, but the kernel reports "Bad device tree blob" or "Invalid magic number." Cause: The DTB stored in flash or eMMC has become corrupted, or the firmware loaded the wrong size. Fix: Re-flash the DTB. Check the DTB magic number: dtb firmware
By mastering DTB compilation, U-Boot integration, and overlay application, you take full control of the embedded boot process. The DTB is more than a file; it is the contract between firmware and the operating system. Make it accurate, make it reliable, and your embedded system will thank you with thousands of hours of stable operation. setenv fdt_addr 0x45000000 # Memory address to load
When your board fails to boot, remember the handshake. Check that the firmware is loading the correct DTB. Verify the DTB’s integrity. Ensure the kernel is compatible. And finally, appreciate the elegant simplicity of a technology that keeps the kernel hardware-agnostic while allowing developers to describe their exotic hardware in a few thousand lines of plain text. To understand DTB firmware
/dts-v1/; / model = "My Custom Board"; compatible = "my,board"; memory@0 device_type = "memory"; reg = <0x0 0x80000000 0x0 0x20000000>; /* 512MB at 0x80000000 */ ; chosen bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2"; stdout-path = "serial0:115200n8"; ; serial@ff130000 compatible = "ns16550a"; reg = <0x0 0xff130000 0x0 0x1000>; interrupts = <0 22 4>; clock-frequency = <24000000>; ; ; Using the Device Tree Compiler (dtc) from the kernel source:
, therefore, refers to the practice of storing, loading, and passing the Device Tree Blob to the kernel via the firmware or bootloader. It is not a separate type of firmware; rather, it is a critical data payload that the firmware delivers to the operating system. Why Do We Need DTB Firmware? The Legacy of x86 vs. Embedded On a standard x86 PC, the kernel can probe hardware via PCI, USB, and ACPI tables. The hardware is largely self-discoverable. Embedded systems (ARM, RISC-V) are different. A custom board might have an I2C temperature sensor at address 0x48 on bus 2 , or an FPGA wired to a specific set of GPIO pins. There is no standardized "plug and play" for these components.
If you have ever tried to boot a Linux kernel on a Raspberry Pi, BeagleBone, or a custom System-on-Module (SoM) only to be met with a black screen or a kernel panic, you have likely encountered a DTB firmware mismatch. This article dives deep into what DTB firmware is, how it works, why it is separate from the kernel, and how to debug it when things go wrong. To understand DTB firmware , we must first break down the two halves of the phrase. Firmware: The Low-Level Overseer In traditional PCs, firmware (BIOS/UEFI) initializes hardware, runs Power-On Self-Test (POST), and loads a bootloader. In the embedded world, firmware often refers to the code running on the board before the OS—typically U-Boot , TF-A (Trusted Firmware-A) , or a simple bootloader stored in SPI flash or eMMC. DTB: Device Tree Blob The Device Tree is a data structure that describes the hardware components of a computer system. It lists CPUs, memory addresses, interrupt controllers, UARTs, I2C buses, GPIO pins, and peripheral devices. The Device Tree Blob (DTB) is the compiled, binary version of the Device Tree Source (DTS) file. The Linux kernel reads this blob at boot time to understand what hardware it is running on.