Skip to main content.

U-Boot is capable of quite comprehensive handling of the flattened device tree blob, implemented by the fdt family of commands:

Note: Included topic DULGData_canyonlands.UBootFDTHelp? does not exist yet

First, the blob that is to be operated on should be stored in memory, and U-Boot has to be informed about its location by the fdt addr command. Once this command has been issued, all subsequent fdt handling commands will use the blob stored at the given address. This address can be changed later on by issuing fdt addr or fdt move command. Here's how to load the blob into memory and tell U-Boot its location:

=> print fdt_addr_r
fdt_addr_r=0x00b00000
=> print fdt_file
fdt_file=/tftpboot/duts/canyonlands/canyonlands.dtb
=> tftp ${fdt_addr_r} ${fdt_file}
Waiting for PHY auto negotiation to complete... done
ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/canyonlands.dtb'.
Load address: 0xb00000
Loading: T #
done
Bytes transferred = 10190 (27ce hex)
=> fdt addr ${fdt_addr_r}
=>

We can now print the device tree stored in the blob just loaded:

=> fdt print /cpus
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

Let's now use fdt mknode to create a new node hanging off the root of the tree. We will use the fdt list command to verify that the new node has been created and that it is empty:

=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt mknode / testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

Now, let's create a property at the newly created node; again we'll use fdt list for verification:

=> fdt set /testnode testprop testvalue
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

The fdt rm command is used to remove nodes and properties, let's delete the newly created test property, and then the test node:

=> fdt rm /testnode testprop
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt rm /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

To move the blob from one memory location to another we will use the fdt move command. Besides moving the blob, it makes the new address the "active" one - similar to fdt addr:

=> fdt move ${fdt_addr_r} $CFG_RAM_WS_BASE
fdt - flattened device tree utility commands

Usage:
fdt addr   <addr> [<length>]       - Set the fdt location to <addr>
fdt boardsetup             - Do board-specific set up
fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active
fdt resize             - Resize fdt to size + padding to 4k addr
fdt print  <path> [<prop>]       - Recursive print starting at <path>
fdt list   <path> [<prop>]       - Print one level starting at <path>
fdt set      <path> <prop> [<val>]    - Set <property> [to <val>]
fdt mknode <path> <node>       - Create a new node after <path>
fdt rm      <path> [<prop>]       - Delete the node or <property>
fdt header             - Display header info
fdt bootcpu <id>          - Set boot cpuid
fdt memory <addr> <size>       - Add/Update memory node
fdt rsvmem print          - Show current mem reserves
fdt rsvmem add <addr> <size>       - Add a mem reserve
fdt rsvmem delete <index>       - Delete a mem reserves
fdt chosen [<start> <end>]       - Add/update the /chosen branch in the tree
               <start>/<end> - initrd start/end addr
NOTE: Dereference aliases by omiting the leading '/', e.g. fdt print ethernet0.
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt mknod / foobar
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt addr ${fdt_addr_r}
=> fdt list /
/ {
   #address-cells = <0x2>;
   #size-cells = <0x1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <0x1>;
   aliases {
   };
   cpus {
   };
   memory {
   };
   interrupt-controller0 {
   };
   interrupt-controller1 {
   };
   interrupt-controller2 {
   };
   interrupt-controller3 {
   };
   sdr {
   };
   cpr {
   };
   l2c {
   };
   plb {
   };
};
=>

One of the modifications made by U-Boot to the blob before passing it to the kernel is the addition of the /chosen node. Linux 2.6 Documentation/powerpc/booting-without-of.txt says that this node is used to store "some variable environment information, like the arguments, or the default input/output devices." To force U-Boot to add the /chosen node to the current blob, fdt chosen command can be used. Let's now verify its operation:

=> fdt list /
/ {
   #address-cells = <0x2>;
   #size-cells = <0x1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <0x1>;
   aliases {
   };
   cpus {
   };
   memory {
   };
   interrupt-controller0 {
   };
   interrupt-controller1 {
   };
   interrupt-controller2 {
   };
   interrupt-controller3 {
   };
   sdr {
   };
   cpr {
   };
   l2c {
   };
   plb {
   };
};
=> fdt chosen
=> fdt list /
/ {
   #address-cells = <0x2>;
   #size-cells = <0x1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <0x1>;
   chosen {
   };
   aliases {
   };
   cpus {
   };
   memory {
   };
   interrupt-controller0 {
   };
   interrupt-controller1 {
   };
   interrupt-controller2 {
   };
   interrupt-controller3 {
   };
   sdr {
   };
   cpr {
   };
   l2c {
   };
   plb {
   };
};
=> fdt list /chosen
chosen {
   bootargs = "root=/dev/ram rw ip=192.168.100.6:192.168.1.1:192.168.1.254:255.255.0.0:canyonlands:eth0:off panic=1 console=ttyS0,115200";
};
=>

Note: fdt boardsetup performs board-specific blob updates, most commonly setting clock frequencies, etc. Discovering its operation is left as an excercise for the reader.

5.9.6. Environment Variables Commands 1. Abstract 5.9.8. Special Commands
Prev Home Next