diff --git a/build/meta-bsp/classes/bsp.bbclass b/build/meta-bsp/classes/bsp.bbclass index 5a30424046..513e2094f8 100644 --- a/build/meta-bsp/classes/bsp.bbclass +++ b/build/meta-bsp/classes/bsp.bbclass @@ -149,7 +149,10 @@ inherit filesystem # `deploy.sh -a` without a prior build still pulls them through sstate). do_deploy_boot_chain[nostamp] = "1" -do_deploy_boot_chain[depends] = "uboot:do_build" +# filesystem:do_fs_check because a chain may write its first stage into the +# raw area of the card (bsp_virt64.inc, IB_FIRST_STAGE_FROM_CARD): on a fresh +# tree the storage image must exist before, not be created by do_deploy after. +do_deploy_boot_chain[depends] = "uboot:do_build filesystem:do_fs_check" python () { extra = [] diff --git a/build/meta-bsp/recipes-bsp/bsp/files/bsp_virt64.inc b/build/meta-bsp/recipes-bsp/bsp/files/bsp_virt64.inc index fb6447931b..a6dda3c2de 100644 --- a/build/meta-bsp/recipes-bsp/bsp/files/bsp_virt64.inc +++ b/build/meta-bsp/recipes-bsp/bsp/files/bsp_virt64.inc @@ -104,14 +104,13 @@ def __do_platform_boot_chain(d): # the image, not of the chain: a ROM copies bytes to an address and jumps, # so the image has to be one that runs from RAM. # - # MCUboot always is. U-Boot depends on how it was configured, and this - # tree builds it two ways (see uboot_2022.04.bb): IB_BOOT_CHAIN="uboot" - # with no hypervisor takes upstream qemu_arm64_defconfig, which is - # position-independent with a text base of 0 — an image meant to execute - # in place from flash, which is why QEMU is handed it as -kernel today and - # why -bios would be the other right answer. Every other combination takes - # ${IB_PLATFORM}_defconfig, linked at a RAM address, and that one can be - # read off the card like any other first stage. + # MCUboot always is. U-Boot depends on how it was configured: this tree + # always builds ${IB_PLATFORM}_defconfig (see uboot_2022.04.bb), linked at + # a RAM address, which can be read off the card like any other first + # stage. Infrabase takes upstream qemu_arm64_defconfig on the bare "uboot" + # chain instead — position-independent with a text base of 0, an image + # meant to execute in place from flash — and the check below keeps such a + # U-Boot on -kernel, should a tree build one. # # The ELF entry point is what says which: zero means "wherever flash is". uboot_entry = 0 diff --git a/build/meta-filesystem/classes/fs_arm_common.bbclass b/build/meta-filesystem/classes/fs_arm_common.bbclass index a4ae6cf62e..aec76d76ce 100644 --- a/build/meta-filesystem/classes/fs_arm_common.bbclass +++ b/build/meta-filesystem/classes/fs_arm_common.bbclass @@ -27,6 +27,7 @@ IB_PARTITION_LAYOUT ?= "${@'ab' if d.getVar('IB_ZEPHYR_BOOT_APP') else 'rootfs'} def __platform_init_storage(d): import os import subprocess + import time IB_STORAGE_MODE = d.getVar('IB_STORAGE_MODE') IB_ROOTFS_SIZE = d.getVar('IB_ROOTFS_SIZE') @@ -128,14 +129,26 @@ def __platform_init_storage(d): print("Waiting ...") - # TODO: use ionotify(7) - # Give a chance to the real SD-card to be sync'd - time.sleep(2) - if devname[-1].isdigit(): devname += "p" - utils_sudo(["mkfs.fat", "-F32", "-a", "-v", "-n", "boot", f"/dev/{devname}1"]) + # Wait for the partition nodes rather than a fixed delay. They are created + # asynchronously by the host's udev, and inside the build container + # (dbuild.sh bind-mounts the host /dev) that regularly takes longer than + # the 2 s this used to sleep: mkfs then ran on a node that did not exist + # yet, failed, and the card was left with an unformatted p1 that only + # showed up as a failed mount in the next deploy. + parts = ("1", "2", "3") if layout == "ab" else ("1", "2") + for _ in range(100): + if all(os.path.exists(f"/dev/{devname}{n}") for n in parts): + break + time.sleep(0.2) + else: + bb.fatal(f"/dev/{devname}{{{','.join(parts)}}} did not appear after " + "partitioning /dev/" + devname.rstrip("p")) + + utils_sudo(["mkfs.fat", "-F32", "-a", "-v", "-n", "boot", f"/dev/{devname}1"], + check=True) if layout == "ab": # p2 and p3 are raw slots. A filesystem on them would be a filesystem @@ -146,7 +159,7 @@ def __platform_init_storage(d): utils_sudo(["dd", "if=/dev/zero", f"of=/dev/{devname}{part}", "bs=1M", "count=1", "conv=fsync"]) else: - utils_sudo(["mkfs.ext4", "-L", "rootfs1", f"/dev/{devname}2"]) + utils_sudo(["mkfs.ext4", "-L", "rootfs1", f"/dev/{devname}2"], check=True) if IB_STORAGE_MODE == "soft": utils_sudo(["losetup", "-D"]) diff --git a/build/meta-uboot/recipes-uboot/uboot/uboot_2022.04.bb b/build/meta-uboot/recipes-uboot/uboot/uboot_2022.04.bb index 0226c7268f..1364f09070 100644 --- a/build/meta-uboot/recipes-uboot/uboot/uboot_2022.04.bb +++ b/build/meta-uboot/recipes-uboot/uboot/uboot_2022.04.bb @@ -41,11 +41,15 @@ do_configure () { cd ${IB_TARGET} # Defconfig selection on virt64: - # - IB_BOOT_CHAIN="uboot" (bare bsp-linux, no ATF): - # upstream qemu_arm64_defconfig — CONFIG_POSITION_INDEPENDENT=y - # and CONFIG_ARCH_QEMU=y, both required for QEMU `-kernel` to - # load the U-Boot ELF at any address. Linux runs at EL1 (no - # secure / no virtualization in QEMU machine). + # - IB_BOOT_CHAIN="uboot" (no ATF): virt64_defconfig too. This tree + # departs from infrabase here, which takes upstream + # qemu_arm64_defconfig for a bare Linux: that U-Boot does not boot + # the SO3 ITB ("Could not find configuration node"), which made the + # default chain unbootable for SO3 standalone, and being + # position-independent with a text base of 0 it can never be read + # off the card by the boot ROM (bsp_virt64.inc). virt64_defconfig + # is linked at a RAM address that QEMU `-kernel` honours, and boots + # both SO3 and Linux. # - IB_BOOT_CHAIN="atf+uboot" and "full" (capsule) both use # virt64_defconfig — same FIP-aware U-Boot, the boot chain # difference lives in ATF (no SPD vs SPD=opteed) and the guest @@ -64,11 +68,7 @@ do_configure () { # absent and Kconfig dies with "syntax error". A host that happens to # have the 64-bit toolchain installed hides the bug. - if [ "${IB_PLATFORM}" = "virt64" ] && [ "${IB_BOOT_CHAIN}" = "uboot" ]; then - make CROSS_COMPILE=${IB_TOOLCHAIN}- qemu_arm64_defconfig - else - make CROSS_COMPILE=${IB_TOOLCHAIN}- ${IB_PLATFORM}_defconfig - fi + make CROSS_COMPILE=${IB_TOOLCHAIN}- ${IB_PLATFORM}_defconfig # Specific handling for bbb platform if [ "${IB_PLATFORM}" = "bbb" ]; then diff --git a/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb b/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb index 604464c73e..d07086bcb0 100644 --- a/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb +++ b/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb @@ -93,8 +93,20 @@ python do_deploy() { d.setVar('ROOTFS_FILENAME', 'rootfs') __do_rootfs_mount(d) - utils_sudo(["rsync", "-a", "--keep-dirlinks", - deploy_src + "/", f"{IB_ROOTFS_PATH}/fs/"], check=True) + + # A failed copy must not leave the extracted, root-owned tree behind, + # as the p2 path below makes sure of for its mount. But not through a + # plain finally: __do_rootfs_umount re-packs the tree INTO rootfs.cpio, + # and a half-copied user space must not end up there. On failure the + # tree is dropped and rootfs.cpio stays as it was; the next deploy + # starts over from it. + try: + utils_sudo(["rsync", "-a", "--keep-dirlinks", + deploy_src + "/", f"{IB_ROOTFS_PATH}/fs/"], check=True) + except Exception: + utils_sudo(["rm", "-rf", os.path.join(d.getVar('WORKDIR'), "fs")]) + raise + __do_rootfs_umount(d) bb.plain("usr deployed into rootfs.cpio (IB_RAMFS_SOURCE = rootfs)") @@ -165,7 +177,10 @@ do_install_apps () { usr_do_install_file_root "${IB_TARGET}/src/modules/*.ko" } -do_clean:append () { +# usr.bbclass defines do_clean in Python, and a shell :append is pasted +# verbatim into that Python function, so `-c clean` died on a SyntaxError. +# The shell stays shell, in its own function, called from a Python append. +usr_linux_clean () { rm -f ${TMPDIR}/stamps/usr-linux* rm -f ${WORKDIR}/*.patch @@ -174,3 +189,7 @@ do_clean:append () { # so a clean removes it entirely (tree, re-attach backup and manifest). rm -rf ${IB_TARGET} ${IB_TARGET}.back ${IB_TARGET}.attach.sha256 } + +python do_clean:append () { + bb.build.exec_func('usr_linux_clean', d) +} diff --git a/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend b/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend index 5393977a31..97b486f29f 100644 --- a/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend +++ b/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend @@ -47,10 +47,17 @@ do_install_apps:append () { fi } -do_clean:append () { +# usr.bbclass defines do_clean in Python, and a shell :append is pasted +# verbatim into that Python function, so `-c clean` died on a SyntaxError. +# The shell stays shell, in its own function, called from a Python append. +usr_linux_clean_lvgl () { if echo ":${OVERRIDES}:" | grep -q ":lvgl"; then rm -rf ${IB_TARGET}/lib/lv_port_linux rm -rf ${WORKDIR}/git fi } + +python do_clean:append () { + bb.build.exec_func('usr_linux_clean_lvgl', d) +} diff --git a/build/meta-usr/recipes-usr/soo/usr-linux_1.0.bbappend b/build/meta-usr/recipes-usr/soo/usr-linux_1.0.bbappend index c9343a4e6d..ee1bdaad47 100644 --- a/build/meta-usr/recipes-usr/soo/usr-linux_1.0.bbappend +++ b/build/meta-usr/recipes-usr/soo/usr-linux_1.0.bbappend @@ -27,7 +27,10 @@ do_install_apps:append () { fi } -do_clean:append() { +# usr.bbclass defines do_clean in Python, and a shell :append is pasted +# verbatim into that Python function, so `-c clean` died on a SyntaxError. +# The shell stays shell, in its own function, called from a Python append. +usr_linux_clean_soo () { if echo ":${OVERRIDES}:" | grep -q ":soo"; then rm -rf ${IB_TARGET}/src/soo @@ -41,3 +44,7 @@ do_clean:append() { fi } + +python do_clean:append () { + bb.build.exec_func('usr_linux_clean_soo', d) +} diff --git a/scripts/dbuild.sh b/scripts/dbuild.sh index 9aef98610f..b46eba72d3 100755 --- a/scripts/dbuild.sh +++ b/scripts/dbuild.sh @@ -119,6 +119,16 @@ fi set -- -e IB_TREE="$IB_ROOT" -e IB_CWD="$cwd" "$@" +# Forward the per-invocation knobs env.sh lets through to bitbake +# (BB_ENV_PASSTHROUGH_ADDITIONS) when they are set on the host. Without it +# `IB_FORCE_ATTACH=1 dbuild.sh build.sh ` — what the attach guard +# itself advises — never reached the container, and the guard kept refusing. + +for _v in IB_FORCE_ATTACH IB_PARTITION_LAYOUT; do + eval "_val=\${$_v:-}" + [ -n "$_val" ] && set -- -e "$_v=$_val" "$@" +done + # Hardware deployment: make any IB_HTTP_DEPLOY_PATH feed directory # visible at its own path so `deploy.sh` can publish into it from inside # (IB_STORAGE_MODE=http). This serves the verdin-imx8mp TEZI flow; on the