Skip to content

Scripts for building a custom Alpine Linux image for the Raspberry Pi

Notifications You must be signed in to change notification settings

foxt/rpi-alpine-image-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Raspberry Pi Alpine Image Builder

This is a rudimentary script to build a custom Alpine Linux image for the Raspberry Pi. The goals of this project are:

  • Build a custom ramdisk based OSimage for the Raspberry Pi
  • Entirely built on a workstation - i.e. not: put a fresh SD card in the Pi to modify an existing image
  • Built in a 'clean-room' fashion - booting an Alpine image and immediately running lbu commit shows that changes are made to the system during the boot process, and can be based on unique configuration (for example, /etc/resolv.conf is filled in with the DNS server & hostname from DHCP).
  • Netboot and or rpiboot for ease of development.

The image is pretty small. A mostly unmodified image, built on Alpine 3.19 for Raspberry Pi 4B produces a 84.3MB (unpacked) boot image, which can be further shrunk to 66.4MB by removing unused packages, DTBs, etc.

On the memory constrained Raspberry Pi Zero 2W, it leaves about 300M out of the total 430M available for activities.

Process

As Alpine must be built on Alpine, an ephemeral Docker container is used to run the build scripts. The scripts clones the aports repo and uses custom mkimg and genapkovl profiles to generate a tar.gz folder which can be extracted to the root of a FAT32 SD card and inserted into the Pi.

Booting from the network or via rpiboot is possible, however is a little bit more involved, as:

  • Neither netboot or rpiboot can only deliver the Linux kernel and initramfs, for the APKs, modloop & apkovl, these must be delivered via HTTP or FTP.
    • This also means that both netboot and rpiboot require the Raspberry Pi to be connected via an Ethernet connection, thus, meaning this cannot be performed on the Zero or the Pi 3A.
    • It may be possible to include wpa_supplicant into the initramfs to allow rpiboot to work on the Zero over Wifi (it doesn't seem there's a clean way to do this), USB ethernet for the 1A/3A and CM1/3/3+/4S. More investigation is needed.
  • Netboot requires a SFTP server to deliver the files.
  • On Pi 4 and 5, the SFTP server IP address can be configured in the EEPROM. On the Pi3, this must be handed out by the DHCP server.
  • A script is provided for network booting via a direct ethernet cable to the Pi by starting a dnsmasq DHCP server on the workstation.
  • A script is also included for macOS users to use rpiboot. This must be installed separately. TODO: convert the boot.img generation script to a Linux script for use in the Docker container.

Configurations

  • 🚫 - Impossible - lacks hardware support.
  • 🔥 - Tested, does not work.
  • 👎 - Untested - likely not working.
  • - Untested - possibly working.
  • - Works

Image architecture

Model aarch64 armv7 armhf Notes
Pi 5 👎 👎
Pi 4/CM4/CM4S/400 🔥 🔥 Tested on a Pi 4 (v1.2) 4GB.
Pi 3/3+/CM3/CM3+/Zero2 🔥 Tested on a Pi 3B 1.2 and a Pi Zero 2W
Pi 2B 👎
Pi 1A/1B/CM1/Zero 🔥 🔥 Tested on a Pi Zero W

Boot methods

The SD card can deliver the kernel, initramfs, APKs, modloop and apkovl. Netboot and rpiboot can only deliver the kernel and initramfs. The rest must be delivered via HTTP or FTP.

When using rpiboot, with a Pi 4, its better to build the boot folder into a boot.img, however this doesn't seem to work on previous models.

Model SD Card Bootloader via Netboot Bootloader via rpiboot Rest via HTTP/FTP Notes
Pi 5
Pi 4/CM4/400 Tested on a Pi 4 (v1.2) 4GB. Tested with onboard ethernet and a USB ethernet adapter. Can be configured either by DHCP or EEPROM option
Pi CM4S 👎
Pi 3B, 3B+ 🚫 Tested on a Pi 3B (v1.2). Onboard ethernet only, USB eth not working.
Pi 3A 🚫 👎
Pi Zero 2 🚫 🔥 USB ethernet not working.
Pi 2B
Pi Zero 🚫 🔥 USB ethernet not working. My Pi Zero wont go into rpiboot mode. Further investigation required.
Pi 1B 🚫 🚫
Pi 1A, CM1 🚫 👎

Troubleshooting

Booting

Generally, make sure you copied the entire boot folder to a FAT32 MBR formatted disk, not named the same of any as the directories on it (i.e. boot), you properly ejected the disk, and your Pi has a good enough power supply.

Rainbow or black screen

This means the Pi could not load the kernel. Ensure you're using the right architecture for the Pi model you're running. This may also occur when using rpiboot with a raw folder. Package the folder into a FAT32 boot.img instead.

/dev/root cannot open block device, Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

This means the Pi could not load the boot/initramfs-pi file. The common reason is due to the SFTP server lacking permissions to read the file.

Mounting boot media failed

This means the Pi could not mount the boot media - for network booting this means that no network connection is possible. Ensure cmdline.txt is configured with the correct IP configuration & links to download the rest of the system image. Check netboot.sh for the correct cmdline.txt configuration.

/sbin/init not found in new root

Your Pi couldn't download the APKs, or the signature is incorrect. Check your HTTP server logs, and make sure the APKs are signed using the correct key.

Boots, but no customisations are applied

This means the Pi couldn't download the apkovl. Check your HTTP server logs and cmdline.txt.

Flashing cursor with Raspberry Pi logo(s)

This is normal! The Pi is booting, but the console is not being displayed. This is because the netboot scripts configure the Pi to use the UART console. You can change this to output over HDMI by editing cmdline.txt and removing console=serial0,115200.

About

Scripts for building a custom Alpine Linux image for the Raspberry Pi

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages