這篇會介紹一下Device Tree的基本資料型態,並透過觀察/sys/firmware/devicetree/讓你更貼近一下DT的資料結構,下面範例是在vexpress-v2p-ca9.dts中include "brook.dtsi",然後在"brook.dtsi"撰寫DT的基本語法。DT的每個node,可包含零個以上的properties或child node。
brook@vista:~/qemu/linux-arm$ vim arch/arm/boot/dts/vexpress-v2p-ca9.dts #include "vexpress-v2m.dtsi" #include "brook.dtsi" /* add this line */ brook@vista:~/qemu/linux-arm$ vim arch/arm/boot/dts/brook.dtsi / { node1 { a-string-property = "A string"; a-string-list-property = "first string", "second string"; // hex is implied in byte arrays. no '0x' prefix is required a-byte-data-property = [01 23 34 56]; child-node1 { first-child-property; second-child-property = <1>; a-string-property = "Hello, world"; }; child-node2 { }; }; node2 { an-empty-property; a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */ //[@ brook@vista:~/qemu/linux-arm$ export ARCH=arm brook@vista:~/qemu/linux-arm$ export CROSS_COMPILE=arm-linux-gnueabihf- brook@vista:~/qemu/linux-arm$ export PATH=/opt/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin:$PATH brook@vista:~/qemu/linux-arm$ make dtbs], // is a simple ascii string and can be up to 31 characters in length. child-node@1 { }; child-node@2 { }; }; };
properties的value可以是empty或是以下資料型態:
- Text strings (null terminated) are represented with double quotes: string-property = "a string";
- 'Cells' are 32 bit unsigned integers delimited by angle brackets: cell-property = <0xbeef 123 0xabcd1234>;
- Binary data is delimited with square brackets: binary-property = [0x01 0x23 0x45 0x67];
- Data of differing representations can be concatenated together using a comma: mixed-property = "a string", [0x01 0x23 0x45 0x67], <0x12345678>;
- Commas are also used to create lists of strings: string-list = "red fish", "blue fish";
brook@vista:~/qemu/linux-arm# cd .. brook@vista:~/qemu$ qemu-system-arm -M vexpress-a9 -m 512M -kernel ./linux-arm/arch/arm/boot/zImage -dtb ./linux-arm/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -initrd ./initrd-arm.img -nographic -append "console=ttyAMA0" ----- boot to VM ----- Please press Enter to activate this console. / # ls /sys/firmware/ devicetree fdt / # ls /sys/firmware/devicetree/ base / # ls /sys/firmware/devicetree/base/ #根目錄(/sys/firmware/devicetree/base/) 多了node1與node2 / # ls /sys/firmware/devicetree/base/ #address-cells model #size-cells name aliases node1 arm,hbi node2 arm,vexpress,site pmu cache-controller@1e00a000 reserved-memory chosen scu@1e000000 clcd@10020000 smb@4000000 compatible timer@100e4000 cpus timer@1e000600 dcc virtio_mmio@10013000 hsb@e0000000 virtio_mmio@10013200 interrupt-controller@1e001000 virtio_mmio@10013400 interrupt-parent virtio_mmio@10013600 memory-controller@100e0000 watchdog@100e5000 memory-controller@100e1000 watchdog@1e000620 memory@60000000 / # find /sys/firmware/devicetree/base/node1 /sys/firmware/devicetree/base/node1 /sys/firmware/devicetree/base/node1/child-node2 /sys/firmware/devicetree/base/node1/child-node2/name /sys/firmware/devicetree/base/node1/a-string-property /sys/firmware/devicetree/base/node1/a-string-list-property /sys/firmware/devicetree/base/node1/a-byte-data-property /sys/firmware/devicetree/base/node1/name /sys/firmware/devicetree/base/node1/child-node1 /sys/firmware/devicetree/base/node1/child-node1/first-child-property /sys/firmware/devicetree/base/node1/child-node1/second-child-property /sys/firmware/devicetree/base/node1/child-node1/a-string-property /sys/firmware/devicetree/base/node1/child-node1/name / # find /sys/firmware/devicetree/base/node2 /sys/firmware/devicetree/base/node2 /sys/firmware/devicetree/base/node2/child-node@1 /sys/firmware/devicetree/base/node2/child-node@1/name /sys/firmware/devicetree/base/node2/child-node@2 /sys/firmware/devicetree/base/node2/child-node@2/name /sys/firmware/devicetree/base/node2/a-cell-property /sys/firmware/devicetree/base/node2/name /sys/firmware/devicetree/base/node2/an-empty-property / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/a-string-property 41 20 73 74 72 69 6E 67 A string 00 / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/a-string-list-property 66 69 72 73 74 20 73 74 first st 72 69 6E 67 00 73 65 63 ringsec 6F 6E 64 20 73 74 72 69 ond stri 6E 67 00 ng strings lists中的element是"0"分隔 / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/a-byte-data-property 01 23 34 56 #4V byte-data如其名,每個值大小就是一個byte / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/name 6E 6F 64 65 31 00 node1 / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/child-node1/first-child-property empty / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/child-node1/second-child-property 00 00 00 01 / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node1/child-node1/a-string-property 48 65 6C 6C 6F 2C 20 77 Hello, w 6F 72 6C 64 00 orld / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node2/a-cell-property 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 cell每個value大小為32byte / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node2/child-node@1/name 63 68 69 6C 64 2D 6E 6F child-no 64 65 00 de / # hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' /sys/firmware/devicetree/base/node2/child-node@2/name 63 68 69 6C 64 2D 6E 6F child-no 64 65 00 de
-
參考資料:
- https://elinux.org/Device_Tree_Usage, Device Tree Usage
- https://elinux.org/images/f/f9/Petazzoni-device-tree-dummies_0.pdf, device tree dumies
- https://blog.csdn.net/RadianceBlau/article/details/70800076, Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)