The U-Boot env file is generated by mkenvimage, which prefixes the variable data with a 4-byte CRC32 by default. ixpreboot.sh previously imported it with `env import -b` as per uboot docs(-b assume binary format (’0’ separated, “00” terminated).), which treats the buffer as raw binary and does not strip the CRC. As a result the first variable's name is parsed a part of CRC. Later variables import correctly because by then the parser is past the CRC. Switching to `env import -c` as per uboot docs (-c assume checksum protected environment format.) makes U-Boot validate and strip the CRC before parsing, so the first variable imports under its real name. Tested on: - QEMU Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
Marvell ESPRESSObin
The ESPRESSObin is a single-board computer based on the Marvell Armada 3720 (dual Cortex-A53, AArch64) SoC and the Marvell 88E6341 (Topaz) switch, oriented toward networking applications.
The board design is old but the switch offers full Linux support, including advanced TSN features for IEEE 1588-2019 (PTP) and IEEE 802.1AS-2020 (gPTP).
Board Variants
The board has gone through several hardware revisions:
| Revision | Storage | Notes |
|---|---|---|
| v1, v3, v5 | SPI NOR only | Obsolete; U-Boot always in SPI |
| v7 | SPI NOR + 4 GB eMMC | Current; SD and eMMC usable |
| Ultra | SPI NOR + 4 GB eMMC | High-end variant |
On all revisions the Boot ROM is hardwired to load U-Boot from SPI NOR flash. There is no strap or jumper to make the Boot ROM load directly from an SD card. The SD card (or eMMC on v7/Ultra) is used only for the operating system.
Building
The ESPRESSObin uses ext4 for its rootfs partitions rather than the default
squashfs, because the stock SPI U-Boot lacks squashfs and blkmap support.
The ext4 configuration snippet enables this. Apply it once after selecting
the defconfig, then build and compose the SD card image:
make O=x-aarch64 aarch64_defconfig
make O=x-aarch64 apply-ext4
make O=x-aarch64
utils/mkimage.sh -r x-aarch64 marvell-espressobin
The resulting image (x-aarch64/images/infix-espressobin-sdcard.img) contains
a GPT disk with the standard Infix partition layout, using ext4 instead of the
read-only squashfs:
| Partition | Label | Contents |
|---|---|---|
| 1 | aux | RAUC upgrade state (ext4) |
| 2 | primary | Rootfs slot primary (ext4) |
| 3 | secondary | Rootfs slot secondary (ext4) |
| 4 | cfg | Persistent config (ext4) |
| 5 | var | Runtime data (ext4) |
Writing to SD Card
dd if=infix-espressobin-sdcard.img of=/dev/sdX bs=4M status=progress conv=fsync
Upgrading
The build produces x-aarch64/images/infix-aarch64-ext4.pkg, a RAUC bundle
containing the ext4 rootfs. Once the board is running Infix, upgrade over the
network in the usual way:
upgrade ftp://192.168.1.1/infix-aarch64-ext4.pkg
RAUC writes the new rootfs to the inactive slot, updates BOOT_ORDER in
/mnt/aux/uboot.env, and the next boot picks it up automatically.
Note
Use
infix-aarch64-ext4.pkg, not the standardinfix-aarch64.pkg. The standard bundle contains a squashfs rootfs which the stock U-Boot cannot boot.
Booting with the Stock SPI U-Boot
The stock Marvell U-Boot has ext4load and the standard variables
($kernel_addr, $fdt_addr, $loadaddr, $console, $image_name,
$fdt_name) already set sensibly. Connect to the board's console port, the
micro USB connector, at 115200 8N1, interrupt autoboot, and paste the commands
below.
Environment Variable Reference
These variables are pre-set in the stock U-Boot environment. Restore them with these values if they are ever lost or corrupted:
setenv kernel_addr 0x5000000
setenv fdt_addr 0x4f00000
setenv loadaddr 0x5000000
setenv console 'console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000'
setenv image_name boot/Image
setenv extra_params quiet
$fdt_name selects the device tree for your specific board revision:
| Board revision | fdt_name value |
|---|---|
| v3 / v5 | boot/marvell/armada-3720-espressobin.dtb |
| v7 | boot/marvell/armada-3720-espressobin-v7.dtb |
| Ultra | boot/marvell/armada-3720-espressobin-ultra.dtb |
| v3/v5 eMMC | boot/marvell/armada-3720-espressobin-emmc.dtb |
| v7 eMMC | boot/marvell/armada-3720-espressobin-v7-emmc.dtb |
setenv fdt_name boot/marvell/armada-3720-espressobin.dtb # adjust for your board
Simple Boot
Fixed boot from the primary slot, useful for initial bring-up:
setenv bootcmd 'mmc dev 0; \
ext4load mmc 0:2 $kernel_addr $image_name; \
ext4load mmc 0:2 $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=primary rw rootwait $extra_params rauc.slot=primary; \
booti $kernel_addr - $fdt_addr'
saveenv
Automatic Slot Selection (RAUC Integration)
The CLI upgrade command writes to the inactive slot and updates uboot.env
on the aux partition with the new boot order. On the next boot U-Boot reads
BOOT_ORDER from the aux partition and selects the appropriate slot. The
setup below also defines bootcmd_primary, bootcmd_secondary, and
bootcmd_net for manual use (see Manual Slot Selection
and Netbooting):
setenv bootcmd_boot \
'mmc dev 0; \
ext4load mmc 0:$bootpart $kernel_addr $image_name; \
ext4load mmc 0:$bootpart $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=$bootslot rw rootwait $extra_params rauc.slot=$bootslot; \
booti $kernel_addr - $fdt_addr'
setenv bootcmd_primary 'setenv bootpart 2; setenv bootslot primary; run bootcmd_boot'
setenv bootcmd_secondary 'setenv bootpart 3; setenv bootslot secondary; run bootcmd_boot'
setenv bootcmd_net \
'dhcp $kernel_addr $image_name; \
tftpboot $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=primary rw rootwait $extra_params rauc.slot=primary; \
booti $kernel_addr - $fdt_addr'
setenv bootcmd \
'setenv bootpart 2; setenv bootslot primary; setenv auxpart 1; \
if ext4load mmc 0:$auxpart $loadaddr /uboot.env; then \
env import -c $loadaddr $filesize BOOT_ORDER; \
fi; \
if test "$BOOT_ORDER" = "secondary primary" || \
test "$BOOT_ORDER" = "secondary primary net"; then \
setenv bootpart 3; setenv bootslot secondary; \
fi; \
if test "$BOOT_ORDER" = "net" || \
test "$BOOT_ORDER" = "net primary" || \
test "$BOOT_ORDER" = "net secondary primary"; then \
run bootcmd_net; \
fi; \
echo ">> Booting $bootslot from mmc 0:$bootpart ..."; \
run bootcmd_boot'
saveenv
Manual Slot Selection
To boot a specific slot without waiting for the autoboot countdown, interrupt the bootloader (press any key) and run one of the convenience commands defined above:
run bootcmd_primary # boot from primary (partition 2)
run bootcmd_secondary # boot from secondary (partition 3)
run bootcmd_net # netboot via DHCP/TFTP
You can also force a permanent change to which slot boots next by setting
BOOT_ORDER directly from Linux (the change persists across reboots):
fw_setenv BOOT_ORDER "secondary primary" # next boot: secondary
fw_setenv BOOT_ORDER "primary secondary" # next boot: primary (default)
Netbooting
The stock U-Boot supports TFTP. This is useful for testing a new kernel or
device tree without reflashing the SD card. Set up a TFTP server with the
contents of the Infix boot/ directory (from the built rootfs at
x-aarch64/target/boot/) and configure the variables:
setenv serverip 192.168.1.1 # IP of your TFTP server
setenv ipaddr 192.168.1.100 # board IP (omit if using dhcp)
saveenv
Then netboot manually:
run bootcmd_net
bootcmd_net uses dhcp to obtain an IP address and the $serverip from
the DHCP server (option 66), then downloads $image_name and $fdt_name
via TFTP. The kernel mounts the primary SD card slot as root, so the SD
card must still be present.
To make netbooting the default on next boot (e.g. for iterative kernel
development), set BOOT_ORDER from Linux:
fw_setenv BOOT_ORDER "net primary secondary"
This causes bootcmd to attempt netboot first; on failure it falls through
to the primary slot on the SD card.