summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/classes-recipe/kernel-fitimage.bbclass864
-rw-r--r--meta/classes-recipe/kernel-uboot.bbclass47
2 files changed, 225 insertions, 686 deletions
diff --git a/meta/classes-recipe/kernel-fitimage.bbclass b/meta/classes-recipe/kernel-fitimage.bbclass
index 8e66f32676..a253b210ef 100644
--- a/meta/classes-recipe/kernel-fitimage.bbclass
+++ b/meta/classes-recipe/kernel-fitimage.bbclass
@@ -56,680 +56,174 @@ python __anonymous () {
56 d.setVar('EXTERNAL_KERNEL_DEVICETREE', "${RECIPE_SYSROOT}/boot/devicetree") 56 d.setVar('EXTERNAL_KERNEL_DEVICETREE', "${RECIPE_SYSROOT}/boot/devicetree")
57} 57}
58 58
59# 59def fitimage_assemble(d, itsfile, fitname, ramdiskcount):
60# Emit the fitImage ITS header 60 import shutil
61# 61 import glob
62# $1 ... .its filename 62 import oe.fitimage
63fitimage_emit_fit_header() { 63
64 cat << EOF >> $1 64 DTBS=""
65/dts-v1/; 65 default_dtb_image=""
66 66
67/ { 67 for f in [itsfile, os.path.join("arch", d.getVar("ARCH"), "boot", fitname)]:
68 description = "${FIT_DESC}"; 68 if os.path.exists(f):
69 #address-cells = <${FIT_ADDRESS_CELLS}>; 69 os.remove(f)
70EOF 70
71} 71 root_node = oe.fitimage.ItsNodeRootKernel(
72 72 d.getVar("FIT_DESC"), d.getVar("FIT_ADDRESS_CELLS"),
73# 73 d.getVar('HOST_PREFIX'), d.getVar('UBOOT_ARCH'), d.getVar("FIT_CONF_PREFIX"),
74# Emit the fitImage section bits 74 d.getVar('UBOOT_SIGN_ENABLE') == "1", d.getVar("UBOOT_SIGN_KEYDIR"),
75# 75 d.getVar("UBOOT_MKIMAGE"), d.getVar("UBOOT_MKIMAGE_DTCOPTS"),
76# $1 ... .its filename 76 d.getVar("UBOOT_MKIMAGE_SIGN"), d.getVar("UBOOT_MKIMAGE_SIGN_ARGS"),
77# $2 ... Section bit type: imagestart - image section start 77 d.getVar('FIT_HASH_ALG'), d.getVar('FIT_SIGN_ALG'), d.getVar('FIT_PAD_ALG'),
78# confstart - configuration section start 78 d.getVar('UBOOT_SIGN_KEYNAME'),
79# sectend - section end 79 d.getVar('FIT_SIGN_INDIVIDUAL') == "1", d.getVar('UBOOT_SIGN_IMG_KEYNAME')
80# fitend - fitimage end 80 )
81# 81
82fitimage_emit_section_maint() { 82 #
83 case $2 in 83 # Step 1: Prepare a kernel image section.
84 imagestart) 84 #
85 cat << EOF >> $1 85 linux_comp = uboot_prep_kimage_py(d)
86 86 root_node.fitimage_emit_section_kernel("kernel-1", "linux.bin", linux_comp,
87 images { 87 d.getVar('UBOOT_LOADADDRESS'), d.getVar('UBOOT_ENTRYPOINT'),
88EOF 88 d.getVar('UBOOT_MKIMAGE_KERNEL_TYPE'), d.getVar("UBOOT_ENTRYSYMBOL"))
89 ;; 89
90 confstart) 90 #
91 cat << EOF >> $1 91 # Step 2: Prepare a DTB image section
92 92 #
93 configurations { 93 kernel_devicetree = d.getVar('KERNEL_DEVICETREE')
94EOF 94 external_kernel_devicetree = d.getVar("EXTERNAL_KERNEL_DEVICETREE")
95 ;; 95 if kernel_devicetree:
96 sectend) 96 for DTB in kernel_devicetree.split():
97 cat << EOF >> $1 97 if "/dts/" in DTB:
98 }; 98 bb.warn(f"{DTB} contains the full path to the dts file, but only the dtb name should be used.")
99EOF 99 DTB = os.path.basename(DTB).replace(".dts", ".dtb")
100 ;; 100
101 fitend) 101 # Skip DTB if it's also provided in EXTERNAL_KERNEL_DEVICETREE
102 cat << EOF >> $1 102 if external_kernel_devicetree:
103}; 103 ext_dtb_path = os.path.join(external_kernel_devicetree, DTB)
104EOF 104 if os.path.exists(ext_dtb_path) and os.path.getsize(ext_dtb_path) > 0:
105 ;; 105 continue
106 esac 106
107} 107 DTB_PATH = os.path.join(d.getVar("KERNEL_OUTPUT_DIR"), "dts", DTB)
108 108 if not os.path.exists(DTB_PATH):
109# 109 DTB_PATH = os.path.join(d.getVar("KERNEL_OUTPUT_DIR"), DTB)
110# Emit the fitImage ITS kernel section 110
111# 111 # Strip off the path component from the filename
112# $1 ... .its filename 112 if not oe.types.boolean(d.getVar("KERNEL_DTBVENDORED")):
113# $2 ... Image counter 113 DTB = os.path.basename(DTB)
114# $3 ... Path to kernel image 114
115# $4 ... Compression type 115 # Set the default dtb image if it exists in the devicetree.
116fitimage_emit_section_kernel() { 116 if d.getVar("FIT_CONF_DEFAULT_DTB") == DTB:
117 117 default_dtb_image = DTB.replace("/", "_")
118 kernel_csum="${FIT_HASH_ALG}" 118
119 kernel_sign_algo="${FIT_SIGN_ALG}" 119 DTB = DTB.replace("/", "_")
120 kernel_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}" 120
121 121 # Skip DTB if we've picked it up previously
122 ENTRYPOINT="${UBOOT_ENTRYPOINT}" 122 if DTB in DTBS.split():
123 if [ -n "${UBOOT_ENTRYSYMBOL}" ]; then 123 continue
124 ENTRYPOINT=`${HOST_PREFIX}nm vmlinux | \ 124
125 awk '$3=="${UBOOT_ENTRYSYMBOL}" {print "0x"$1;exit}'` 125 DTBS += " " + DTB
126 fi 126
127 127 root_node.fitimage_emit_section_dtb(DTB, DTB_PATH,
128 cat << EOF >> $1 128 d.getVar("UBOOT_DTB_LOADADDRESS"), d.getVar("UBOOT_DTBO_LOADADDRESS"))
129 kernel-$2 { 129
130 description = "Linux kernel"; 130 if external_kernel_devicetree:
131 type = "${UBOOT_MKIMAGE_KERNEL_TYPE}"; 131 dtb_files = []
132 compression = "$4"; 132 for ext in ['*.dtb', '*.dtbo']:
133 data = /incbin/("$3"); 133 dtb_files.extend(sorted(glob.glob(os.path.join(external_kernel_devicetree, ext))))
134 arch = "${UBOOT_ARCH}"; 134
135 os = "linux"; 135 for dtb_path in dtb_files:
136 load = <${UBOOT_LOADADDRESS}>; 136 dtb_name = os.path.relpath(dtb_path, external_kernel_devicetree)
137 entry = <$ENTRYPOINT>; 137 dtb_name_underscore = dtb_name.replace('/', '_')
138 hash-1 { 138
139 algo = "$kernel_csum"; 139 # Set the default dtb image if it exists in the devicetree.
140 }; 140 if d.getVar("FIT_CONF_DEFAULT_DTB") == dtb_name:
141 }; 141 default_dtb_image = dtb_name_underscore
142EOF 142
143 143 # Skip DTB/DTBO if we've picked it up previously
144 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$kernel_sign_keyname" ] ; then 144 if dtb_name_underscore in DTBS.split():
145 sed -i '$ d' $1 145 continue
146 cat << EOF >> $1 146
147 signature-1 { 147 DTBS += " " + dtb_name_underscore
148 algo = "$kernel_csum,$kernel_sign_algo"; 148
149 key-name-hint = "$kernel_sign_keyname"; 149 # For symlinks, add a configuration node that refers to the DTB image node to which the symlink points
150 }; 150 symlink_target = oe.fitimage.symlink_points_below(dtb_name, external_kernel_devicetree)
151 }; 151 if symlink_target:
152EOF 152 root_node.fitimage_emit_section_dtb_alias(dtb_name, symlink_target, True)
153 fi 153 # For real DTB files add an image node and a configuration node
154} 154 else:
155 155 root_node.fitimage_emit_section_dtb(dtb_name_underscore, dtb_path,
156# 156 d.getVar("UBOOT_DTB_LOADADDRESS"), d.getVar("UBOOT_DTBO_LOADADDRESS"), True)
157# Emit the fitImage ITS DTB section 157
158# 158 if d.getVar("FIT_CONF_DEFAULT_DTB") and not default_dtb_image:
159# $1 ... .its filename 159 bb.warn("%s is not available in the list of device trees." % d.getVar('FIT_CONF_DEFAULT_DTB'))
160# $2 ... Image counter 160
161# $3 ... Path to DTB image 161 #
162fitimage_emit_section_dtb() { 162 # Step 3: Prepare a u-boot script section
163 163 #
164 dtb_csum="${FIT_HASH_ALG}" 164 fit_uboot_env = d.getVar("FIT_UBOOT_ENV")
165 dtb_sign_algo="${FIT_SIGN_ALG}" 165 if fit_uboot_env:
166 dtb_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}" 166 unpack_dir = d.getVar("UNPACKDIR")
167 167 shutil.copy(os.path.join(unpack_dir, fit_uboot_env), fit_uboot_env)
168 dtb_loadline="" 168 root_node.fitimage_emit_section_boot_script("bootscr-"+fit_uboot_env , fit_uboot_env)
169 dtb_ext=${DTB##*.} 169
170 if [ "${dtb_ext}" = "dtbo" ]; then 170 #
171 if [ -n "${UBOOT_DTBO_LOADADDRESS}" ]; then 171 # Step 4: Prepare a setup section. (For x86)
172 dtb_loadline="load = <${UBOOT_DTBO_LOADADDRESS}>;" 172 #
173 fi 173 setup_bin_path = os.path.join(d.getVar("KERNEL_OUTPUT_DIR"), "setup.bin")
174 elif [ -n "${UBOOT_DTB_LOADADDRESS}" ]; then 174 if os.path.exists(setup_bin_path):
175 dtb_loadline="load = <${UBOOT_DTB_LOADADDRESS}>;" 175 root_node.fitimage_emit_section_setup("setup-1", setup_bin_path)
176 fi 176
177 cat << EOF >> $1 177 #
178 fdt-$2 { 178 # Step 5: Prepare a ramdisk section.
179 description = "Flattened Device Tree blob"; 179 #
180 type = "flat_dt"; 180 if ramdiskcount == 1 and d.getVar("INITRAMFS_IMAGE_BUNDLE") != "1":
181 compression = "none"; 181 # Find and use the first initramfs image archive type we find
182 data = /incbin/("$3"); 182 found = False
183 arch = "${UBOOT_ARCH}"; 183 for img in d.getVar("FIT_SUPPORTED_INITRAMFS_FSTYPES").split():
184 $dtb_loadline 184 initramfs_path = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), "%s.%s" % (d.getVar('INITRAMFS_IMAGE_NAME'), img))
185 hash-1 { 185 if os.path.exists(initramfs_path):
186 algo = "$dtb_csum"; 186 bb.note("Found initramfs image: " + initramfs_path)
187 }; 187 found = True
188 }; 188 root_node.fitimage_emit_section_ramdisk("ramdisk-%d" % ramdiskcount, initramfs_path,
189EOF 189 d.getVar('INITRAMFS_IMAGE'),
190 190 d.getVar("UBOOT_RD_LOADADDRESS"),
191 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$dtb_sign_keyname" ] ; then 191 d.getVar("UBOOT_RD_ENTRYPOINT"))
192 sed -i '$ d' $1 192 break
193 cat << EOF >> $1 193 else:
194 signature-1 { 194 bb.note("Did not find initramfs image: " + initramfs_path)
195 algo = "$dtb_csum,$dtb_sign_algo"; 195
196 key-name-hint = "$dtb_sign_keyname"; 196 if not found:
197 }; 197 bb.fatal("Could not find a valid initramfs type for %s, the supported types are: %s" % (d.getVar('INITRAMFS_IMAGE_NAME'), d.getVar('FIT_SUPPORTED_INITRAMFS_FSTYPES')))
198 }; 198
199EOF 199 # Generate the configuration section
200 fi 200 root_node.fitimage_emit_section_config(default_dtb_image)
201} 201
202 202 #
203# 203 # Write the ITS file
204# Emit the fitImage ITS u-boot script section 204 root_node.write_its_file(itsfile)
205# 205
206# $1 ... .its filename 206 #
207# $2 ... Image counter 207 # Step 7: Assemble the image
208# $3 ... Path to boot script image 208 #
209fitimage_emit_section_boot_script() { 209 fitfile = os.path.join(d.getVar("KERNEL_OUTPUT_DIR"), fitname)
210 210 root_node.run_mkimage_assemble(itsfile, fitfile)
211 bootscr_csum="${FIT_HASH_ALG}" 211
212 bootscr_sign_algo="${FIT_SIGN_ALG}" 212 #
213 bootscr_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}" 213 # Step 8: Sign the image if required
214 214 #
215 cat << EOF >> $1 215 root_node.run_mkimage_sign(fitfile)
216 bootscr-$2 { 216
217 description = "U-boot script"; 217
218 type = "script"; 218python do_assemble_fitimage() {
219 compression = "none"; 219 if "fitImage" in d.getVar("KERNEL_IMAGETYPES").split():
220 data = /incbin/("$3"); 220 os.chdir(d.getVar("B"))
221 arch = "${UBOOT_ARCH}"; 221 fitimage_assemble(d, "fit-image.its", "fitImage-none", "")
222 hash-1 { 222 if d.getVar("INITRAMFS_IMAGE_BUNDLE") != "1":
223 algo = "$bootscr_csum"; 223 link_name = os.path.join(d.getVar("B"), d.getVar("KERNEL_OUTPUT_DIR"), "fitImage")
224 }; 224 if os.path.islink(link_name):
225 }; 225 os.unlink(link_name)
226EOF 226 os.symlink("fitImage-none", link_name)
227
228 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$bootscr_sign_keyname" ] ; then
229 sed -i '$ d' $1
230 cat << EOF >> $1
231 signature-1 {
232 algo = "$bootscr_csum,$bootscr_sign_algo";
233 key-name-hint = "$bootscr_sign_keyname";
234 };
235 };
236EOF
237 fi
238}
239
240#
241# Emit the fitImage ITS setup section
242#
243# $1 ... .its filename
244# $2 ... Image counter
245# $3 ... Path to setup image
246fitimage_emit_section_setup() {
247
248 setup_csum="${FIT_HASH_ALG}"
249 setup_sign_algo="${FIT_SIGN_ALG}"
250 setup_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
251
252 cat << EOF >> $1
253 setup-$2 {
254 description = "Linux setup.bin";
255 type = "x86_setup";
256 compression = "none";
257 data = /incbin/("$3");
258 arch = "${UBOOT_ARCH}";
259 os = "linux";
260 load = <0x00090000>;
261 entry = <0x00090000>;
262 hash-1 {
263 algo = "$setup_csum";
264 };
265 };
266EOF
267
268 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$setup_sign_keyname" ] ; then
269 sed -i '$ d' $1
270 cat << EOF >> $1
271 signature-1 {
272 algo = "$setup_csum,$setup_sign_algo";
273 key-name-hint = "$setup_sign_keyname";
274 };
275 };
276EOF
277 fi
278}
279
280#
281# Emit the fitImage ITS ramdisk section
282#
283# $1 ... .its filename
284# $2 ... Image counter
285# $3 ... Path to ramdisk image
286fitimage_emit_section_ramdisk() {
287
288 ramdisk_csum="${FIT_HASH_ALG}"
289 ramdisk_sign_algo="${FIT_SIGN_ALG}"
290 ramdisk_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
291 ramdisk_loadline=""
292 ramdisk_entryline=""
293
294 if [ -n "${UBOOT_RD_LOADADDRESS}" ]; then
295 ramdisk_loadline="load = <${UBOOT_RD_LOADADDRESS}>;"
296 fi
297 if [ -n "${UBOOT_RD_ENTRYPOINT}" ]; then
298 ramdisk_entryline="entry = <${UBOOT_RD_ENTRYPOINT}>;"
299 fi
300
301 cat << EOF >> $1
302 ramdisk-$2 {
303 description = "${INITRAMFS_IMAGE}";
304 type = "ramdisk";
305 compression = "none";
306 data = /incbin/("$3");
307 arch = "${UBOOT_ARCH}";
308 os = "linux";
309 $ramdisk_loadline
310 $ramdisk_entryline
311 hash-1 {
312 algo = "$ramdisk_csum";
313 };
314 };
315EOF
316
317 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$ramdisk_sign_keyname" ] ; then
318 sed -i '$ d' $1
319 cat << EOF >> $1
320 signature-1 {
321 algo = "$ramdisk_csum,$ramdisk_sign_algo";
322 key-name-hint = "$ramdisk_sign_keyname";
323 };
324 };
325EOF
326 fi
327}
328
329#
330# echoes symlink destination if it points below directory
331#
332# $1 ... file that's a potential symlink
333# $2 ... expected parent directory
334symlink_points_below() {
335 file="$2/$1"
336 dir=$2
337
338 if ! [ -L "$file" ]; then
339 return
340 fi
341
342 realpath="$(realpath --relative-to=$dir $file)"
343 if [ -z "${realpath%%../*}" ]; then
344 return
345 fi
346
347 echo "$realpath"
348}
349
350#
351# Emit the fitImage ITS configuration section
352#
353# $1 ... .its filename
354# $2 ... Linux kernel ID
355# $3 ... DTB image name
356# $4 ... ramdisk ID
357# $5 ... u-boot script ID
358# $6 ... config ID
359# $7 ... default flag
360# $8 ... default DTB image name
361fitimage_emit_section_config() {
362
363 conf_csum="${FIT_HASH_ALG}"
364 conf_sign_algo="${FIT_SIGN_ALG}"
365 conf_padding_algo="${FIT_PAD_ALG}"
366 if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then
367 conf_sign_keyname="${UBOOT_SIGN_KEYNAME}"
368 fi
369
370 its_file="$1"
371 kernel_id="$2"
372 dtb_image="$3"
373 ramdisk_id="$4"
374 bootscr_id="$5"
375 config_id="$6"
376 default_flag="$7"
377 default_dtb_image="$8"
378
379 # Test if we have any DTBs at all
380 sep=""
381 conf_desc=""
382 conf_node="${FIT_CONF_PREFIX}"
383 kernel_line=""
384 fdt_line=""
385 ramdisk_line=""
386 bootscr_line=""
387 setup_line=""
388 default_line=""
389 compatible_line=""
390
391 dtb_image_sect=$(symlink_points_below $dtb_image "${EXTERNAL_KERNEL_DEVICETREE}")
392 if [ -z "$dtb_image_sect" ]; then
393 dtb_image_sect=$dtb_image
394 fi
395
396 dtb_path="${EXTERNAL_KERNEL_DEVICETREE}/${dtb_image_sect}"
397 if [ -f "$dtb_path" ] || [ -L "$dtb_path" ]; then
398 compat=$(fdtget -t s "$dtb_path" / compatible | sed 's/ /", "/g')
399 if [ -n "$compat" ]; then
400 compatible_line="compatible = \"$compat\";"
401 fi
402 fi
403
404 dtb_image=$(echo $dtb_image | tr '/' '_')
405 dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
406
407 # conf node name is selected based on dtb ID if it is present,
408 # otherwise its selected based on kernel ID
409 if [ -n "$dtb_image" ]; then
410 conf_node=$conf_node$dtb_image
411 else
412 conf_node=$conf_node$kernel_id
413 fi
414
415 if [ -n "$kernel_id" ]; then
416 conf_desc="Linux kernel"
417 sep=", "
418 kernel_line="kernel = \"kernel-$kernel_id\";"
419 fi
420
421 if [ -n "$dtb_image" ]; then
422 conf_desc="$conf_desc${sep}FDT blob"
423 sep=", "
424 fdt_line="fdt = \"fdt-$dtb_image_sect\";"
425 fi
426
427 if [ -n "$ramdisk_id" ]; then
428 conf_desc="$conf_desc${sep}ramdisk"
429 sep=", "
430 ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
431 fi
432
433 if [ -n "$bootscr_id" ]; then
434 conf_desc="$conf_desc${sep}u-boot script"
435 sep=", "
436 bootscr_line="bootscr = \"bootscr-$bootscr_id\";"
437 fi
438
439 if [ -n "$config_id" ]; then
440 conf_desc="$conf_desc${sep}setup"
441 setup_line="setup = \"setup-$config_id\";"
442 fi
443
444 if [ "$default_flag" = "1" ]; then
445 # default node is selected based on dtb ID if it is present,
446 # otherwise its selected based on kernel ID
447 if [ -n "$dtb_image" ]; then
448 # Select default node as user specified dtb when
449 # multiple dtb exists.
450 if [ -n "$default_dtb_image" ]; then
451 default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
452 else
453 default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
454 fi
455 else
456 default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
457 fi
458 fi
459
460 cat << EOF >> $its_file
461 $default_line
462 $conf_node {
463 description = "$default_flag $conf_desc";
464 $compatible_line
465 $kernel_line
466 $fdt_line
467 $ramdisk_line
468 $bootscr_line
469 $setup_line
470 hash-1 {
471 algo = "$conf_csum";
472 };
473EOF
474
475 if [ -n "$conf_sign_keyname" ] ; then
476
477 sign_line="sign-images = "
478 sep=""
479
480 if [ -n "$kernel_id" ]; then
481 sign_line="$sign_line${sep}\"kernel\""
482 sep=", "
483 fi
484
485 if [ -n "$dtb_image" ]; then
486 sign_line="$sign_line${sep}\"fdt\""
487 sep=", "
488 fi
489
490 if [ -n "$ramdisk_id" ]; then
491 sign_line="$sign_line${sep}\"ramdisk\""
492 sep=", "
493 fi
494
495 if [ -n "$bootscr_id" ]; then
496 sign_line="$sign_line${sep}\"bootscr\""
497 sep=", "
498 fi
499
500 if [ -n "$config_id" ]; then
501 sign_line="$sign_line${sep}\"setup\""
502 fi
503
504 sign_line="$sign_line;"
505
506 cat << EOF >> $its_file
507 signature-1 {
508 algo = "$conf_csum,$conf_sign_algo";
509 key-name-hint = "$conf_sign_keyname";
510 padding = "$conf_padding_algo";
511 $sign_line
512 };
513EOF
514 fi
515
516 cat << EOF >> $its_file
517 };
518EOF
519}
520
521#
522# Assemble fitImage
523#
524# $1 ... .its filename
525# $2 ... fitImage name
526# $3 ... include ramdisk
527fitimage_assemble() {
528 kernelcount=1
529 dtbcount=""
530 DTBS=""
531 ramdiskcount=$3
532 setupcount=""
533 bootscr_id=""
534 default_dtb_image=""
535 rm -f $1 arch/${ARCH}/boot/$2
536
537 if [ -n "${UBOOT_SIGN_IMG_KEYNAME}" -a "${UBOOT_SIGN_KEYNAME}" = "${UBOOT_SIGN_IMG_KEYNAME}" ]; then
538 bbfatal "Keys used to sign images and configuration nodes must be different."
539 fi
540
541 fitimage_emit_fit_header $1
542
543 #
544 # Step 1: Prepare a kernel image section.
545 #
546 fitimage_emit_section_maint $1 imagestart
547
548 uboot_prep_kimage
549 fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
550
551 #
552 # Step 2: Prepare a DTB image section
553 #
554
555 if [ -n "${KERNEL_DEVICETREE}" ]; then
556 dtbcount=1
557 for DTB in ${KERNEL_DEVICETREE}; do
558 if echo $DTB | grep -q '/dts/'; then
559 bbwarn "$DTB contains the full path to the the dts file, but only the dtb name should be used."
560 DTB=`basename $DTB | sed 's,\.dts$,.dtb,g'`
561 fi
562
563 # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
564 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
565 continue
566 fi
567
568 DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
569 if [ ! -e "$DTB_PATH" ]; then
570 DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
571 fi
572
573 # Strip off the path component from the filename
574 if "${@'false' if oe.types.boolean(d.getVar('KERNEL_DTBVENDORED')) else 'true'}"; then
575 DTB=`basename $DTB`
576 fi
577
578 # Set the default dtb image if it exists in the devicetree.
579 if [ "${FIT_CONF_DEFAULT_DTB}" = "$DTB" ];then
580 default_dtb_image=$(echo "$DTB" | tr '/' '_')
581 fi
582
583 DTB=$(echo "$DTB" | tr '/' '_')
584
585 # Skip DTB if we've picked it up previously
586 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
587
588 DTBS="$DTBS $DTB"
589 DTB=$(echo $DTB | tr '/' '_')
590 fitimage_emit_section_dtb $1 $DTB $DTB_PATH
591 done
592 fi
593
594 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
595 dtbcount=1
596 for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtb' -printf '%P\n' | sort) \
597 $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtbo' -printf '%P\n' | sort); do
598 # Set the default dtb image if it exists in the devicetree.
599 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
600 default_dtb_image=$(echo "$DTB" | tr '/' '_')
601 fi
602
603 DTB=$(echo "$DTB" | tr '/' '_')
604
605 # Skip DTB/DTBO if we've picked it up previously
606 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
607
608 DTBS="$DTBS $DTB"
609
610 # Also skip if a symlink. We'll later have each config section point at it
611 [ $(symlink_points_below $DTB "${EXTERNAL_KERNEL_DEVICETREE}") ] && continue
612
613 DTB=$(echo $DTB | tr '/' '_')
614 fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
615 done
616 fi
617
618 if [ -n "${FIT_CONF_DEFAULT_DTB}" ] && [ -z $default_dtb_image ]; then
619 bbwarn "${FIT_CONF_DEFAULT_DTB} is not available in the list of device trees."
620 fi
621
622 #
623 # Step 3: Prepare a u-boot script section
624 #
625
626 if [ -n "${FIT_UBOOT_ENV}" ]; then
627 cp ${UNPACKDIR}/${FIT_UBOOT_ENV} ${B}
628 bootscr_id="${FIT_UBOOT_ENV}"
629 fitimage_emit_section_boot_script $1 "$bootscr_id" ${FIT_UBOOT_ENV}
630 fi
631
632 #
633 # Step 4: Prepare a setup section. (For x86)
634 #
635 if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
636 setupcount=1
637 fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
638 fi
639
640 #
641 # Step 5: Prepare a ramdisk section.
642 #
643 if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
644 # Find and use the first initramfs image archive type we find
645 found=
646 for img in ${FIT_SUPPORTED_INITRAMFS_FSTYPES}; do
647 initramfs_path="${INITRAMFS_DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img"
648 if [ -e "$initramfs_path" ]; then
649 bbnote "Found initramfs image: $initramfs_path"
650 found=true
651 fitimage_emit_section_ramdisk $1 "$ramdiskcount" "$initramfs_path"
652 break
653 else
654 bbnote "Did not find initramfs image: $initramfs_path"
655 fi
656 done
657
658 if [ -z "$found" ]; then
659 bbfatal "Could not find a valid initramfs type for ${INITRAMFS_IMAGE_NAME}, the supported types are: ${FIT_SUPPORTED_INITRAMFS_FSTYPES}"
660 fi
661 fi
662
663 fitimage_emit_section_maint $1 sectend
664
665 # Force the first Kernel and DTB in the default config
666 kernelcount=1
667 if [ -n "$dtbcount" ]; then
668 dtbcount=1
669 fi
670
671 #
672 # Step 6: Prepare a configurations section
673 #
674 fitimage_emit_section_maint $1 confstart
675
676 # kernel-fitimage.bbclass currently only supports a single kernel (no less or
677 # more) to be added to the FIT image along with 0 or more device trees and
678 # 0 or 1 ramdisk.
679 # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
680 # When the initramfs bundle is used ramdisk is disabled.
681 # If a device tree is to be part of the FIT image, then select
682 # the default configuration to be used is based on the dtbcount. If there is
683 # no dtb present than select the default configuation to be based on
684 # the kernelcount.
685 if [ -n "$DTBS" ]; then
686 i=1
687 for DTB in ${DTBS}; do
688 dtb_ext=${DTB##*.}
689 if [ "$dtb_ext" = "dtbo" ]; then
690 fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
691 else
692 fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
693 fi
694 i=`expr $i + 1`
695 done
696 else
697 defaultconfigcount=1
698 fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id" "$setupcount" $defaultconfigcount "$default_dtb_image"
699 fi
700
701 fitimage_emit_section_maint $1 sectend
702
703 fitimage_emit_section_maint $1 fitend
704
705 #
706 # Step 7: Assemble the image
707 #
708 ${UBOOT_MKIMAGE} \
709 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
710 -f $1 \
711 ${KERNEL_OUTPUT_DIR}/$2
712
713 #
714 # Step 8: Sign the image
715 #
716 if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
717 ${UBOOT_MKIMAGE_SIGN} \
718 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
719 -F -k "${UBOOT_SIGN_KEYDIR}" \
720 -r ${KERNEL_OUTPUT_DIR}/$2 \
721 ${UBOOT_MKIMAGE_SIGN_ARGS}
722 fi
723}
724
725do_assemble_fitimage() {
726 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
727 cd ${B}
728 fitimage_assemble fit-image.its fitImage-none ""
729 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
730 ln -sf fitImage-none ${B}/${KERNEL_OUTPUT_DIR}/fitImage
731 fi
732 fi
733} 227}
734 228
735addtask assemble_fitimage before do_install after do_compile 229addtask assemble_fitimage before do_install after do_compile
@@ -742,17 +236,17 @@ do_install:append() {
742 fi 236 fi
743} 237}
744 238
745do_assemble_fitimage_initramfs() { 239python do_assemble_fitimage_initramfs() {
746 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \ 240 if "fitImage" in d.getVar("KERNEL_IMAGETYPES").split() and d.getVar("INITRAMFS_IMAGE"):
747 test -n "${INITRAMFS_IMAGE}" ; then 241 os.chdir(d.getVar("B"))
748 cd ${B} 242 if d.getVar("INITRAMFS_IMAGE_BUNDLE") == "1":
749 if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then 243 fitimage_assemble(d, "fit-image-%s.its" % d.getVar("INITRAMFS_IMAGE"), "fitImage-bundle", "")
750 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-bundle "" 244 link_name = os.path.join(d.getVar("B"), d.getVar("KERNEL_OUTPUT_DIR"), "fitImage")
751 ln -sf fitImage-bundle ${B}/${KERNEL_OUTPUT_DIR}/fitImage 245 if os.path.islink(link_name):
752 else 246 os.unlink(link_name)
753 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1 247 os.symlink("fitImage-bundle", link_name)
754 fi 248 else:
755 fi 249 fitimage_assemble(d, "fit-image-%s.its" % d.getVar("INITRAMFS_IMAGE"), "fitImage-%s" % d.getVar("INITRAMFS_IMAGE"), 1)
756} 250}
757 251
758addtask assemble_fitimage_initramfs before do_deploy after do_bundle_initramfs 252addtask assemble_fitimage_initramfs before do_deploy after do_bundle_initramfs
diff --git a/meta/classes-recipe/kernel-uboot.bbclass b/meta/classes-recipe/kernel-uboot.bbclass
index d2a63524ec..6d365355e3 100644
--- a/meta/classes-recipe/kernel-uboot.bbclass
+++ b/meta/classes-recipe/kernel-uboot.bbclass
@@ -56,4 +56,49 @@ uboot_prep_kimage() {
56 fi 56 fi
57 57
58 printf "$linux_comp" > "$output_dir/linux_comp" 58 printf "$linux_comp" > "$output_dir/linux_comp"
59} \ No newline at end of file 59}
60
61def uboot_prep_kimage_py(d):
62 import subprocess
63
64 arch = d.getVar('ARCH')
65 initramfs_image_bundle = d.getVar('INITRAMFS_IMAGE_BUNDLE')
66 fit_kernel_comp_alg = d.getVar('FIT_KERNEL_COMP_ALG') or 'gzip'
67 fit_kernel_comp_alg_extension = d.getVar('FIT_KERNEL_COMP_ALG_EXTENSION') or '.gz'
68 kernel_objcopy = d.getVar('KERNEL_OBJCOPY')
69
70 vmlinux_path = ""
71 linux_suffix = ""
72 linux_comp = "none"
73
74 if os.path.exists(f'arch/{arch}/boot/compressed/vmlinux'):
75 vmlinux_path = f'arch/{arch}/boot/compressed/vmlinux'
76 elif os.path.exists(f'arch/{arch}/boot/vmlinuz.bin'):
77 if os.path.exists('linux.bin'):
78 os.remove('linux.bin')
79 os.link(f'arch/{arch}/boot/vmlinuz.bin', 'linux.bin')
80 else:
81 vmlinux_path = 'vmlinux'
82 # Use vmlinux.initramfs for linux.bin when INITRAMFS_IMAGE_BUNDLE set
83 # As per the implementation in kernel.bbclass.
84 # See do_bundle_initramfs function
85 if initramfs_image_bundle == '1' and os.path.exists('vmlinux.initramfs'):
86 vmlinux_path = 'vmlinux.initramfs'
87 linux_suffix = fit_kernel_comp_alg_extension
88 linux_comp = fit_kernel_comp_alg
89
90 if vmlinux_path:
91 subprocess.run([kernel_objcopy.strip(), '-O', 'binary', '-R', '.note', '-R', '.comment', '-S', os.path.abspath(vmlinux_path), 'linux.bin'], check=True)
92 # if ret.returncode != 0:
93 # bb.fatal(f"Error: stderr: {ret.stderr.decode('utf-8')} stdout: {ret.stdout.decode('utf-8')}, vmlinux_path: {os.path.abspath(vmlinux_path)}, pwd: {os.getcwd()}, args: {ret.args}")
94
95 if linux_comp != "none":
96 if linux_comp == "gzip":
97 subprocess.run(['gzip', '-9', 'linux.bin'], check=True)
98 elif linux_comp == "lzo":
99 subprocess.run(['lzop', '-9', 'linux.bin'], check=True)
100 elif linux_comp == "lzma":
101 subprocess.run(['xz', '--format=lzma', '-f', '-6', 'linux.bin'], check=True)
102 os.rename(f'linux.bin{linux_suffix}', 'linux.bin')
103
104 return linux_comp