Trees need care a solution to Device Tree validation problem April 30, 2014 Embedded Linux Conference San Jose, CA Tomasz Figa Linux Kernel Developer Samsung R&D Institute Poland
Overview 1. Device Tree recap 2. Device Tree data flow 3. What’s wrong? 4. Problem analysis 5. History of work 6. Solution proposal 7. What’s next? 8. Q&A
A quick recap. Device Tree
Device Tree Root node / Nodes Bus Device Device Sub-nodes Device Device Device Properties Interrupt MMIO GPIO Clock Data structure for describing hardware Needed to tell the OS about devices that cannot be detected automatically Tree-like structure correllated with hardware topology 4
Device Tree Describes resources needed by devices Represents relations between devices Passed to kernel at boot Replaces hard-coded platform details in the OS 5
Device Tree Terminology: Property: a key-value pair; key – property name, value – arbitrary data. Node: a set of properties and/or child nodes. Bindings: a description how a device is described using device tree; a list of properties and nodes (and their formats) necessary to describe a device. 6
Device Tree Widely adopted SPARC, PowerPC, ARM, MIPS, C6x, Metag, OpenRISC, Xtensa, Microblaze, ARC Even x86 ;-) More than 600 in-tree board device tree source files* More than 4000 compatible strings defined* *As of Linux 3.14 7
Device Tree 1000 900 800 700 600 500 Initial DT support on ARM 400 300 200 100 0 Number of *.dts* files Number of documentation files
What’s happening to our trees? Device Tree data flow
Device Tree data flow [...] [...] cpus cpus { #address address-cells cells = = <1> <1>; #size size-cells cells = = <0> <0>; cpu@0 { cpu@0 { device_type device_type = = "cpu cpu"; Device Tree Source (DTS) compatible compatible = = "arm,arm1176jzf "arm,arm1176jzf-s", "arm,arm1176" s", "arm,arm1176"; reg reg = = <0x0> <0x0>; }; }; }; }; Plain text soc soc: soc soc { compatible = compatible = "simple simple-bus bus"; #address address-cells cells = = <1> <1>; Human-readable #size size-cells cells = = <1> <1>; ranges ranges; Developer- and GIT-friendly vic0: vic0: interrupt interrupt-controller@71200000 { controller@71200000 { compatible compatible = = "arm,pl192 "arm,pl192-vic" vic"; interrupt interrupt-controller controller; reg reg = = <0x71200000 0x1000> <0x71200000 0x1000>; #interrupt interrupt-cells cells = = <1> <1>; }; }; vic1: vic1: interrupt interrupt-controller@71300000 { controller@71300000 { compatible compatible = = "arm,pl192 "arm,pl192-vic" vic"; interrupt interrupt-controller controller; reg = reg = <0x71300000 0x1000> <0x71300000 0x1000>; #interrupt interrupt-cells cells = = <1> <1>; }; }; sdhci0: sdhci0: sdhci@7c200000 { sdhci@7c200000 { compatible = compatible = "samsung,s3c6410 "samsung,s3c6410-sdhci" sdhci"; reg reg = = <0x7c200000 0x100> <0x7c200000 0x100>; interrupt-parent interrupt parent = = <&vic1 &vic1>; interrupts interrupts = = <24 <24>; }; }; [...] [...] 10
Device Tree data flow 00000000 d0 0d fe ed ed 00 00 03 a1 00 00 00 38 00 00 03 14 |...........8....| 00000010 00 00 00 28 00 00 00 11 00 00 00 10 00 00 00 00 |...(............| 00000020 00 00 00 8d 00 00 02 dc 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 |................| 00000040 00 00 00 03 00 00 00 04 00 00 00 00 00 00 00 01 |................| 00000050 00 00 00 03 00 00 00 04 00 00 00 0f 00 00 00 01 |................| 00000060 00 00 00 01 63 68 6f 73 65 6e 00 00 00 00 00 02 |....chosen......| 00000070 00 00 00 01 61 6c 69 61 73 65 73 00 00 00 00 02 |....aliases.....| 00000080 00 00 00 01 6d 65 6d 6f 72 79 00 00 00 00 00 03 |....memory......| Device Tree Blob (DTB) 00000090 00 00 00 07 00 00 00 1b 6d 65 6d 6f 72 79 00 00 |........memory..| ..| 000000a0 00 00 00 03 00 00 00 08 00 00 00 27 00 00 00 00 |...........'....| 000000b0 00 00 00 00 00 00 00 02 00 00 00 01 63 70 75 73 |............cpus| 000000c0 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 00 |................| Binary representation called 000000d0 00 00 00 01 00 00 00 03 00 00 00 04 00 00 00 0f |................| 000000e0 00 00 00 00 00 00 00 01 63 70 75 40 30 00 00 00 |........cpu@0...| Flattened Device Tree (FDT) 000000f0 00 00 00 03 00 00 00 04 00 00 00 1b 63 70 75 00 |............cpu.| .| 00000100 00 00 00 03 00 00 00 1d 00 00 00 2b 61 72 6d 2c |...........+arm,| ,| 00000110 61 72 6d 31 31 37 36 6a 7a 66 2d 73 00 61 72 6d |arm1176jzf-s.arm| 00000120 2c 61 72 6d 31 31 37 36 00 00 00 00 00 00 00 03 |,arm1176........| Machine-readable 00000130 00 00 00 04 00 00 00 27 00 00 00 00 00 00 00 02 |.......'........| 00000140 00 00 00 02 00 00 00 01 73 6f 63 00 00 00 00 03 |........soc soc.....| 00000150 00 00 00 0b 00 00 00 2b 73 69 6d 70 6c 65 2d 62 |.......+simple-b| b| 00000160 75 73 00 00 00 00 00 03 00 00 00 04 00 00 00 00 |us us..............| CPU-friendly 00000170 00 00 00 01 00 00 00 03 00 00 00 04 00 00 00 0f |................| 00000180 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 36 |...............6| 00000190 00 00 00 01 69 6e 74 65 72 72 75 70 74 2d 63 6f |....interrupt-co| co| 000001a0 6e 74 72 6f 6c 6c 6c 65 72 40 37 31 32 30 30 30 30 |ntroller@7120000| 000001b0 30 00 00 00 00 00 00 03 00 00 00 0e 00 00 00 2b |0..............+| 000001c0 61 72 6d 2c 70 6c 31 39 32 2d 76 69 63 00 00 00 |arm,pl192-vic...| 000001d0 00 00 00 03 00 00 00 00 00 00 00 3d 00 00 00 03 |...........=....| 000001e0 00 00 00 08 00 00 00 27 71 20 00 00 00 00 10 00 |.......'q ......| 000001f0 00 00 00 03 00 00 00 04 00 00 00 52 00 00 00 01 |...........R....| 00000200 00 00 00 02 00 00 00 01 69 6e 74 65 72 72 75 70 |........interrup| 00000210 74 2d 63 6f 6e 74 72 6f 6c 6c 6c 65 72 40 37 31 33 |t-controller@713| 00000220 30 30 30 30 30 00 00 00 00 00 00 03 00 00 00 0e |00000...........| 00000230 00 00 00 2b 61 72 6d 2c 70 6c 31 39 32 2d 76 69 |...+arm,pl192-vi| vi| 00000240 63 00 00 00 00 00 00 03 00 00 00 00 00 00 00 3d |c..............=| 00000250 00 00 00 03 00 00 00 08 00 00 00 27 71 30 00 00 |...........'q0..| 00000260 00 00 10 00 00 00 00 03 00 00 00 04 00 00 00 52 |...............R| 00000270 00 00 00 01 00 00 00 03 00 00 00 04 00 00 00 63 |...............c| 00000280 00 00 00 01 00 00 00 03 00 00 00 04 00 00 00 69 |...............i| 00000290 00 00 00 01 00 00 00 02 00 00 00 01 73 64 68 63 |............sdhc| 000002a0 69 40 37 63 32 30 30 30 30 30 00 00 00 00 00 03 |i@7c200000......| 11
Device Tree data flow Device Tree Compiler (DTC) [1] Translates between various DT representations Usually DTS -> DTB Contains simple DTS parser built with Flex+Bison [1] DTC GIT repo at kernel.org
A story of a failure. What’s wrong?
What’s wrong? DTC translates data directly from one representation to another Every node/property reaches output file Almost no checks performed on input data Let’s see... 14
What’s wrong? sample.dts (part of arch/arm/boot/dts/s3c64xx.dtsi) [...] [...] vic0: vic0: interrupt-controller@71200000 { compatib compatible le = = "arm,pl192-vic" vic"; interrup interrupt-controlller; reg reg = = <0x71200000 0x1000>; #interrupt-cells = = <1> <1>; }; }; vic1: vic1: interrupt-controller@71300000 { compatib compatible le = = "arm,pl192-vic" vic"; interrupt-controller; interrup reg reg = = <0x71300000 0x1000>; #interrupt-calls = = <1> <1>; }; }; sdhci0: sdhci@7c200000 { sdhci0: compatible compatib le = = "samsung, samsung,s3c641 s3c6410-sdhci sdhci"; reg = reg = <0x7c200000 0x100>; interrup interrupt-parent = = <&vic1>; interrup interrupts ts = = <24 0> 24 0>; [...] [...] How many errors can you spot in this snippet? 15
What’s wrong? sample.dts (part of arch/arm/boot/dts/s3c64xx.dtsi) [...] [...] vic0: vic0: interrupt-controller@71200000 { compatible compatib le = = "arm,pl192-vic" vic"; interrup interrupt-controlller; reg = reg = <0x71200000 0x1000>; #interrupt-cells = = <1> <1>; }; }; vic1: vic1: interrupt-controller@71300000 { compatib compatible le = = "arm,pl192-vic" vic"; interrupt-controller; interrup reg reg = = <0x71300000 0x1000>; #interrupt-calls = = <1> <1>; }; }; sdhci0: sdhci0: sdhci@7c200000 { compatible compatib le = = "samsung, samsung,s3c641 s3c6410-sdhci sdhci"; reg reg = = <0x7c200000 0x100>; interrupt-parent = interrup = <&vic1>; interrup interrupts ts = = <24 0> 24 0>; [...] [...] And the answer is … 16
What’s wrong? t.f .fig iga@A @AMD MDC1 C1227 27 ~/ ~/ker ernel el $ $ scripts/dtc/dtc -O dtb -o sample.dtb arch/arm/boot/dts/sample.dts t.f .fig iga@A @AMD MDC1 C1227 27 ~/ ~/ker ernel el $ $ ls -l sample.dtb -rw-r--r-- 1 t.figa t.figa 929 04-21 14:21 sample.dtb t.f .fig iga@A @AMD MDC1 C1227 27 ~/ ~/ker ernel el $ Hmm... Zero? 17
Getting back on the right track. Device Tree validation
Recommend
More recommend