Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scripts/make_fit: Support decomposing DTBs

The kernel tree builds some "composite" DTBs, where the final DTB is the
result of applying one or more DTB overlays on top of a base DTB with
fdtoverlay.

The FIT image specification already supports configurations having one
base DTB and overlays applied on top. It is then up to the bootloader to
apply said overlays and either use or pass on the final result. This
allows the FIT image builder to reuse the same FDT images for multiple
configurations, if such cases exist.

The decomposition function depends on the kernel build system, reading
back the .cmd files for the to-be-packaged DTB files to check for the
fdtoverlay command being called. This will not work outside the kernel
tree. The function is off by default to keep compatibility with possible
existing users.

To facilitate the decomposition and keep the code clean, the model and
compatitble string extraction have been moved out of the output_dtb
function. The FDT image description is replaced with the base file name
of the included image.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>

authored by

Chen-Yu Tsai and committed by
Masahiro Yamada
17c31ade e61b190b

+65 -22
+1
scripts/Makefile.lib
··· 522 522 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ 523 523 --name '$(UIMAGE_NAME)' \ 524 524 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ 525 + $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ 525 526 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) 526 527 527 528 # XZ
+64 -22
scripts/make_fit.py
··· 22 22 Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and 23 23 zstd algorithms. 24 24 25 + Use -D to decompose "composite" DTBs into their base components and 26 + deduplicate the resulting base DTBs and DTB overlays. This requires the 27 + DTBs to be sourced from the kernel build directory, as the implementation 28 + looks at the .cmd files produced by the kernel build. 29 + 25 30 The resulting FIT can be booted by bootloaders which support FIT, such 26 31 as U-Boot, Linuxboot, Tianocore, etc. 27 32 ··· 69 64 help='Specifies the architecture') 70 65 parser.add_argument('-c', '--compress', type=str, default='none', 71 66 help='Specifies the compression') 67 + parser.add_argument('-D', '--decompose-dtbs', action='store_true', 68 + help='Decompose composite DTBs into base DTB and overlays') 72 69 parser.add_argument('-E', '--external', action='store_true', 73 70 help='Convert the FIT to use external data') 74 71 parser.add_argument('-n', '--name', type=str, required=True, ··· 147 140 fsw.end_node() 148 141 seq = 0 149 142 with fsw.add_node('configurations'): 150 - for model, compat in entries: 143 + for model, compat, files in entries: 151 144 seq += 1 152 145 with fsw.add_node(f'conf-{seq}'): 153 146 fsw.property('compatible', bytes(compat)) 154 147 fsw.property_string('description', model) 155 - fsw.property_string('fdt', f'fdt-{seq}') 148 + fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) 156 149 fsw.property_string('kernel', 'kernel') 157 150 fsw.end_node() 158 151 ··· 200 193 fname (str): Filename containing the DTB 201 194 arch: FIT architecture, e.g. 'arm64' 202 195 compress (str): Compressed algorithm, e.g. 'gzip' 203 - 204 - Returns: 205 - tuple: 206 - str: Model name 207 - bytes: Compatible stringlist 208 196 """ 209 197 with fsw.add_node(f'fdt-{seq}'): 210 - # Get the compatible / model information 211 - with open(fname, 'rb') as inf: 212 - data = inf.read() 213 - fdt = libfdt.FdtRo(data) 214 - model = fdt.getprop(0, 'model').as_str() 215 - compat = fdt.getprop(0, 'compatible') 216 - 217 - fsw.property_string('description', model) 198 + fsw.property_string('description', os.path.basename(fname)) 218 199 fsw.property_string('type', 'flat_dt') 219 200 fsw.property_string('arch', arch) 220 201 fsw.property_string('compression', compress) ··· 210 215 with open(fname, 'rb') as inf: 211 216 compressed = compress_data(inf, compress) 212 217 fsw.property('data', compressed) 213 - return model, compat 214 218 219 + 220 + def process_dtb(fname, args): 221 + """Process an input DTB, decomposing it if requested and is possible 222 + 223 + Args: 224 + fname (str): Filename containing the DTB 225 + args (Namespace): Program arguments 226 + Returns: 227 + tuple: 228 + str: Model name string 229 + str: Root compatible string 230 + files: list of filenames corresponding to the DTB 231 + """ 232 + # Get the compatible / model information 233 + with open(fname, 'rb') as inf: 234 + data = inf.read() 235 + fdt = libfdt.FdtRo(data) 236 + model = fdt.getprop(0, 'model').as_str() 237 + compat = fdt.getprop(0, 'compatible') 238 + 239 + if args.decompose_dtbs: 240 + # Check if the DTB needs to be decomposed 241 + path, basename = os.path.split(fname) 242 + cmd_fname = os.path.join(path, f'.{basename}.cmd') 243 + with open(cmd_fname, 'r', encoding='ascii') as inf: 244 + cmd = inf.read() 245 + 246 + if 'scripts/dtc/fdtoverlay' in cmd: 247 + # This depends on the structure of the composite DTB command 248 + files = cmd.split() 249 + files = files[files.index('-i') + 1:] 250 + else: 251 + files = [fname] 252 + else: 253 + files = [fname] 254 + 255 + return (model, compat, files) 215 256 216 257 def build_fit(args): 217 258 """Build the FIT from the provided files and arguments ··· 266 235 fsw = libfdt.FdtSw() 267 236 setup_fit(fsw, args.name) 268 237 entries = [] 238 + fdts = {} 269 239 270 240 # Handle the kernel 271 241 with open(args.kernel, 'rb') as inf: ··· 275 243 write_kernel(fsw, comp_data, args) 276 244 277 245 for fname in args.dtbs: 278 - # Ignore overlay (.dtbo) files 279 - if os.path.splitext(fname)[1] == '.dtb': 280 - seq += 1 281 - size += os.path.getsize(fname) 282 - model, compat = output_dtb(fsw, seq, fname, args.arch, args.compress) 283 - entries.append([model, compat]) 246 + # Ignore non-DTB (*.dtb) files 247 + if os.path.splitext(fname)[1] != '.dtb': 248 + continue 249 + 250 + (model, compat, files) = process_dtb(fname, args) 251 + 252 + for fn in files: 253 + if fn not in fdts: 254 + seq += 1 255 + size += os.path.getsize(fn) 256 + output_dtb(fsw, seq, fn, args.arch, args.compress) 257 + fdts[fn] = seq 258 + 259 + files_seq = [fdts[fn] for fn in files] 260 + 261 + entries.append([model, compat, files_seq]) 284 262 285 263 finish_fit(fsw, entries) 286 264