Linux device tree binaries are built from source code using the device tree compiler.  The source code usually has a ‘.dts‘ or ‘.dtsi’ extension depending on if the file is intended to be compiled directly, or included by another device tree file.  The resulting binaries usually have a ‘.dtb’ extension.  The standard tools used to compile a device tree are gcc and the device tree compiler, dtc.  The gcc compiler is used to pre-process the source files.  The main purpose of this step is to combine the top-level device tree source (‘.dts’ file) with all of the includes into a single source file.  It also replaces any use of C ‘#define’ symbols with their value, which is required by dtc.

The following example command will pre-process a device tree source file (myboard.dts) to a pre-processed source file (myboard.dts.pp):

> gcc -E -x assembler-with-cpp -undef -I$LINUX_DIR/include -o myboard.dts.pp myboard.dts

In this example, ‘-E’ tells gcc to only do pre-processing.  The option ‘-x assembler-with-cpp’ tells gcc how to interpret the source code.  This is required because the source file has a non-standard file extension.  The ‘-undef’ option prevents defining some symbols that might interfere.  The -I option brings in standard Linux device tree includes.  The symbols defined in these includes can be used in device tree source files to make them more readable and to make sure they are compatible with the device drivers they represent.

After the pre-processed source file is generated, it can be compiled into a device tree binary using the device tree compiler.  The following example command shows how to do this:

> dtc -O dtb -o myboard.dtb myboard.dts.pp

This generates the ‘.dtb’ file that can be used by the bootloader on an embedded system.  When debugging device trees, it is sometimes useful to de-compile the binaries to see exactly what’s in them.  The following example command shows how to do this:

> dtc -I dtb -O dts -o myboard.decompile.dts myboard.dtb