1.20. Devboot¶
Devboot is a development convenience that builds on top of the
boot override mechanism. It sources a per-user,
per-board script from the network and translates it into boot -o
arguments, making it easy to redirect any combination of kernel, device tree
and initrd to network-hosted files without touching the boot medium.
1.20.1. Boot overrides¶
Enable CONFIG_BOOT_OVERRIDE to allow partial overrides of boot entries.
This is already enabled in multi_v7_defconfig and multi_v8_defconfig.
The boot command then accepts one or more -o flags:
boot -o bootm.image=/mnt/tftp/my-zImage mmc
boot -o bootm.oftree=/mnt/tftp/my-board.dtb mmc
boot -o bootm.initrd=/mnt/tftp/my-initrd mmc
Multiple overrides can be combined in a single invocation:
boot -o bootm.image=/mnt/tftp/zImage \
-o bootm.oftree=/mnt/tftp/board.dtb \
-o bootm.initrd=/mnt/tftp/initrd \
mmc
Overrides are applied after the boot entry has been loaded, so the original entry still selects the boot handler, kernel arguments, etc. Only the specified components are replaced.
1.20.1.1. Override rules¶
bootm.imageThe override file is probed for its type. If it is a FIT image, the FIT configuration is re-opened and all components (kernel, initrd, device tree) are taken from the override FIT. If it is a plain kernel image (zImage, Image, uImage, …), only the OS loadable is replaced.
bootm.oftreeA colon-separated list of files. The first entry is the base device tree; subsequent entries are applied as overlays:
# Use a as the device tree boot -o bootm.oftree=a mmc # Use a as the device tree, apply b as overlay boot -o bootm.oftree=a:b mmc # Keep the existing device tree, apply b as overlay boot -o bootm.oftree=:b mmc # Use a as the device tree, apply b and c as overlays boot -o bootm.oftree=a:b:c mmc
Setting
bootm.oftreeto an empty string (bootm.oftree=) discards whatever device tree the boot entry provides. IfCONFIG_BOOTM_OFTREE_FALLBACKis enabled (the default), the barebox-internal device tree is passed to the kernel instead. If the option is disabled, no device tree is passed at all.bootm.initrdA colon-separated list of initrd/CPIO files. Linux can transparently extract any number of concatenated CPIOs, even if individually compressed. A leading colon appends to the initrd that the boot entry already provides:
# Replace with a single initrd boot -o bootm.initrd=/mnt/tftp/initrd mmc # Concatenate two initrds boot -o bootm.initrd=initrd1:initrd2 mmc # Append an extra CPIO to the existing initrd boot -o bootm.initrd=:extra.cpio mmc
Tip
The Linux kernel
make cpio-modules-pkgtarget builds a CPIO archive containing all kernel modules. This is useful for supplementing an existing initramfs with modules without modifying the root filesystem. Combined with initrd concatenation, a devboot script can append it to any boot entry’s initrd:devboot_initrd=":afa-modules-arm64"
To make use of the modules, the initramfs init will need to make initramfs /modules available to the rootfs, e.g. via a bind mount:
mount -n –bind /lib/modules ${ROOT_MOUNT}/lib/modules
Note
When secure boot is enforced (bootm_signed_images_are_forced()),
overrides are silently ignored.
1.20.2. The devboot script¶
The devboot command (/env/bin/devboot) automates the override
workflow for network-based development:
Brings up the network (
ifup -a1).Changes into the fetch directory (global.net.fetchdir, default
/mnt/tftp).Sources a configuration script named
${global.user}-devboot-${global.hostname}. If that file does not exist, it falls back to${global.user}-devboot-${global.arch}.Translates the variables set by the script into
boot -oarguments.Passes any extra arguments through to the
bootcommand.
Note
TFTP is not a real file system, e.g., listing of directories is not possible. Keep that in mind if the devboot script does more than just fetch files by name from TFTP.
1.20.2.1. Usage¶
# Boot from MMC with devboot overrides
devboot mmc
# Boot from the default boot entry
devboot
1.20.2.2. Configuration script¶
The configuration script lives in the fetch directory and sets up to three variables:
devboot_imageOverride for
bootm.image. Path is relative to the fetch directory.devboot_oftreeOverride for
bootm.oftree. An empty string discards the boot entry’s device tree (seebootm.oftreerules above).devboot_initrdOverride for
bootm.initrd. A leading colon appends to the boot entry’s existing initrd.
Variables that are not set (using [[ -v ... ]]) are left alone,
so unset variables do not generate override arguments.
The script can also set arbitrary barebox variables, for example kernel command line fragments:
# /tftpboot/afa-devboot-rock3a
devboot_image=afa-fit-rock3a
devboot_oftree=
devboot_initrd=":afa-rsinit-arm64"
global linux.bootargs.dyn.rsinit="rsinit.bind=/lib/modules"
With this script in place and global.user=afa, global.hostname=rock3a,
running devboot mmc on the board expands to:
boot -o bootm.image="afa-fit-rock3a" \
-o bootm.oftree="" \
-o bootm.initrd=":afa-rsinit-arm64" \
mmc
This fetches the FIT image afa-fit-rock3a from the fetch directory,
discards the FIT’s device tree (falling back to the barebox-internal one
when CONFIG_BOOTM_OFTREE_FALLBACK is enabled), and appends the
afa-rsinit-arm64 CPIO archive to whatever initrd the FIT already
contains.
1.20.2.3. Setting up the variables¶
The global.user and global.hostname variables control which
script is loaded. Make them persistent with:
nv user=afa
nv hostname=rock3a
global.hostname is typically derived from the device tree, but can be
overridden.
1.20.2.4. Forwarding a remote build directory over the internet¶
If the build server is not reachable from the Device-Under-Test, one possibility is to forward the build artifacts to a local TFTP server via SSHFS:
sshfs -o follow_symlinks,allow_other buildserver:/tftpboot /tftpboot
The local development host can then export /tftpboot via TFTP.
If the TFTP server is not running on the local development host, the
dpipe utility can be used to connect a local SFTP server process to
an SSH session that runs sshfs in slave mode on the remote machine:
dpipe /usr/lib/openssh/sftp-server = ssh a3f@tftpserver.in-my.lan sshfs -o slave,follow_symlinks,allow_other -o idmap=user -o gid=1001 :/tftpboot /tftpboot
This works as follows:
dpipeconnects the standard input/output of both sides of=.The left side runs the local SFTP server, giving the remote end access to the local filesystem.
The right side runs
sshfson the TFTP server host inslavemode, reading SFTP protocol directly from stdin instead of spawning its own SSH connection.follow_symlinksresolves symlinks on the build host, so the TFTP server sees regular files even if the build tree uses symlinks.allow_otherpermits the TFTP daemon (which typically runs as a different user) to read the mounted files.idmap=usermaps the remote user’s UID to the local user, avoiding permission issues.gid=1001sets the group ID for all files (adjust to match the group that the TFTP daemon runs as on the server, e.g.tftpornogroup).The colon prefix in
:/tftpbootrefers to the root of the local (build host) filesystem as exported by the SFTP server.
The result is that /tftpboot on the remote TFTP server mirrors the
/tftpboot directory on the build host. Build output can be
symlinked there and the board will fetch it directly over TFTP.
To undo the mount, terminate the dpipe process and run
fusermount -u /tftpboot on the TFTP server.
Note
On Debian/Ubuntu, dpipe can be installed via apt install vde2
sshfs and fuse must be installed on the TFTP server.
/etc/fuse.conf on the server must have user_allow_other
enabled for allow_other to work.