Overview
AVH supports two types of firmware images.
A zip file containing multiple images such as a disk image, kernel or binary firmware etc
A raw binary file, ELF executable or kernel loaded into RAM
Zip package
The format of the zip package looks like this -
Required files:
Info.plist
(meta information)If what you are booting is Linux -
kernel
(a Linux kernel in theImage
format)devicetree
(the device tree for Linux in binary.dtb
format)
Or if it's a raw firmware (e.g. used by Cortex-M machines)
firmware
(Binary, ELF executable file, ZIP archive with load instructions)
Storage
Most devices have flash specific files that are required. See the relevant storage files page for that specific device.
What does the Info.plist
look like?
An Info.plist
file containing the version, type, build, unique identifier and device identifier.
Example
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Type</key>
<string>iot</string>
<key>UniqueIdentifier</key>
<string>WifiBasics</string>
<key>DeviceIdentifier</key>
<string>stm32u5-b-u585i-iot02a</string>
<key>Version</key>
<string>WifiBasics</string>
<key>Build</key>
<string>WB</string>
</dict>
</plist>
Formats of raw firmware
There are three supported formats for executable firmware:
ELF executable: 32-bit ELF program files (fully linked, no relocation required) typically produced by IoT vendor tools: recommended - they contain all information needed to load the program, even if it has multiple memory ranges;
binary: loaded at a predefined location in memory (typically start of Flash for devices with built-in executable Flash, otherwise start of RAM);
ZIP archive: an archive containing a few binary files, and a file called
LOAD.TXT
that instructs the firmware loader to distribute them to different load locations in memory; aLOAD.TXT
file could look like this:
load:0x00000000 name:bl2.bin
load:0x01000000 name:tfm_s_ns_signed.bin
This LOAD.TXT
file would cause file bl2.bin
in the same ZIP archive to be loaded at address 0x00000000, and tfm_s_ns_signed.bin
at 0x01000000. This format is required when all that's available is binary files, and there's more than one of them.
Sample Firmware Packaging Script for Raspberry Pi
#!/bin/bash
set -e
[ -d pi ] || mkdir pi
cd pi
# Grab the raspberry pi firmware
[ -f 2022-01-28-raspios-bullseye-arm64.zip ] || wget https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2022-01-28/2022-01-28-raspios-bullseye-arm64.zip
rm -rf {nand,devicetree,kernel,Info.plist,boot,rootfs}
unzip 2022-01-28-raspios-bullseye-arm64.zip
mv 2022-01-28-raspios-bullseye-arm64.img nand
# Mount the firmware image and extract the kernel and device tree
LO="$(losetup -f)"
mkdir boot
losetup -P "${LO}" nand
mount "${LO}p1" boot
# Enable ssh
touch boot/ssh
cp boot/bcm2711-rpi-4-b.dtb devicetree
zcat boot/kernel8.img > kernel
umount boot
rm -rf boot
mkdir rootfs
mount "${LO}p2" rootfs
# Don't run dhcpcd on docker interfaces
echo 'denyinterfaces veth*' >> rootfs/etc/dhcpcd.conf
umount rootfs
rm -rf rootfs
losetup -d "${LO}"
# create the Info plist that describes the model image
cat << EOF > Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Type</key>
<string>iot</string>
<key>UniqueIdentifier</key>
<string>Raspberry Pi OS Desktop</string>
<key>DeviceIdentifier</key>
<string>rpi4b</string>
<key>Version</key>
<string>11.2.0</string>
<key>Build</key>
<string>desktop</string>
</dict>
</plist>
EOF
# zip image and its ready for use
zip -r ../rpi4b-11.2-desktop.zip Info.plist nand devicetree kernel ramdisk.img