summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorNathan Rossi <nathan@nathanrossi.com>2018-08-02 18:55:04 +1000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-08-08 10:51:59 +0100
commit4ffc885788fb1401639a57b66eb5ecf91908e1d8 (patch)
tree68efd3338f85faf06d4a628184adb094460957d1 /meta
parenta0b2bb6a9d9bcc2b9ae3f8b869cd4295aa6c7b37 (diff)
downloadpoky-4ffc885788fb1401639a57b66eb5ecf91908e1d8.tar.gz
devicetree.bbclass: User/BSP device tree source compilation class
This bbclass implements the device tree compilation for user provided device trees. In order to use this class, it should be inherited in a BSP recipe which provides the sources. The default setup enables inclusion of kernel device tree sources (though can be disabled by the recipe by overriding DT_INCLUDE or KERNEL_INCLUDE). This provides an additional mechanism for BSPs to provide device trees and device tree overlays for their target machines. Whilst still enabling access to the kernel device trees for base SoC includes and headers. This approach to providing device trees has benefits for certain use cases over patching the device trees into the kernel source. * device trees are separated from kernel source, allows for selection of kernel and or kernel versions without needing to explicitly patch the kernel (or appending to the kernel recipes). * providing device trees from separate sources, from the layer, generated by the recipe or other recipes. This class also implements some additional features that are not available in the kernel-devicetree flow. This includes population of device tree blobs into the sysroot which allows for other recipes to consume built dtbs (e.g. U-Boot with EXT_DTB compilation), device tree overlay compilation and customizing DTC compilation args (boot cpu/padding/etc.). (From OE-Core rev: 3874c3859c3515fc8440fa9e776a02ad6ff3135c) Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> Acked-by: Martin Hundebøll <mnhu@prevas.dk> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes/devicetree.bbclass140
1 files changed, 140 insertions, 0 deletions
diff --git a/meta/classes/devicetree.bbclass b/meta/classes/devicetree.bbclass
new file mode 100644
index 0000000000..dbc83f2a1d
--- /dev/null
+++ b/meta/classes/devicetree.bbclass
@@ -0,0 +1,140 @@
1# This bbclass implements device tree compliation for user provided device tree
2# sources. The compilation of the device tree sources is the same as the kernel
3# device tree compilation process, this includes being able to include sources
4# from the kernel such as soc dtsi files or header files such as gpio.h. In
5# addition to device trees this bbclass also handles compilation of device tree
6# overlays.
7#
8# The output of this class behaves similar to how kernel-devicetree.bbclass
9# operates in that the output files are installed into /boot/devicetree.
10# However this class on purpose separates the deployed device trees into the
11# 'devicetree' subdirectory. This prevents clashes with the kernel-devicetree
12# output. Additionally the device trees are populated into the sysroot for
13# access via the sysroot from within other recipes.
14
15SECTION ?= "bsp"
16
17# The default inclusion of kernel device tree includes and headers means that
18# device trees built with them are at least GPLv2 (and in some cases dual
19# licensed). Default to GPLv2 if the recipe does not specify a license.
20LICENSE ?= "GPLv2"
21LIC_FILES_CHKSUM ?= "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"
22
23INHIBIT_DEFAULT_DEPS = "1"
24DEPENDS += "dtc-native"
25
26inherit deploy kernel-arch
27
28COMPATIBLE_MACHINE ?= "^$"
29
30PACKAGE_ARCH = "${MACHINE_ARCH}"
31
32SYSROOT_DIRS += "/boot/devicetree"
33FILES_${PN} = "/boot/devicetree/*.dtb /boot/devicetree/*.dtbo"
34
35S = "${WORKDIR}"
36B = "${WORKDIR}/build"
37
38# Default kernel includes, these represent what are normally used for in-kernel
39# sources.
40KERNEL_INCLUDE ??= " \
41 ${STAGING_KERNEL_DIR}/arch/${ARCH}/boot/dts \
42 ${STAGING_KERNEL_DIR}/arch/${ARCH}/boot/dts/* \
43 ${STAGING_KERNEL_DIR}/scripts/dtc/include-prefixes \
44 "
45
46DT_INCLUDE[doc] = "Search paths to be made available to both the device tree compiler and preprocessor for inclusion."
47DT_INCLUDE ?= "${DT_FILES_PATH} ${KERNEL_INCLUDE}"
48DT_FILES_PATH[doc] = "Defaults to source directory, can be used to select dts files that are not in source (e.g. generated)."
49DT_FILES_PATH ?= "${S}"
50
51DT_PADDING_SIZE[doc] = "Size of padding on the device tree blob, used as extra space typically for additional properties during boot."
52DT_PADDING_SIZE ??= "0x3000"
53DT_RESERVED_MAP[doc] = "Number of reserved map entires."
54DT_RESERVED_MAP ??= "8"
55DT_BOOT_CPU[doc] = "The boot cpu, defaults to 0"
56DT_BOOT_CPU ??= "0"
57
58DTC_FLAGS ?= "-R ${DT_RESERVED_MAP} -p ${DT_PADDING_SIZE} -b ${DT_BOOT_CPU}"
59DTC_PPFLAGS ?= "-nostdinc -undef -D__DTS__ -x assembler-with-cpp"
60DTC_OFLAGS ?= "-@ -H epapr"
61
62python () {
63 if d.getVar("KERNEL_INCLUDE"):
64 # auto add dependency on kernel tree, but only if kernel include paths
65 # are specified.
66 d.appendVarFlag("do_compile", "depends", " virtual/kernel:do_configure")
67}
68
69def expand_includes(varname, d):
70 import glob
71 includes = set()
72 # expand all includes with glob
73 for i in (d.getVar(varname) or "").split():
74 for g in glob.glob(i):
75 if os.path.isdir(g): # only add directories to include path
76 includes.add(g)
77 return includes
78
79def devicetree_source_is_overlay(path):
80 # determine if a dts file is an overlay by checking if it uses "/plugin/;"
81 with open(path, "r") as f:
82 for i in f:
83 if i.startswith("/plugin/;"):
84 return True
85 return False
86
87def devicetree_compile(dtspath, includes, d):
88 import subprocess
89 dts = os.path.basename(dtspath)
90 dtname = os.path.splitext(dts)[0]
91 bb.note("Processing {0} [{1}]".format(dtname, dts))
92
93 # preprocess
94 ppargs = d.getVar("BUILD_CPP").split()
95 ppargs += (d.getVar("DTC_PPFLAGS") or "").split()
96 for i in includes:
97 ppargs.append("-I{0}".format(i))
98 ppargs += ["-o", "{0}.pp".format(dts), dtspath]
99 bb.note("Running {0}".format(" ".join(ppargs)))
100 subprocess.run(ppargs, check = True)
101
102 # determine if the file is an overlay or not (using the preprocessed file)
103 isoverlay = devicetree_source_is_overlay("{0}.pp".format(dts))
104
105 # compile
106 dtcargs = ["dtc"] + (d.getVar("DTC_FLAGS") or "").split()
107 if isoverlay:
108 dtcargs += (d.getVar("DTC_OFLAGS") or "").split()
109 for i in includes:
110 dtcargs += ["-i", i]
111 dtcargs += ["-o", "{0}.{1}".format(dtname, "dtbo" if isoverlay else "dtb")]
112 dtcargs += ["-I", "dts", "-O", "dtb", "{0}.pp".format(dts)]
113 bb.note("Running {0}".format(" ".join(dtcargs)))
114 subprocess.run(dtcargs, check = True)
115
116python devicetree_do_compile() {
117 includes = expand_includes("DT_INCLUDE", d)
118 listpath = d.getVar("DT_FILES_PATH")
119 for dts in os.listdir(listpath):
120 if not dts.endswith(".dts"):
121 continue # skip non-.dts files
122 dtspath = os.path.join(listpath, dts)
123 devicetree_compile(dtspath, includes, d)
124}
125
126devicetree_do_install() {
127 for DTB_FILE in `ls *.dtb *.dtbo`; do
128 install -Dm 0644 ${B}/${DTB_FILE} ${D}/boot/devicetree/${DTB_FILE}
129 done
130}
131
132devicetree_do_deploy() {
133 for DTB_FILE in `ls *.dtb *.dtbo`; do
134 install -Dm 0644 ${B}/${DTB_FILE} ${DEPLOYDIR}/devicetree/${DTB_FILE}
135 done
136}
137addtask deploy before do_build after do_install
138
139EXPORT_FUNCTIONS do_compile do_install do_deploy
140