Files
dtc-src-1.4.5/dtc-1.4.5/Documentation/dtc-paper.tex
svcmobrel-release 52ac9f9d32 Updating prebuilts and/or headers
dfac199a7539a404407098a2541b9482279f690d - dtc-1.4.5/GPL
688431c05a68fedfcb7a36fb482a952d75b05a75 - dtc-1.4.5/Makefile
a4555a920b020b1bb06ca45224d692c0094362c1 - dtc-1.4.5/fdtoverlay.c
81ec523838a03a9f6e95e6e6b4a57a0a2b81620a - dtc-1.4.5/.gitignore
d525dcaa04b47f205c8cb69936399691e89b1fbb - dtc-1.4.5/README
29d5b51f10d7874704f2faaf9741d793e973a8ba - dtc-1.4.5/fdtget.c
db29d7f8b36abb5ab1d3c0ff25a2e056cbb7471e - dtc-1.4.5/flattree.c
cab130d5213077509e3b7c88fb99c589945625f1 - dtc-1.4.5/fdtput.c
e6060b19e275bde4187546231ba289a486d987e9 - dtc-1.4.5/README.license
95a16c709f1da90f55607005158862d34bd777ca - dtc-1.4.5/data.c
01c714a2f40e85b39871ff83605edbf2078ffe57 - dtc-1.4.5/srcpos.c
3c3ab9789cf4a6bce3448e8fbfdc9f2df2bd2aff - dtc-1.4.5/treesource.c
aa5cc18bcc85135e1d2a053a9ee8a3c40fc6ae7b - dtc-1.4.5/dtdiff
ebfc1d387c8ae94200e421549e1a301add720c66 - dtc-1.4.5/dtc.c
ce3d01a2829cf142f32579b9b429c0a53fc27bdb - dtc-1.4.5/dtc-lexer.l
53a52ecbb1b16bf144144f68c5e681f9554ff862 - dtc-1.4.5/util.h
e565c2b61d5c44d608b35f52a321ea68ccc794b0 - dtc-1.4.5/dtc-parser.y
453c878d681e2e6bbfec2a0b522e7e05e2363056 - dtc-1.4.5/checks.c
a39cc082f177f5f833b7fbfa2a35f8ca88f41826 - dtc-1.4.5/Makefile.dtc
edc3f2659d0771955ddea5e11f6d4d8b73dbd85b - dtc-1.4.5/.travis.yml
0cb72d7f3aeaee1cb122bac3c9d4c2227725b8f0 - dtc-1.4.5/fstree.c
e5147ec0a4049d9551c81c703e5fd4d51db8f366 - dtc-1.4.5/Makefile.convert-dtsv0
5ea9fc651c441c3cd5a381092581ed691dc49d5d - dtc-1.4.5/fdtdump.c
ce99f6374471fc140add69b0c86f623b4fe23186 - dtc-1.4.5/util.c
597d528effbe428cb6bacc6d4a4d093644e3fbd4 - dtc-1.4.5/dtc.h
cc0e7e5a498451c733e735ed95db6c2591aaf868 - dtc-1.4.5/Makefile.utils
25ae5e897cd351320137faa6577f11cf585f32da - dtc-1.4.5/srcpos.h
c56abdacfd7fe1144c6e68e7b1d0465e66e1545b - dtc-1.4.5/TODO
2c9a841513149efc0f5234215752b58b1c93a0f6 - dtc-1.4.5/convert-dtsv0-lexer.l
2e76fbfb41b15c4a60f2479eb1657308d4a024e1 - dtc-1.4.5/livetree.c
23dae1b1e6d96cbf7557ceac42bfa1cf13936ad5 - dtc-1.4.5/libfdt/fdt_wip.c
cb6dd625a5f8e41e0a0312c2bed4ba2167e62750 - dtc-1.4.5/libfdt/fdt_ro.c
2eb4a858b80211c6b700414b37b3ba1d9558ace1 - dtc-1.4.5/libfdt/fdt.h
9a1e89e0a6ad35bb3463e3a3f87dd7626d918c20 - dtc-1.4.5/libfdt/fdt_overlay.c
ebadc1eeeb3e463427b13de190569c9ca3849c27 - dtc-1.4.5/libfdt/fdt_rw.c
cb09ff924d581148c98dce072ecdaee4c5f289cd - dtc-1.4.5/libfdt/fdt.c
09a844c8978591b0af11e81928b851d4599a40fa - dtc-1.4.5/libfdt/fdt_empty_tree.c
a288dd3281a869616871849278224af702129e47 - dtc-1.4.5/libfdt/libfdt_env.h
e1c374080fc1e9f2101102f8aeb356082fe370c8 - dtc-1.4.5/libfdt/fdt_strerror.c
e49c8031e598fa2956bb26367570d8c06745367f - dtc-1.4.5/libfdt/fdt_sw.c
9332862189cd63c6d7e7e80c6b67446181fdd4c4 - dtc-1.4.5/libfdt/libfdt_internal.h
b929dc832e5ad67a6027aa0fdb3d39868f10125e - dtc-1.4.5/libfdt/Makefile.libfdt
431fd6a95e97ff1fec779f086cf35833c2bc33dd - dtc-1.4.5/libfdt/fdt_addresses.c
31ae7f44847e5a4e4a207f182dbb80f8714ec510 - dtc-1.4.5/libfdt/version.lds
f88a9a1f847941e4e8d8cd75b8337251c2ac8a1b - dtc-1.4.5/libfdt/libfdt.h
96d83160ed4341696adae458a154984eec3c7dfc - dtc-1.4.5/libfdt/TODO
628865d7616d254cc4c7996d1e972842ad922d98 - dtc-1.4.5/scripts/kup-dtc
2a320e30ee21461af08bb76f4051052044441de8 - dtc-1.4.5/scripts/setlocalversion
5b6353ff199345f7dde7fd8dcaaf32441befef95 - dtc-1.4.5/tests/obsolete-chosen-interrupt-controller.dts
1a13a82806e74da0fe7e39587e6bb9d6323d0012 - dtc-1.4.5/tests/truncated_property.c
e04703bdbb788f6f519059006d11a04c66c2d4e9 - dtc-1.4.5/tests/nonexist-label-ref.dts
6fb4a06a4267d2efe200ba82a2516817c70e7338 - dtc-1.4.5/tests/boot-cpuid.c
7e60aa8d9e1d0fc859d83bb287b12c7884b51d54 - dtc-1.4.5/tests/minusone-phandle.dts
a92ee30ee224515ec9e74dd392d22f1c370583c1 - dtc-1.4.5/tests/test_tree1_wrong4.dts
17a04207b4941b17fd362cb2e4cd958e3e74ad91 - dtc-1.4.5/tests/test01.dts
b1ee15fb5ad66b865f12e6994c4c8cd8ff125d57 - dtc-1.4.5/tests/dtbs_equal_ordered.c
dc4372a1ce8bf6a8175133dbc747b8e5802ef767 - dtc-1.4.5/tests/bad-gpio.dts
e597380112f351dc1d96530824b4c9eab2130c8b - dtc-1.4.5/tests/mangle-layout.supp
1a1de5c063dff543882f638a0dc5801628364556 - dtc-1.4.5/tests/extra-terminating-null.c
db16441c4b330570a9ac83b0e0b006fcd74cc32b - dtc-1.4.5/tests/incbin.bin
e94ef627a9dbfae24ea5eaccc985ced1738ad96f - dtc-1.4.5/tests/test_tree1_wrong9.dts
b3d47e46906126d2e0277adb8c35e6fc22e6380e - dtc-1.4.5/tests/include8.dts
a2cd7d79b779d2adfe2ec0c6b2a87312287c7abe - dtc-1.4.5/tests/include5a.dts
3e3767ef8b845fa7cace62543fda1fb19dd59d9d - dtc-1.4.5/tests/include2.dts
45e3fa0098f1d154ea2c1b3b61e87853f63cc4c2 - dtc-1.4.5/tests/sw_tree1.supp
58a4885d5573e8f0153839633f0c27820b373359 - dtc-1.4.5/tests/.gitignore
8f42d8e919b03dc09cac7ab58b2f9a28c830c9f5 - dtc-1.4.5/tests/stringlist.dts
968572da053916799c6b292dbd7ae6aba6755eda - dtc-1.4.5/tests/stacked_overlay_bar.dts
5fe77cdfa90bb405ded8bf20f7c3ed796f40abd5 - dtc-1.4.5/tests/reuse-label5.dts
e7e02f700b8e537130b0bc7a5fd9459660f8060c - dtc-1.4.5/tests/subnode_offset.c
7eae2be2813b5dca217a4e56bf8fae289e35166b - dtc-1.4.5/tests/Makefile.tests
e2d500c1ce6a9cff11cfba7b3859ebbcbbc588f4 - dtc-1.4.5/tests/trees.S
d576360fbfe36cc1f2c8f8c879f9109ab7cf9001 - dtc-1.4.5/tests/overlay_bad_fixup_index_trailing.dts
0082526b79f4d6d567faa039b5bec0295b5ec40b - dtc-1.4.5/tests/incbin.c
0886327c6106fd381312af3ceca674a4101380e0 - dtc-1.4.5/tests/nonexist-node-ref2.dts
fd68ece161bb07980e8ab678c61e293439906e2e - dtc-1.4.5/tests/run_tests.sh
4d98a0b920d0a7d37426b858e02387b16f007d58 - dtc-1.4.5/tests/overlay_overlay.dts
99c9cab16ce9f3db83dab99f1798f0bee79f055c - dtc-1.4.5/tests/open_pack.supp
210a4bfe688816869d79d5e9ce31a0a757441921 - dtc-1.4.5/tests/embedded_nul.dts
67c6674e15b3157690e444af5b5bedbd987659e2 - dtc-1.4.5/tests/overlay.c
cfcd5acf194801ca0b01302bf1d64eabeca89f68 - dtc-1.4.5/tests/value-labels.c
e3accfdb6f94c8d1bebcca85d9a5b52db0333670 - dtc-1.4.5/tests/sw_tree1.c
17846cb1d5428c6b0736ebcf8c2426dce37b47cf - dtc-1.4.5/tests/tests.h
773742f1338a51bde4d17f50b8ce97aac353a4ce - dtc-1.4.5/tests/overlay_bad_fixup_bad_index.dts
2a3c7f084000959f1b8fb4c405c23baf507835eb - dtc-1.4.5/tests/subnode_iterate.dts
7d6aa332681677fa7ac56d3390d1790b24ecc67f - dtc-1.4.5/tests/del_node.c
50be2e1000a7f0e19b94276143ed086a3081d161 - dtc-1.4.5/tests/get_path.c
4d1ae34edf08284d07b15103276d9c2a90059528 - dtc-1.4.5/tests/property_iterate.dts
097641bc7cdb15643af0ce67afa53910b559fa71 - dtc-1.4.5/tests/test_tree1_wrong5.dts
b98faf87f6f8dc361fc5fb11938921027c08b84f - dtc-1.4.5/tests/overlay_bad_fixup.c
cc5da65a932ea3005fb828dd16adb4b6049c0503 - dtc-1.4.5/tests/reuse-label6.dts
0bbd9c00bbe4150c13eed944cb787cf1480ddb9a - dtc-1.4.5/tests/references.dts
09c7a2b43ab5861b597da0497506e5a1a6ea1a9c - dtc-1.4.5/tests/include6.dts
bdcecf87f4aeb28c666d1196253746415f459864 - dtc-1.4.5/tests/overlay_bad_fixup_path_empty_prop.dts
53d884493b1a91d6d94e2d9fef517f9edbbdb7ec - dtc-1.4.5/tests/test_kernel_dts
3f29e779d64b1fb3fe743c958473e6a37879e1d9 - dtc-1.4.5/tests/path_offset_aliases.c
bace86d14d5a88839dc38c67b7bfdb78a0cd30f7 - dtc-1.4.5/tests/overlay_overlay_manual_fixups.dts
e15294970cf6645789ecb2fa573f4cfcdfc18008 - dtc-1.4.5/tests/appendprop2.c
78c9a2794d6684c52e601e58a6348f808a667122 - dtc-1.4.5/tests/bad-interrupt-cells.dts
dc911a4dd77c234586d0abdfccb66d23b990279f - dtc-1.4.5/tests/test01.asm
c58561b0a7af860779d89d27ebd4fbcfe3dd9862 - dtc-1.4.5/tests/base01.asm
4c182e2cd290bbc9677007b2cc26d526525cea7e - dtc-1.4.5/tests/overlay_base_manual_symbols.dts
3d58b283fc73faeab28eddf460ba97a401469c8c - dtc-1.4.5/tests/nonexist-node-ref.dts
1450026fe5e5d5c0854803d9d90567e9999a7c94 - dtc-1.4.5/tests/getprop.c
ca049c8511a0081118bca5cc76d17a5214b6fe9a - dtc-1.4.5/tests/fdtput-runtest.sh
557bd08f0cb8a37abd7568e5857508b1dd861474 - dtc-1.4.5/tests/parent_offset.c
ff6959ed32b3495ef5766c03da4f312488bb3983 - dtc-1.4.5/tests/deps_inc1.dtsi
7856fa203be221173cb6bafca81bf394a4f355bd - dtc-1.4.5/tests/test_tree1_merge.dts
4e44e71434ff788af4781ee934c70331870458ca - dtc-1.4.5/tests/path-references.c
e000be7a8d461e4a76027d36cc9c4839fbc2d58d - dtc-1.4.5/tests/node_offset_by_phandle.c
8abd5ffeb21a0ebc6795240d73152acb2240f442 - dtc-1.4.5/tests/include5.dts
7895dc6b800832b032bc29c87e78b1c97408f605 - dtc-1.4.5/tests/search_paths.dts
d0d88754d30e63fedd93010747838960d98c915e - dtc-1.4.5/tests/dup-propname.dts
e03aa51b95a671a3f98cae0051cd3474b7c207dd - dtc-1.4.5/tests/test_tree1_wrong7.dts
56b55df15337c52aac7c0246a5d44b3e82b76c6f - dtc-1.4.5/tests/overlay_base.dts
0e209c69b49d699ee05d19ae1424ea08585b1b6b - dtc-1.4.5/tests/pylibfdt_tests.py
4548237d664096155c80836bb9f273adddf7b6d6 - dtc-1.4.5/tests/comments-cmp.dts
a9415e9554e16fc01e5978cea5881c7ef5ddee40 - dtc-1.4.5/tests/node_offset_by_prop_value.c
2b5cf055b95da40dfa61458471fe259db8e9d0ee - dtc-1.4.5/tests/extra-terminating-null.dts
6cf4266274b916b715ada14627a86b19435a202e - dtc-1.4.5/tests/subnode_iterate.c
95a8a947549e7daaea521605f6bd4613d006dd29 - dtc-1.4.5/tests/fdtget-runtest.sh
b71203a02d1cb91de3b063e87aab076fee50cb3f - dtc-1.4.5/tests/references.c
064610a3c824b272b84c94e2518ed42b09e598ff - dtc-1.4.5/tests/reuse-label4.dts
dfd7e528eefbe6be39865053c8d1787ab95faf81 - dtc-1.4.5/tests/add_subnode_with_nops.c
18a64c7d93e2dc77c78cca13d9d187a0a2ee5d83 - dtc-1.4.5/tests/del_property.c
825eaa2f39e18b03c44e4fc04869294fb955d56c - dtc-1.4.5/tests/dup-nodename.dts
a34a59272e4ded11d69fa1563608a7cf417efb53 - dtc-1.4.5/tests/addresses.dts
a9323cf5194c13e3c29af052c1a85286f9492fa4 - dtc-1.4.5/tests/overlay_bad_fixup_base.dtsi
d2e394c31434137df0d3989fb15cebeec2bed2e7 - dtc-1.4.5/tests/base01.stderr
c267915a9a6b62629b509d13990b19aac4ad44ca - dtc-1.4.5/tests/fdtoverlay-runtest.sh
6225480114e8a14d25c2bd170f55ed78529db893 - dtc-1.4.5/tests/bad-ncells.dts
1ea38bf20a653f9b757f98160739a90737c4ce00 - dtc-1.4.5/tests/reg-ranges-root.dts
03e8cf8533103cb87b399fef32a36514b64bdcbc - dtc-1.4.5/tests/dtbs_equal_unordered.c
c3bbd9a0eb2ce642a716955eab223cca11e427ac - dtc-1.4.5/tests/overlay_bad_fixup_empty.dts
a6f8e3450be51ce6cd2ec18fa592726889b616ee - dtc-1.4.5/tests/char_literal.dts
627781fdd8a4fc415142e12d0edd5f7ac92f8f14 - dtc-1.4.5/tests/check_path.c
c27562784d986c84137d4e2500b8b3e321d46a1b - dtc-1.4.5/tests/nopulate.c
238b692003697e0cc242d047971bb6a3af60b464 - dtc-1.4.5/tests/nul-in-line-info2.dts
48599e299578b9ca040e45ab220edbb397a55108 - dtc-1.4.5/tests/embedded_nul_equiv.dts
a577bd5b22f52302600164b952210ee0a69b86fe - dtc-1.4.5/tests/stringlist.c
606a0da173c3d23f841cf8f5184a867f3cc9b1f3 - dtc-1.4.5/tests/utilfdt_test.c
1171b227d4252d704d9a300c0cd5e85e244b55e9 - dtc-1.4.5/tests/include4.dts
6e38c669946d6d95d026f40d735e730ade3aa714 - dtc-1.4.5/tests/deps_inc2.dtsi
c31535957cc2cea57dab87317a0bbb7c5a107b0c - dtc-1.4.5/tests/label01.dts
944504b8f4474793305037eddf9dd13979265432 - dtc-1.4.5/tests/get_name.c
aadb873ed244256fb50ea64d1b25b7796ffcffca - dtc-1.4.5/tests/include7.dts
6ff537c825a6683b1e857eebd754a1cdfc18d75c - dtc-1.4.5/tests/phandle_format.c
4cdb0a0f5aeddf820d35d5f9154e4359325c3e2e - dtc-1.4.5/tests/reuse-label.dts
fdf6935c1ab9032dc683ecfff2cc21f0185370f4 - dtc-1.4.5/tests/bad-name-property.dts
b0a1a56999d7db375e2e52055cbcf8f60ebf7077 - dtc-1.4.5/tests/overlay_overlay_simple.dts
b6517c85f38b3175d84d2986922d1751c92d242e - dtc-1.4.5/tests/appendprop.dts
e7e1445b585cd04a7992a66c346374f9c97a1188 - dtc-1.4.5/tests/bad-reg-ranges.dts
b5a2155cb7a8d9094f7de6f7bb16442abaf42436 - dtc-1.4.5/tests/unit-addr-leading-0s.dts
05057f2e73c3d8a5c9dfea99ccfe6553cafcbf74 - dtc-1.4.5/tests/bad-string-props.dts
27ac33471f9f470dd15959f1b43a58582b763298 - dtc-1.4.5/tests/root_node.c
8f1d286da170262b3ac2e705c175bd6cf1af14cd - dtc-1.4.5/tests/multilabel.dts
df629984df17b68032f9e61a688865fe5ec52798 - dtc-1.4.5/tests/move_and_save.c
59f8b8532a360f30d639aee56ecf821d8810c39e - dtc-1.4.5/tests/empty.dts
587400ca7d9a39476a5162859da7d21f9e816d64 - dtc-1.4.5/tests/testdata.h
399a348f311be369f68220b3732fcefde0f740f1 - dtc-1.4.5/tests/test_tree1.dts
94e0a5da6d15f081a21a2a5d02bbf45c3f85b62b - dtc-1.4.5/tests/supernode_atdepth_offset.c
c5deddb0fb0cd547da34fcaf924bdbe303b17492 - dtc-1.4.5/tests/test_tree1_wrong2.dts
49599b99ec6deb90718c05cb56711f1072ef623a - dtc-1.4.5/tests/reg-without-unit-addr.dts
6e6a7ec861bd63506d082a793bda483f8540be5b - dtc-1.4.5/tests/open_pack.c
08a95e2c1ce9ff35b2b6d9bad6a31bda3d2dadb4 - dtc-1.4.5/tests/overlay_bad_fixup_empty_index.dts
29a54f5c1c352e672dd7742b342629f356e5df6e - dtc-1.4.5/tests/zero-phandle.dts
8b046ab9a11a0c3a6780cf09cc82b5a6c5cec5c9 - dtc-1.4.5/tests/overlay_bad_fixup_path_prop.dts
9bc91516a068a176123a69777f41ad435c82933f - dtc-1.4.5/tests/string_escapes.c
c33c776418f1a2f4206f32680137822d6665eb89 - dtc-1.4.5/tests/mangle-layout.c
2e52702a5a474751f42991a4c68246a7c6356102 - dtc-1.4.5/tests/default-addr-size.dts
7c16967c713c20f58949e9a1d64dd14fcc0006a1 - dtc-1.4.5/tests/escapes.dts
265a369071203707125f015936d258f095f7db10 - dtc-1.4.5/tests/dtc-fatal.sh
da2bc0ecdecb507bfd11c951c3f0612834fcc922 - dtc-1.4.5/tests/nul-in-escape.dts
58bb1310303666817f190475c130e19a411a0c1f - dtc-1.4.5/tests/base01.dts
a1720d7f7d1c022c7e4f6717009a691693556aa1 - dtc-1.4.5/tests/find_property.c
03e96eb3ee1f650106cb90e06a4841681de15197 - dtc-1.4.5/tests/addr_size_cells.c
a748aadffd49ef78eeac7ad521a0d84aebcdbdbf - dtc-1.4.5/tests/dumptrees.c
f0eeb4b91084a61d9008a90d09b86425f4733c0c - dtc-1.4.5/tests/test01.stderr
8700502c294e949f908fa5c0c44248bd96af5ca6 - dtc-1.4.5/tests/dtc-fails.sh
9dcc1f85d0c8a1ce34c57d64c8e3fff4920f2df7 - dtc-1.4.5/tests/asm_tree_dump.c
1e8705f0eaec9950cd074b09b8463ede99a019b6 - dtc-1.4.5/tests/test_label_ref.dts
1ab3cfcd6d35f35618dc3d0b90a1b093a3467c1d - dtc-1.4.5/tests/division-by-zero.dts
06d3aebaaa4a26b6cb8fc1b3804fbef8d3ddd9ac - dtc-1.4.5/tests/line_directives.dts
9f00325b7377977b942eb0a1e01f978c806482f4 - dtc-1.4.5/tests/property_iterate.c
0181f2cb1a32b682733fa9db274226c7745c80cd - dtc-1.4.5/tests/test_tree1_delete.dts
bcc58605628d627ab670e8afe59d82916737e534 - dtc-1.4.5/tests/comments.dts
21e36b524a10b28810260a151e718818b79d87d1 - dtc-1.4.5/tests/sized_cells.c
3d6060bcbb5d4e369be0b5b518f0b80fd448faa0 - dtc-1.4.5/tests/setprop.c
82c9e391f5ba20d3b1c56ea7978a925f60481f18 - dtc-1.4.5/tests/overlay_overlay_no_fixups.dts
c825d82e7ed5fa8bdc4b0cd04cca5cc73a156709 - dtc-1.4.5/tests/bad-octal-literal.dts
444db827745be8840705a7cce26b024194624d15 - dtc-1.4.5/tests/incbin.dts
6ea01b148f3a82e51d775f9fadc37602ffe095ed - dtc-1.4.5/tests/testutils.c
026b4b16a20b6e79c02dba88f997f35d9562bb30 - dtc-1.4.5/tests/appendprop1.c
132e01eefa23f6a8c7b88c2a234b04c7d6529e4c - dtc-1.4.5/tests/unit-addr-without-reg.dts
9533807e3b9982017e411ba37f29dc322e691b68 - dtc-1.4.5/tests/unit-addr-leading-0x.dts
5286525de751b12c681101f6336d48533d904aa5 - dtc-1.4.5/tests/node_check_compatible.c
3f3316bfa1b4b2e718c30765c999b5a7075af3bd - dtc-1.4.5/tests/sized_cells.dts
09d871f55acf837e1467bde782781212dfecabc1 - dtc-1.4.5/tests/dependencies.dts
66f3655753343a0b87ff386da265bede08f99aee - dtc-1.4.5/tests/path_offset.c
f62430e11919a194daf565d6681a1df5fc6017f9 - dtc-1.4.5/tests/fdtdump-runtest.sh
c05d5b477def26d28273932ffc2bac34a91f4b8e - dtc-1.4.5/tests/propname_escapes.c
e6f56bdf21ace78b4e2150b088263c3ce7e1f1c9 - dtc-1.4.5/tests/test_tree1_merge_path.dts
c95ed15e2b3847366ecf12d1a7c8f4756ee745e6 - dtc-1.4.5/tests/delete_reinstate_multilabel_ref.dts
fd7d8b2bb9a288532134b0c82ee7fc3d7c983bfb - dtc-1.4.5/tests/dependencies.cmp
80911d8420ea3e794b86bd9c04aeae892eaad657 - dtc-1.4.5/tests/label_repeated.dts
3150edab60c72057f68b275f7f0bd2abeabf67de - dtc-1.4.5/tests/nop_property.c
1df4762532e24bf29f9cfaf82772fef9487683d2 - dtc-1.4.5/tests/search_paths_b.dts
52cf04b57ff7424ca1c57a12f5df19247940a3eb - dtc-1.4.5/tests/fdtdump.dts
332afd52254b8dbfaff4c7c1644d8c73cac2d855 - dtc-1.4.5/tests/stacked_overlay_baz.dts
02eef4caeaddab2f3722b86026ce2e1e434cde14 - dtc-1.4.5/tests/reuse-label1.dts
bdd28adcd03ea8a4c41a3e75de84a85c6938a044 - dtc-1.4.5/tests/dtc-checkfails.sh
53995be36144e22baca01a26b5c2113e5e9dea11 - dtc-1.4.5/tests/overlay_bad_fixup_path_only_sep.dts
6d74b16a531067c828acfdf118ecd5765f3168da - dtc-1.4.5/tests/node_offset_by_compatible.c
05a8ec0dae916212ba5e29c17ab63c766b8f6142 - dtc-1.4.5/tests/nop_node.c
badb0d8f62608674030ca278620b061f1d53f625 - dtc-1.4.5/tests/notfound.c
52ffd7a9b99beedbf46df87b18396daf91187d2d - dtc-1.4.5/tests/test_tree1_label_noderef.dts
ccecd5a83df37929613b6fdde5c88c3ecc8e84a8 - dtc-1.4.5/tests/include3.dts
78c91d2a0808bae30377b1dae9731c15725a972d - dtc-1.4.5/tests/prop-after-subnode.dts
42a972b76e039f30913fa708eb708901ed470c38 - dtc-1.4.5/tests/test_tree1_wrong8.dts
c7f82cecdd0ce4ca602890f2dd9d029d216deddf - dtc-1.4.5/tests/get_alias.c
771dc03d722d5c951a41f1fbab202f3f66f9a91e - dtc-1.4.5/tests/aliases.dts
2d816cf202120e151e9a4c10a11a68c4115f4f29 - dtc-1.4.5/tests/value-labels.dts
555bcf861816bdd82884301d1de455221cb1d288 - dtc-1.4.5/tests/data.S
c925cf6f789d4e7b879863a4414b3805a201cbae - dtc-1.4.5/tests/base01.cmd
03535626db5128f181593328582a7ef441776e2f - dtc-1.4.5/tests/sourceoutput.dts
a82abc5909ca25c13485da36752562db0acb1d3e - dtc-1.4.5/tests/get_mem_rsv.c
7b4ee02efa4d17433ba49c82dd2f30f1773c9d7a - dtc-1.4.5/tests/boot-cpuid.dts
55074ad8e933275058412606c278e1002a94b55a - dtc-1.4.5/tests/bad-size-cells.dts
fda3eb684c8ea2dae5845f23fd2f18ac8719d3e1 - dtc-1.4.5/tests/reuse-label3.dts
1187a7fb193ca9eb92ddbfb1500cf9ec7595a43a - dtc-1.4.5/tests/dtb_reverse.c
cd3ebe8d5c0e89669dc866b78d74611ec1d399cb - dtc-1.4.5/tests/reuse-label2.dts
fbaa8c4c9b156b24b74456bc8824f1aa6e777ec3 - dtc-1.4.5/tests/include1.dts
18a5eaaf67886b19caeec13d1f91fbac9dab40ea - dtc-1.4.5/tests/include0.dts
e220e5db0820592bd028adb9431401970522cd93 - dtc-1.4.5/tests/nul-in-line-info1.dts
9cb78df0d0f7fd73119b57ce7a171704631af5e4 - dtc-1.4.5/tests/delete_reinstate_multilabel.dts
ba55daa9627a9fa3af7ddbbb4c8e23b159fef96b - dtc-1.4.5/tests/char_literal.c
7997cfd671338152e5947ad6e3a7476b762f84b0 - dtc-1.4.5/tests/set_name.c
f7c3f569b0ef5a9c2ffe17656de222437bdcba78 - dtc-1.4.5/tests/overlay_bad_fixup_path_only.dts
738ebbc0f6e1fc9e4462d3b74081a83335be17aa - dtc-1.4.5/tests/bad-empty-ranges.dts
3a30897484d829884db97735b23fedec00d1df18 - dtc-1.4.5/tests/test_tree1_wrong3.dts
f3b0a0b0586f072ca642e33648ad6a8cc88f0ac9 - dtc-1.4.5/tests/setprop_inplace.c
549b82463e24ea3d3cbb8992cc21c8ea65686671 - dtc-1.4.5/tests/test_tree1_merge_labelled.dts
7ff38d835b0084e9a2fa409cd697a2e0d135ac19 - dtc-1.4.5/tests/tests.sh
86e03f6d539ccb33585658f93b9b53e89534719c - dtc-1.4.5/tests/path-references.dts
42c311ee4bcf10bd46c6894d5338d00b69a0a7e7 - dtc-1.4.5/tests/propname_escapes.dts
32913f10eab70e2a11e13a7d4a0f31aee903a53d - dtc-1.4.5/tests/test_tree1_wrong6.dts
d7da06091195ba54e6904bd46ccd5aeb5445c22a - dtc-1.4.5/tests/test_tree1_wrong1.dts
54b58cc0e02047df34ab21ff906ad4d8669521c8 - dtc-1.4.5/tests/bad-phandle-cells.dts
2c7f7bed3fa31d608e32095cc3469559a80376df - dtc-1.4.5/tests/multilabel_merge.dts
81c4b081a92462f90ffa24915b2cad76cb687f88 - dtc-1.4.5/tests/dup-phandle.dts
665f89ab83944d57bb09f3a18a1391280f446db3 - dtc-1.4.5/tests/rw_tree1.c
90fd6ea3d82dfc9cadd37a93e3a62fc72e6b336d - dtc-1.4.5/tests/integer-expressions.c
e8c561bde2558fb895f327e6e005c7af8818a1f5 - dtc-1.4.5/tests/stacked_overlay_base.dts
0ea1b9337b59fd9872199301ac37114c37a2a620 - dtc-1.4.5/tests/get_phandle.c
448994a1143852a9b1154db51a9db49d717d9c31 - dtc-1.4.5/tests/search_dir_b/search_test_c.dtsi
74d5e33802b093e2abd21b884a018223a853c93d - dtc-1.4.5/tests/search_dir_b/search_test_b.dtsi
60d17f79adc996b2b1ea979208cca39f6acf4145 - dtc-1.4.5/tests/search_dir_b/search_paths_subdir.dts
e3a9bc2e23703093aca0d62db5587a8c7da3e9a3 - dtc-1.4.5/tests/search_dir_b/search_test_b2.dtsi
a3efef7df14727a6a4e97a1a6c5c5dc70ee761d9 - dtc-1.4.5/tests/search_dir/search_test2.dtsi
2adb422636000206499201175d397a4e065118d1 - dtc-1.4.5/tests/search_dir/search_test.dtsi
cbaff71343d90c58f78fa1ee686fc0114bc88399 - dtc-1.4.5/pylibfdt/.gitignore
950f95518e818abf2c8f84f1074b6f7c67002a36 - dtc-1.4.5/pylibfdt/Makefile.pylibfdt
103f0f23a13380d020ea07587574e3c16a8812d2 - dtc-1.4.5/pylibfdt/setup.py
efd79993fabe982fc1c772d90d796f9ca3be096c - dtc-1.4.5/pylibfdt/libfdt.i
edcd4769af7d6adf1bd71db82c02b377a55a665f - dtc-1.4.5/Documentation/dtc-paper.tex
657ff4514367b424637b70b785eda2b5f527374c - dtc-1.4.5/Documentation/dtc-paper.bib

Change-Id: I5459677964991672faf7e102f27fbb01c89fbb33
2025-10-10 11:32:30 -07:00

598 lines
27 KiB
TeX

\documentclass[a4paper,twocolumn]{article}
\usepackage{abstract}
\usepackage{xspace}
\usepackage{amssymb}
\usepackage{latexsym}
\usepackage{tabularx}
\usepackage[T1]{fontenc}
\usepackage{calc}
\usepackage{listings}
\usepackage{color}
\usepackage{url}
\title{Device trees everywhere}
\author{David Gibson \texttt{<{dwg}{@}{au1.ibm.com}>}\\
Benjamin Herrenschmidt \texttt{<{benh}{@}{kernel.crashing.org}>}\\
\emph{OzLabs, IBM Linux Technology Center}}
\newcommand{\R}{\textsuperscript{\textregistered}\xspace}
\newcommand{\tm}{\textsuperscript{\texttrademark}\xspace}
\newcommand{\tge}{$\geqslant$}
%\newcommand{\ditto}{\textquotedbl\xspace}
\newcommand{\fixme}[1]{$\bigstar$\emph{\textbf{\large #1}}$\bigstar$\xspace}
\newcommand{\ppc}{\mbox{PowerPC}\xspace}
\newcommand{\of}{Open Firmware\xspace}
\newcommand{\benh}{Ben Herrenschmidt\xspace}
\newcommand{\kexec}{\texttt{kexec()}\xspace}
\newcommand{\dtbeginnode}{\texttt{OF\_DT\_BEGIN\_NODE\xspace}}
\newcommand{\dtendnode}{\texttt{OF\_DT\_END\_NODE\xspace}}
\newcommand{\dtprop}{\texttt{OF\_DT\_PROP\xspace}}
\newcommand{\dtend}{\texttt{OF\_DT\_END\xspace}}
\newcommand{\dtc}{\texttt{dtc}\xspace}
\newcommand{\phandle}{\texttt{linux,phandle}\xspace}
\begin{document}
\maketitle
\begin{abstract}
We present a method for booting a \ppc{}\R Linux\R kernel on an
embedded machine. To do this, we supply the kernel with a compact
flattened-tree representation of the system's hardware based on the
device tree supplied by Open Firmware on IBM\R servers and Apple\R
Power Macintosh\R machines.
The ``blob'' representing the device tree can be created using \dtc
--- the Device Tree Compiler --- that turns a simple text
representation of the tree into the compact representation used by
the kernel. The compiler can produce either a binary ``blob'' or an
assembler file ready to be built into a firmware or bootwrapper
image.
This flattened-tree approach is now the only supported method of
booting a \texttt{ppc64} kernel without Open Firmware, and we plan
to make it the only supported method for all \texttt{powerpc}
kernels in the future.
\end{abstract}
\section{Introduction}
\subsection{OF and the device tree}
Historically, ``everyday'' \ppc machines have booted with the help of
\of (OF), a firmware environment defined by IEEE1275 \cite{IEEE1275}.
Among other boot-time services, OF maintains a device tree that
describes all of the system's hardware devices and how they're
connected. During boot, before taking control of memory management,
the Linux kernel uses OF calls to scan the device tree and transfer it
to an internal representation that is used at run time to look up
various device information.
The device tree consists of nodes representing devices or
buses\footnote{Well, mostly. There are a few special exceptions.}.
Each node contains \emph{properties}, name--value pairs that give
information about the device. The values are arbitrary byte strings,
and for some properties, they contain tables or other structured
information.
\subsection{The bad old days}
Embedded systems, by contrast, usually have a minimal firmware that
might supply a few vital system parameters (size of RAM and the like),
but nothing as detailed or complete as the OF device tree. This has
meant that the various 32-bit \ppc embedded ports have required a
variety of hacks spread across the kernel to deal with the lack of
device tree. These vary from specialised boot wrappers to parse
parameters (which are at least reasonably localised) to
CONFIG-dependent hacks in drivers to override normal probe logic with
hardcoded addresses for a particular board. As well as being ugly of
itself, such CONFIG-dependent hacks make it hard to build a single
kernel image that supports multiple embedded machines.
Until relatively recently, the only 64-bit \ppc machines without OF
were legacy (pre-POWER5\R) iSeries\R machines. iSeries machines often
only have virtual IO devices, which makes it quite simple to work
around the lack of a device tree. Even so, the lack means the iSeries
boot sequence must be quite different from the pSeries or Macintosh,
which is not ideal.
The device tree also presents a problem for implementing \kexec. When
the kernel boots, it takes over full control of the system from OF,
even re-using OF's memory. So, when \kexec comes to boot another
kernel, OF is no longer around for the second kernel to query.
\section{The Flattened Tree}
In May 2005 \benh implemented a new approach to handling the device
tree that addresses all these problems. When booting on OF systems,
the first thing the kernel runs is a small piece of code in
\texttt{prom\_init.c}, which executes in the context of OF. This code
walks the device tree using OF calls, and transcribes it into a
compact, flattened format. The resulting device tree ``blob'' is then
passed to the kernel proper, which eventually unflattens the tree into
its runtime form. This blob is the only data communicated between the
\texttt{prom\_init.c} bootstrap and the rest of the kernel.
When OF isn't available, either because the machine doesn't have it at
all or because \kexec has been used, the kernel instead starts
directly from the entry point taking a flattened device tree. The
device tree blob must be passed in from outside, rather than generated
by part of the kernel from OF. For \kexec, the userland
\texttt{kexec} tools build the blob from the runtime device tree
before invoking the new kernel. For embedded systems the blob can
come either from the embedded bootloader, or from a specialised
version of the \texttt{zImage} wrapper for the system in question.
\subsection{Properties of the flattened tree}
The flattened tree format should be easy to handle, both for the
kernel that parses it and the bootloader that generates it. In
particular, the following properties are desirable:
\begin{itemize}
\item \emph{relocatable}: the bootloader or kernel should be able to
move the blob around as a whole, without needing to parse or adjust
its internals. In practice that means we must not use pointers
within the blob.
\item \emph{insert and delete}: sometimes the bootloader might want to
make tweaks to the flattened tree, such as deleting or inserting a
node (or whole subtree). It should be possible to do this without
having to effectively regenerate the whole flattened tree. In
practice this means limiting the use of internal offsets in the blob
that need recalculation if a section is inserted or removed with
\texttt{memmove()}.
\item \emph{compact}: embedded systems are frequently short of
resources, particularly RAM and flash memory space. Thus, the tree
representation should be kept as small as conveniently possible.
\end{itemize}
\subsection{Format of the device tree blob}
\label{sec:format}
\begin{figure}[htb!]
\centering
\footnotesize
\begin{tabular}{r|c|l}
\multicolumn{1}{r}{\textbf{Offset}}& \multicolumn{1}{c}{\textbf{Contents}} \\\cline{2-2}
\texttt{0x00} & \texttt{0xd00dfeed} & magic number \\\cline{2-2}
\texttt{0x04} & \emph{totalsize} \\\cline{2-2}
\texttt{0x08} & \emph{off\_struct} & \\\cline{2-2}
\texttt{0x0C} & \emph{off\_strs} & \\\cline{2-2}
\texttt{0x10} & \emph{off\_rsvmap} & \\\cline{2-2}
\texttt{0x14} & \emph{version} \\\cline{2-2}
\texttt{0x18} & \emph{last\_comp\_ver} & \\\cline{2-2}
\texttt{0x1C} & \emph{boot\_cpu\_id} & \tge v2 only\\\cline{2-2}
\texttt{0x20} & \emph{size\_strs} & \tge v3 only\\\cline{2-2}
\multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2}
\emph{off\_rsvmap} & \emph{address0} & memory reserve \\
+ \texttt{0x04} & ...& table \\\cline{2-2}
+ \texttt{0x08} & \emph{len0} & \\
+ \texttt{0x0C} & ...& \\\cline{2-2}
\vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2}
& \texttt{0x00000000}- & end marker\\
& \texttt{00000000} & \\\cline{2-2}
& \texttt{0x00000000}- & \\
& \texttt{00000000} & \\\cline{2-2}
\multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2}
\emph{off\_strs} & \texttt{'n' 'a' 'm' 'e'} & strings block \\
+ \texttt{0x04} & \texttt{~0~ 'm' 'o' 'd'} & \\
+ \texttt{0x08} & \texttt{'e' 'l' ~0~ \makebox[\widthof{~~~}]{\textrm{...}}} & \\
\vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2}
\multicolumn{1}{r}{+ \emph{size\_strs}} \\
\multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2}
\emph{off\_struct} & \dtbeginnode & structure block \\\cline{2-2}
+ \texttt{0x04} & \texttt{'/' ~0~ ~0~ ~0~} & root node\\\cline{2-2}
+ \texttt{0x08} & \dtprop & \\\cline{2-2}
+ \texttt{0x0C} & \texttt{0x00000005} & ``\texttt{model}''\\\cline{2-2}
+ \texttt{0x10} & \texttt{0x00000008} & \\\cline{2-2}
+ \texttt{0x14} & \texttt{'M' 'y' 'B' 'o'} & \\
+ \texttt{0x18} & \texttt{'a' 'r' 'd' ~0~} & \\\cline{2-2}
\vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2}
& \texttt{\dtendnode} \\\cline{2-2}
& \texttt{\dtend} \\\cline{2-2}
\multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2}
\multicolumn{1}{r}{\emph{totalsize}} \\
\end{tabular}
\caption{Device tree blob layout}
\label{fig:blob-layout}
\end{figure}
The format for the blob we devised, was first described on the
\texttt{linuxppc64-dev} mailing list in \cite{noof1}. The format has
since evolved through various revisions, and the current version is
included as part of the \dtc (see \S\ref{sec:dtc}) git tree,
\cite{dtcgit}.
Figure \ref{fig:blob-layout} shows the layout of the blob of data
containing the device tree. It has three sections of variable size:
the \emph{memory reserve table}, the \emph{structure block} and the
\emph{strings block}. A small header gives the blob's size and
version and the locations of the three sections, plus a handful of
vital parameters used during early boot.
The memory reserve map section gives a list of regions of memory that
the kernel must not use\footnote{Usually such ranges contain some data
structure initialised by the firmware that must be preserved by the
kernel.}. The list is represented as a simple array of (address,
size) pairs of 64 bit values, terminated by a zero size entry. The
strings block is similarly simple, consisting of a number of
null-terminated strings appended together, which are referenced from
the structure block as described below.
The structure block contains the device tree proper. Each node is
introduced with a 32-bit \dtbeginnode tag, followed by the node's name
as a null-terminated string, padded to a 32-bit boundary. Then
follows all of the properties of the node, each introduced with a
\dtprop tag, then all of the node's subnodes, each introduced with
their own \dtbeginnode tag. The node ends with an \dtendnode tag, and
after the \dtendnode for the root node is an \dtend tag, indicating
the end of the whole tree\footnote{This is redundant, but included for
ease of parsing.}. The structure block starts with the \dtbeginnode
introducing the description of the root node (named \texttt{/}).
Each property, after the \dtprop, has a 32-bit value giving an offset
from the beginning of the strings block at which the property name is
stored. Because it's common for many nodes to have properties with
the same name, this approach can substantially reduce the total size
of the blob. The name offset is followed by the length of the
property value (as a 32-bit value) and then the data itself padded to
a 32-bit boundary.
\subsection{Contents of the tree}
\label{sec:treecontents}
Having seen how to represent the device tree structure as a flattened
blob, what actually goes into the tree? The short answer is ``the
same as an OF tree''. On OF systems, the flattened tree is
transcribed directly from the OF device tree, so for simplicity we
also use OF conventions for the tree on other systems.
In many cases a flat tree can be simpler than a typical OF provided
device tree. The flattened tree need only provide those nodes and
properties that the kernel actually requires; the flattened tree
generally need not include devices that the kernel can probe itself.
For example, an OF device tree would normally include nodes for each
PCI device on the system. A flattened tree need only include nodes
for the PCI host bridges; the kernel will scan the buses thus
described to find the subsidiary devices. The device tree can include
nodes for devices where the kernel needs extra information, though:
for example, for ISA devices on a subsidiary PCI/ISA bridge, or for
devices with unusual interrupt routing.
Where they exist, we follow the IEEE1275 bindings that specify how to
describe various buses in the device tree (for example,
\cite{IEEE1275-pci} describe how to represent PCI devices). The
standard has not been updated for a long time, however, and lacks
bindings for many modern buses and devices. In particular, embedded
specific devices such as the various System-on-Chip buses are not
covered. We intend to create new bindings for such buses, in keeping
with the general conventions of IEEE1275 (a simple such binding for a
System-on-Chip bus was included in \cite{noof5} a revision of
\cite{noof1}).
One complication arises for representing ``phandles'' in the flattened
tree. In OF, each node in the tree has an associated phandle, a
32-bit integer that uniquely identifies the node\footnote{In practice
usually implemented as a pointer or offset within OF memory.}. This
handle is used by the various OF calls to query and traverse the tree.
Sometimes phandles are also used within the tree to refer to other
nodes in the tree. For example, devices that produce interrupts
generally have an \texttt{interrupt-parent} property giving the
phandle of the interrupt controller that handles interrupts from this
device. Parsing these and other interrupt related properties allows
the kernel to build a complete representation of the system's
interrupt tree, which can be quite different from the tree of bus
connections.
In the flattened tree, a node's phandle is represented by a special
\phandle property. When the kernel generates a flattened tree from
OF, it adds a \phandle property to each node, containing the phandle
retrieved from OF. When the tree is generated without OF, however,
only nodes that are actually referred to by phandle need to have this
property.
Another complication arises because nodes in an OF tree have two
names. First they have the ``unit name'', which is how the node is
referred to in an OF path. The unit name generally consists of a
device type followed by an \texttt{@} followed by a \emph{unit
address}. For example \texttt{/memory@0} is the full path of a memory
node at address 0, \texttt{/ht@0,f2000000/pci@1} is the path of a PCI
bus node, which is under a HyperTransport\tm bus node. The form of
the unit address is bus dependent, but is generally derived from the
node's \texttt{reg} property. In addition, nodes have a property,
\texttt{name}, whose value is usually equal to the first path of the
unit name. For example, the nodes in the previous example would have
\texttt{name} properties equal to \texttt{memory} and \texttt{pci},
respectively. To save space in the blob, the current version of the
flattened tree format only requires the unit names to be present.
When the kernel unflattens the tree, it automatically generates a
\texttt{name} property from the node's path name.
\section{The Device Tree Compiler}
\label{sec:dtc}
\begin{figure}[htb!]
\centering
\begin{lstlisting}[frame=single,basicstyle=\footnotesize\ttfamily,
tabsize=3,numbers=left,xleftmargin=2em]
/memreserve/ 0x20000000-0x21FFFFFF;
/ {
model = "MyBoard";
compatible = "MyBoardFamily";
#address-cells = <2>;
#size-cells = <2>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,970@0 {
device_type = "cpu";
reg = <0>;
clock-frequency = <5f5e1000>;
timebase-frequency = <1FCA055>;
linux,boot-cpu;
i-cache-size = <10000>;
d-cache-size = <8000>;
};
};
memory@0 {
device_type = "memory";
memreg: reg = <00000000 00000000
00000000 20000000>;
};
mpic@0x3fffdd08400 {
/* Interrupt controller */
/* ... */
};
pci@40000000000000 {
/* PCI host bridge */
/* ... */
};
chosen {
bootargs = "root=/dev/sda2";
linux,platform = <00000600>;
interrupt-controller =
< &/mpic@0x3fffdd08400 >;
};
};
\end{lstlisting}
\caption{Example \dtc source}
\label{fig:dts}
\end{figure}
As we've seen, the flattened device tree format provides a convenient
way of communicating device tree information to the kernel. It's
simple for the kernel to parse, and simple for bootloaders to
manipulate. On OF systems, it's easy to generate the flattened tree
by walking the OF maintained tree. However, for embedded systems, the
flattened tree must be generated from scratch.
Embedded bootloaders are generally built for a particular board. So,
it's usually possible to build the device tree blob at compile time
and include it in the bootloader image. For minor revisions of the
board, the bootloader can contain code to make the necessary tweaks to
the tree before passing it to the booted kernel.
The device trees for embedded boards are usually quite simple, and
it's possible to hand construct the necessary blob by hand, but doing
so is tedious. The ``device tree compiler'', \dtc{}\footnote{\dtc can
be obtained from \cite{dtcgit}.}, is designed to make creating device
tree blobs easier by converting a text representation of the tree
into the necessary blob.
\subsection{Input and output formats}
As well as the normal mode of compiling a device tree blob from text
source, \dtc can convert a device tree between a number of
representations. It can take its input in one of three different
formats:
\begin{itemize}
\item source, the normal case. The device tree is described in a text
form, described in \S\ref{sec:dts}.
\item blob (\texttt{dtb}), the flattened tree format described in
\S\ref{sec:format}. This mode is useful for checking a pre-existing
device tree blob.
\item filesystem (\texttt{fs}), input is a directory tree in the
layout of \texttt{/proc/device-tree} (roughly, a directory for each
node in the device tree, a file for each property). This is useful
for building a blob for the device tree in use by the currently
running kernel.
\end{itemize}
In addition, \dtc can output the tree in one of three different
formats:
\begin{itemize}
\item blob (\texttt{dtb}), as in \S\ref{sec:format}. The most
straightforward use of \dtc is to compile from ``source'' to
``blob'' format.
\item source (\texttt{dts}), as in \S\ref{sec:dts}. If used with blob
input, this allows \dtc to act as a ``decompiler''.
\item assembler source (\texttt{asm}). \dtc can produce an assembler
file, which will assemble into a \texttt{.o} file containing the
device tree blob, with symbols giving the beginning of the blob and
its various subsections. This can then be linked directly into a
bootloader or firmware image.
\end{itemize}
For maximum applicability, \dtc can both read and write any of the
existing revisions of the blob format. When reading, \dtc takes the
version from the blob header, and when writing it takes a command line
option specifying the desired version. It automatically makes any
necessary adjustments to the tree that are necessary for the specified
version. For example, formats before 0x10 require each node to have
an explicit \texttt{name} property. When \dtc creates such a blob, it
will automatically generate \texttt{name} properties from the unit
names.
\subsection{Source format}
\label{sec:dts}
The ``source'' format for \dtc is a text description of the device
tree in a vaguely C-like form. Figure \ref{fig:dts} shows an
example. The file starts with \texttt{/memreserve/} directives, which
gives address ranges to add to the output blob's memory reserve table,
then the device tree proper is described.
Nodes of the tree are introduced with the node name, followed by a
\texttt{\{} ... \texttt{\};} block containing the node's properties
and subnodes. Properties are given as just {\emph{name} \texttt{=}
\emph{value}\texttt{;}}. The property values can be given in any
of three forms:
\begin{itemize}
\item \emph{string} (for example, \texttt{"MyBoard"}). The property
value is the given string, including terminating NULL. C-style
escapes (\verb+\t+, \verb+\n+, \verb+\0+ and so forth) are allowed.
\item \emph{cells} (for example, \texttt{<0 8000 f0000000>}). The
property value is made up of a list of 32-bit ``cells'', each given
as a hex value.
\item \emph{bytestring} (for example, \texttt{[1234abcdef]}). The
property value is given as a hex bytestring.
\end{itemize}
Cell properties can also contain \emph{references}. Instead of a hex
number, the source can give an ampersand (\texttt{\&}) followed by the
full path to some node in the tree. For example, in Figure
\ref{fig:dts}, the \texttt{/chosen} node has an
\texttt{interrupt-controller} property referring to the interrupt
controller described by the node \texttt{/mpic@0x3fffdd08400}. In the
output tree, the value of the referenced node's phandle is included in
the property. If that node doesn't have an explicit phandle property,
\dtc will automatically create a unique phandle for it. This approach
makes it easy to create interrupt trees without having to explicitly
assign and remember phandles for the various interrupt controller
nodes.
The \dtc source can also include ``labels'', which are placed on a
particular node or property. For example, Figure \ref{fig:dts} has a
label ``\texttt{memreg}'' on the \texttt{reg} property of the node
\texttt{/memory@0}. When using assembler output, corresponding labels
in the output are generated, which will assemble into symbols
addressing the part of the blob with the node or property in question.
This is useful for the common case where an embedded board has an
essentially fixed device tree with a few variable properties, such as
the size of memory. The bootloader for such a board can have a device
tree linked in, including a symbol referring to the right place in the
blob to update the parameter with the correct value determined at
runtime.
\subsection{Tree checking}
Between reading in the device tree and writing it out in the new
format, \dtc performs a number of checks on the tree:
\begin{itemize}
\item \emph{syntactic structure}: \dtc checks that node and property
names contain only allowed characters and meet length restrictions.
It checks that a node does not have multiple properties or subnodes
with the same name.
\item \emph{semantic structure}: In some cases, \dtc checks that
properties whose contents are defined by convention have appropriate
values. For example, it checks that \texttt{reg} properties have a
length that makes sense given the address forms specified by the
\texttt{\#address-cells} and \texttt{\#size-cells} properties. It
checks that properties such as \texttt{interrupt-parent} contain a
valid phandle.
\item \emph{Linux requirements}: \dtc checks that the device tree
contains those nodes and properties that are required by the Linux
kernel to boot correctly.
\end{itemize}
These checks are useful to catch simple problems with the device tree,
rather than having to debug the results on an embedded kernel. With
the blob input mode, it can also be used for diagnosing problems with
an existing blob.
\section{Future Work}
\subsection{Board ports}
The flattened device tree has always been the only supported way to
boot a \texttt{ppc64} kernel on an embedded system. With the merge of
\texttt{ppc32} and \texttt{ppc64} code it has also become the only
supported way to boot any merged \texttt{powerpc} kernel, 32-bit or
64-bit. In fact, the old \texttt{ppc} architecture exists mainly just
to support the old ppc32 embedded ports that have not been migrated
to the flattened device tree approach. We plan to remove the
\texttt{ppc} architecture eventually, which will mean porting all the
various embedded boards to use the flattened device tree.
\subsection{\dtc features}
While it is already quite usable, there are a number of extra features
that \dtc could include to make creating device trees more convenient:
\begin{itemize}
\item \emph{better tree checking}: Although \dtc already performs a
number of checks on the device tree, they are rather haphazard. In
many cases \dtc will give up after detecting a minor error early and
won't pick up more interesting errors later on. There is a
\texttt{-f} parameter that forces \dtc to generate an output tree
even if there are errors. At present, this needs to be used more
often than one might hope, because \dtc is bad at deciding which
errors should really be fatal, and which rate mere warnings.
\item \emph{binary include}: Occasionally, it is useful for the device
tree to incorporate as a property a block of binary data for some
board-specific purpose. For example, many of Apple's device trees
incorporate bytecode drivers for certain platform devices. \dtc's
source format ought to allow this by letting a property's value be
read directly from a binary file.
\item \emph{macros}: it might be useful for \dtc to implement some
sort of macros so that a tree containing a number of similar devices
(for example, multiple identical ethernet controllers or PCI buses)
can be written more quickly. At present, this can be accomplished
in part by running the source file through CPP before compiling with
\dtc. It's not clear whether ``native'' support for macros would be
more useful.
\end{itemize}
\bibliographystyle{amsplain}
\bibliography{dtc-paper}
\section*{About the authors}
David Gibson has been a member of the IBM Linux Technology Center,
working from Canberra, Australia, since 2001. Recently he has worked
on Linux hugepage support and performance counter support for ppc64,
as well as the device tree compiler. In the past, he has worked on
bringup for various ppc and ppc64 embedded systems, the orinoco
wireless driver, ramfs, and a userspace checkpointing system
(\texttt{esky}).
Benjamin Herrenschmidt was a MacOS developer for about 10 years, but
ultimately saw the light and installed Linux on his Apple PowerPC
machine. After writing a bootloader, BootX, for it in 1998, he
started contributing to the PowerPC Linux port in various areas,
mostly around the support for Apple machines. He became official
PowerMac maintainer in 2001. In 2003, he joined the IBM Linux
Technology Center in Canberra, Australia, where he ported the 64 bit
PowerPC kernel to Apple G5 machines and the Maple embedded board,
among others things. He's a member of the ppc64 development ``team''
and one of his current goals is to make the integration of embedded
platforms smoother and more maintainable than in the 32-bit PowerPC
kernel.
\section*{Legal Statement}
This work represents the view of the author and does not necessarily
represent the view of IBM.
IBM, \ppc, \ppc Architecture, POWER5, pSeries and iSeries are
trademarks or registered trademarks of International Business Machines
Corporation in the United States and/or other countries.
Apple and Power Macintosh are a registered trademarks of Apple
Computer Inc. in the United States, other countries, or both.
Linux is a registered trademark of Linus Torvalds.
Other company, product, and service names may be trademarks or service
marks of others.
\end{document}