1@page page_device_dtc Devicetree Compiler 2 3# Introduction to the DTC 4 5Device Tree Compiler, dtc, takes as input a device-tree in a given format and outputs a device-tree in another format for booting kernels on embedded systems. 6Typically, the input format is "dts" (device-tree source), a human readable source format, and creates a "dtb" (device-tree binary), or binary format as output. 7 8> If the dtc tool is not installed on your host system, the dtc module will guide you through the installation. 9 10## Generate DTS 11 12When you have a DTB or FDT file from firmware or another runtime system, you might want to convert it into a DTS file for easier reading. 13You can do this in Python or your SConscript file. For example, assuming you have `dummpy.dtb`: 14 15```python 16import os, sys 17 18RTT_ROOT = os.getenv('RTT_ROOT') 19sys.path.append(RTT_ROOT + '/tools') 20 21from building import * 22import dtc 23 24dtc.dtb_to_dts(RTT_ROOT, "dummpy.dtb") 25``` 26 27This will generate a dummpy.dts in the current directory. If a file with the same name already exists, it will be replaced. 28To avoid overwriting, you can specify a different output name: 29 30```python 31[...] 32 33dtc.dtb_to_dts(RTT_ROOT, "dummpy.dtb", "dummpy-tmp.dts") 34# or 35dtc.dtb_to_dts(RTT_ROOT, "dummpy.dtb", dts_name = "dummpy-tmp.dts") 36``` 37 38## Generate DTB 39 40Before generating a DTB, you may want to review the basics of DTS syntax and structure: [DeviceTree Specification](https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html) 41 42### Include and Macros 43 44By default, dtc does not support C-style preprocessing (like cpp), but you can use the C preprocessor with your DTS files. 45Don't worry — our dtc module already includes this step. 46 47If your DTS file uses dt-bindings headers or macros, you can write something like: 48 49```c 50/* 51 * Used "#include" if header file need preprocessor, 52 * `components/drivers/include` and current directory path is default. 53 */ 54#include <dt-bindings/size.h> 55#include "dummy.dtsi" 56/* Well, if dtsi is simple, you can use "/include/", it is supported by dtc */ 57/include/ "chosen.dtsi" 58 59#define MMIO_BASE 0x10000 60#define MMIO_SIZE SIZE_GB 61#define MEM_BASE (MMIO_BASE + MMIO_SIZE) 62 63#ifndef CPU_HARDID 64#define CPU_HARDID 0 65#endif 66 67#ifndef SOC_INTC 68#define SOC_INTC intc_a 69#endif 70 71/ { 72 #address-cells = <2>; 73 #size-cells = <2>; 74 /* 75 * Macros after "&" will be replaced, 76 * there will affect the interrupt controller in this SoC. 77 */ 78 interrupt-parent = <&SOC_INTC>; 79 80 [...] 81 82 memory { 83 /* When there is a calculation, please use "()" to include them */ 84 reg = <0x0 MEM_BASE 0x0 (3 * SIZE_GB)>; 85 device_type = "memory"; 86 }; 87 88 cpus { 89 #size-cells = <0>; 90 #address-cells = <1>; 91 92 /* Macros after "@" will be replaced */ 93 cpu0: cpu@CPU_HARDID { 94 reg = <CPU_HARDID>; 95 device_type = "cpu"; 96 }; 97 }; 98 99 /* Macros replace support phandle name, too */ 100 intc_a: intc-a { 101 interrupt-controller; 102 }; 103 104 intc_b: intc-b { 105 interrupt-controller; 106 }; 107 108 [...] 109}; 110``` 111 112To generate the DTB: 113 114```python 115import os, sys 116 117RTT_ROOT = os.getenv('RTT_ROOT') 118sys.path.append(RTT_ROOT + '/tools') 119 120from building import * 121import dtc 122 123dtc.dts_to_dtb(RTT_ROOT, ["dummpy.dts"] 124``` 125 126To append more include paths, for example, SoC DM headers: 127 128```python 129[...] 130 131dtc.dts_to_dtb(RTT_ROOT, ["dummpy.dts"], include_paths = ['dm/include', 'firmware']) 132``` 133 134### Multiple DTB 135 136A single SoC may have different board variants. 137Example `dummy.dtsi` (common base): 138 139```c 140/* SoC dummy */ 141/ { 142 #address-cells = <2>; 143 #size-cells = <2>; 144 model = "Dummy SoC Board"; 145 146 [...] 147 148 chosen { 149 bootargs = "cma=8M coherent_pool=2M"; 150 }; 151 152 reserved-memory { 153 #address-cells = <2>; 154 #size-cells = <2>; 155 156 isp_shm@100000 { 157 reg = <0x0 0x100000 0x0 0x100000>; 158 }; 159 160 dsp_shm@200000 { 161 reg = <0x0 0x200000 0x0 0x100000>; 162 }; 163 }; 164 165 dsp { 166 status = "okay"; 167 }; 168 169 buddy { 170 isp = <&{/reserved-memory/isp_shm@100000}>; 171 dsp = <&{/reserved-memory/dsp_shm@200000}>; 172 }; 173 174 uart0: uart { 175 status = "disabled"; 176 }; 177 178 i2c0: i2c { 179 status = "okay"; 180 }; 181 182 [...] 183}; 184``` 185 186For a vendor-specific variant (Vendor A): 187 188```c 189/* vendorA dummy */ 190#include "dummy.dtsi" 191 192/ { 193 /* No phandle name can modify in place */ 194 chosen { 195 bootargs = "console=uart0 cma=8M coherent_pool=2M"; 196 }; 197}; 198 199/* Reference and modify direct if has phandle name */ 200&uart0 { 201 status = "okay"; 202 pinctrl-0 = <&uart0_m1>; 203}; 204 205&i2c0 { 206 status = "disabled"; 207}; 208``` 209 210To remove nodes or properties (Vendor B): 211 212```c 213/* vendorB dummy */ 214#include "dummy.dtsi" 215 216/delete-node/ &dsp_shm; 217 218/ { 219 /* Delete in place if no phandle name */ 220 /delete-node/ dsp; 221 222 /* Delete property */ 223 buddy { 224 /delete-property/ dsp; 225 }; 226}; 227``` 228 229To add new devices (Vendor C): 230 231```c 232/* vendorC dummy */ 233#include "dummy.dtsi" 234 235&i2c0 { 236 rtc@0 { 237 clock-frequency = <32768>; 238 }; 239}; 240``` 241 242Build all DTBs together: 243 244```python 245[...] 246 247dtc.dts_to_dtb(RTT_ROOT, ["dummpy-vendorA.dts", "dummpy-vendorB.dts", "dummpy-vendorC.dts"]) 248``` 249 250This will produce `dummpy-vendorA.dtb`, `dummpy-vendorB.dtb`, and `dummpy-vendorC.dtb` 251 252## Warnings 253 254DTC may produce warnings that are irrelevant or noisy. 255To suppress specific warnings: 256 257```python 258[...] 259 260dtc.dts_to_dtb(RTT_ROOT, ["dummpy.dts"], ignore_warning = ["simple_bus_reg", "unit_address_vs_reg", "clocks_is_cell", "gpios_property"]) 261``` 262 263Make sure your DTS is valid! 264 265## Raw options 266 267DTC provides additional command-line options (see dtc --help). You can pass raw options like this: 268 269```python 270[...] 271 272dtc.dtb_to_dts(RTT_ROOT, "dummpy.dtb", options = "--quiet") 273dtc.dts_to_dtb(RTT_ROOT, ["dummpy.dts"], options = "--quiet") 274``` 275