Table of Contents

AVH supports running custom Linux firmware packages.

This guide outlines the contents of a valid Ubuntu firmware package, provides a script for building the Ubuntu Server firmware, and walks through the installation on a virtual Raspberry Pi 4 board.

This packaging process follows the Understanding Firmware on AVH knowledge base article and uses the Raspberry Pi image of Ubuntu Server available directly from Ubuntu.

Please also refer to our companion guide Package Ubuntu Desktop Firmware for AVH.


Firmware Package Contents

A proper Ubuntu Server firmware package file contains the following:

  • Info.plist - the version, type, build, unique identifier, and device identifier

  • nand - the preinstalled Ubuntu Server arm64 image file

  • devicetree - hardware components data for the Linux kernel

  • kernel - the Linux kernel file

  • ramdisk.img (optional) - the initrd root file system image

Although specifying a ramdisk.img is generally optional, we need to add a reboot command in this case because of how this virtual device handles the first pass.


Firmware Packaging Script

The following script creates a custom firmware package in your working directory:

#!/bin/bash
set -e
mkdir rpi_ubuntu_server_firmware
cd rpi_ubuntu_server_firmware
# Download and extract the "Ubuntu 22.04.1 Server for RPi" image
wget https://cdimage.ubuntu.com/releases/22.04.1/release/ubuntu-22.04.1-preinstalled-server-arm64+raspi.img.xz
xz -dv ubuntu-22.04.1-preinstalled-server-arm64+raspi.img.xz
mv ubuntu-22.04.1-preinstalled-server-arm64+raspi.img nand
# Attach the image file
LO="$(losetup -f)"
losetup -P "${LO}" nand
# Mount partition 1 to directory boot
mkdir boot
mount "${LO}p1" boot
# Copy the rpi4b devicetree
cp boot/bcm2711-rpi-4-b.dtb devicetree
# Extract the Linux kernel
zcat boot/vmlinuz > kernel
# Extract initrd
lz4 -d boot/initrd.img initrd.cpio
umount boot
rm -r boot/
losetup -d "${LO}"
mkdir ramdisk
cd ramdisk
# Extract initrd
cat ../initrd.cpio | cpio -idm
rm ../initrd.cpio
# Add reboot conditional to init before matching string
sed -i '/Move virtual filesystems over to the real filesystem/i \
if /bin/grep init_resize /proc/cmdline; then\
/bin/reboot -f\
fi\
' init
# Create ramdisk.img from directory
find . | cpio -o -H newc -R root:root | lz4 -l > ../ramdisk.img
cd ..
rm -r ramdisk/
# Create the Info.plist file
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>Ubuntu Server on RPi</string>
<key>DeviceIdentifier</key>
<string>rpi4b</string>
<key>Version</key>
<string>22.04.1</string>
<key>Build</key>
<string>Ubuntu Server</string>
</dict>
</plist>
EOF
zip -rm ../rpi4b-ubuntu-server.zip Info.plist nand devicetree kernel ramdisk.img
cd ..
rm -r rpi_ubuntu_server_firmware/


Install the Package

  1. Run the above shell script on your local Linux environment to create the firmware package rpi4b-ubuntu-server.zip.

  2. On the AVH web interface, click CREATE DEVICE.

  3. In Step 1, choose the Raspberry Pi 4 and click NEXT.

  4. In Step 2, upload the custom firmware package. When the process is complete, click NEXT.

  5. Create the device without enabling advanced boot options.

  6. The virtual board will boot to the Ubuntu Server login screen. Login with the default credentials (ubuntu/ubuntu) and change your admin password.

    Note: Since we are using a custom configuration, you will need to adjust the SSH commands under the CONNECT tab to use ubuntu as the username instead of the default (pi).

Did this answer your question?