From 86e0949a146efff718548ee8e259941c16b56c4f Mon Sep 17 00:00:00 2001 From: Ming Liu Date: Tue, 14 May 2024 11:52:59 +0200 Subject: [PATCH] rpi-update-firmware.bbclass: refactor rpi_install_firmware_to_rootfs The current rpi_install_firmware_to_rootfs has several problems: - it's installing duplicated devicetrees to /boot/firmware, because it is installing all dtb/dtbo links but they are duplicated, for instance: uart2.dtbo and uart2-raspberrypi4-64.dtbo are pointing to a same file. - While RPI bootfs contains all files listed in IMAGE_BOOT_FILES, a end user can customize that variable to install the files they want to be in boot partition, but rpi_install_firmware_to_rootfs does not handle it. To fix the above, introduce a function mender_install_deployed_files which is implemented in the same way with how WIC handle IMAGE_BOOT_FILES, now the files in boot partition and the files in /boot/firmware of A/B partitions are consistent. Signed-off-by: Ming Liu --- .../classes/rpi-update-firmware.bbclass | 66 ++++++++++++++++--- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/meta-mender-raspberrypi/classes/rpi-update-firmware.bbclass b/meta-mender-raspberrypi/classes/rpi-update-firmware.bbclass index c0c27a086..5dff08c8c 100644 --- a/meta-mender-raspberrypi/classes/rpi-update-firmware.bbclass +++ b/meta-mender-raspberrypi/classes/rpi-update-firmware.bbclass @@ -1,15 +1,63 @@ -rpi_install_firmware_to_rootfs() { - install -d ${IMAGE_ROOTFS}/boot/firmware/overlays +# Whitespace separated list of files declared by 'deploy_var' variable +# from 'source_dir' (DEPLOY_DIR_IMAGE by default) to place in 'deploy_dir'. +# Entries will be installed under a same name as the source file. To change +# the destination file name, pass a desired name after a semicolon +# (eg. u-boot.img;uboot). Exactly same rules with how IMAGE_BOOT_FILES being +# handled by wic. +def mender_install_deployed_files(d, deploy_var, deploy_dir, source_dir=None): + import os, re, glob, subprocess - cp ${DEPLOY_DIR_IMAGE}/${BOOTFILES_DIR_NAME}/* ${IMAGE_ROOTFS}/boot/firmware/ + src_files = d.getVar(deploy_var) or "" + src_dir = source_dir or d.getVar('DEPLOY_DIR_IMAGE') + dst_dir = deploy_dir - # To exclude files such as bcm2710-rpi-3-b-1-4.19.88+git0+988cc7beac-r0-raspberrypi3-20200323173633.dtb - # as only the link names are actually valid and searched for on the device. - find ${DEPLOY_DIR_IMAGE}/ -type l \( -iname "*.dtb" \) -exec cp {} ${IMAGE_ROOTFS}/boot/firmware/ \; - find ${DEPLOY_DIR_IMAGE}/ -type l \( -iname "*.dtbo" \) -exec cp {} ${IMAGE_ROOTFS}/boot/firmware/overlays/ \; + # list of tuples (src_name, dst_name) + deploy_files = [] + for src_entry in re.findall(r'[\w;\-\./\*]+', src_files): + if ';' in src_entry: + dst_entry = tuple(src_entry.split(';')) + if not dst_entry[0] or not dst_entry[1]: + bb.fatal('Malformed file entry: %s' % src_entry) + else: + dst_entry = (src_entry, src_entry) + deploy_files.append(dst_entry) - cp ${DEPLOY_DIR_IMAGE}/u-boot.bin ${IMAGE_ROOTFS}/boot/firmware/${SDIMG_KERNELIMAGE} - cp ${DEPLOY_DIR_IMAGE}/boot.scr ${IMAGE_ROOTFS}/boot/firmware/ + # list of tuples (src_path, dst_path) + install_task = [] + for deploy_entry in deploy_files: + src, dst = deploy_entry + if '*' in src: + # by default install files under their basename + entry_name_fn = os.path.basename + if dst != src: + # unless a target name was given, then treat name + # as a directory and append a basename + entry_name_fn = lambda name: \ + os.path.join(dst, + os.path.basename(name)) + + srcs = glob.glob(os.path.join(src_dir, src)) + for entry in srcs: + src = os.path.relpath(entry, src_dir) + entry_dst_name = entry_name_fn(entry) + install_task.append((src, entry_dst_name)) + else: + install_task.append((src, dst)) + + # install src_path to dst_path + for task in install_task: + src_path, dst_path = task + install_cmd = "install -m 0644 -D %s %s" \ + % (os.path.join(src_dir, src_path), + os.path.join(dst_dir, dst_path)) + try: + subprocess.check_output(install_cmd, stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError as e: + bb.fatal("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output)) + + +python rpi_install_firmware_to_rootfs() { + mender_install_deployed_files(d, 'IMAGE_BOOT_FILES', os.path.join(d.getVar('IMAGE_ROOTFS'), 'boot', 'firmware')) } ROOTFS_POSTPROCESS_COMMAND += "rpi_install_firmware_to_rootfs; "