4
0
Fork 0
Build Raspi Alpine image in Docker
Go to file
Benjamin Böhmke 710ff5b186 fixed remount of uboot partition 2019-12-15 16:55:18 +01:00
example added example 2019-11-12 21:02:43 +01:00
resources fixed data prepare init script 2019-12-15 15:29:11 +01:00
.gitignore added network config 2019-11-29 19:53:17 +01:00
Dockerfile added cmd to Dockerfile 2019-11-12 21:01:10 +01:00
README.md added more configurations 2019-11-17 10:58:55 +01:00
go.mod added system config and actions 2019-11-29 22:12:38 +01:00
go.sum added system config and actions 2019-11-29 22:12:38 +01:00
network.go added network config 2019-11-29 19:53:17 +01:00
network_test.go added network config 2019-11-29 19:53:17 +01:00
system.go fixed SystemSetRootPassword 2019-12-15 16:29:06 +01:00
system_test.go fixed SystemSSHEnabled 2019-12-15 16:24:44 +01:00
update.go fixed remount of uboot partition 2019-12-15 16:55:18 +01:00
update_test.go fixed remount of uboot partition 2019-12-15 16:55:18 +01:00

README.md

Raspberry PI Alpine Linux Image Builder

Create minimal Linux images based on Alpine Linux for the Raspberry PI.

Features

  • Alpine base
    • Small image size
    • Fast image build
  • A/B partition schema
    • Simple update of whole system
    • Fallback if update failed
  • Single image for every Raspberry PI
  • Read only root filesystem

Usage

Image Creation

A simple example for a go application can be found in the example directory.

To generate an empty image simply run:

docker run --rm -it -v $PWD/output:/output bboehmke/raspi-alpine-builder

This will create 2 image files in the directory $PWD/output/:

  • alpine.img.gz: complete SD card image for the raspberry
  • alpine_update.img.gz: image of root partition to update running raspberry

For each image a *.sha256 file will be generated to validate integrity.

To add custom modifications mount a script to /input/image.sh. The following variables can be useful for the for and image.sh:

Variable Description
INPUT_PATH Path to input directory
ROOTFS_PATH Path to new root filesystem
BOOTFS_PATH Path to new boot filesystem
DATAFS_PATH Path to new data filesystem

There is also a function chroot_exec that can be used to run command inside the new root filesystem. To enable a service called example_daemon simple run:

chroot_exec rc-update add example_daemon default

Config Variables

The following variables can be used to modify the base behaviour of the image builder.

Variable Default Value Description
ALPINE_BRANCH 3.10 Alpine Branch to use for image
ALPINE_MIRROR http://dl-cdn.alpinelinux.org/alpine Mirror used for package download
CUSTOM_IMAGE_SCRIPT image.sh Name of script for image customizations (relative to input dir)
DEFAULT_HOSTNAME alpine Default hostname
DEFAULT_ROOT_PASSWORD alpine Default password for root user
DEFAULT_TIMEZONE Etc/UTC Default Timezone to use for image
IMG_NAME sdcard Base name of created image file
INPUT_PATH /input Input directory inside container
OUTPUT_PATH /output Output directory inside container
SIZE_BOOT 100M Size of boot partition
SIZE_DATA 20M Initial Size of data partition
SIZE_ROOT_FS 200M Size of root file system
SIZE_ROOT_PART 500M Size of root partition

Update running system

The system can be updated without a complete flash of the SD card from the running system with the following steps:

  1. Transfer the update image to the running system
  2. (Optional) Validate integrity of image with checksum file
  3. Write the image to the actual inactive partition
  4. Switch active partition
  5. Reboot system

An example implementation can be found in the helper script ab_flash

Image structure

Partition Layout

The image contains 4 partitions:

  1. Boot: (Size: SIZE_BOOT)
    Contains boot loader and boot configuration

  2. Root A: (Size: SIZE_ROOT_PART)
    Contains complete root filesystem including all required kernels

  3. Root B: (Size: SIZE_ROOT_PART)
    Same as Root A

  4. Data: (Size: Initial SIZE_DATA & increases on first start)
    Contains persistent data for both root partitions

With the exception of the data partition every partition is mounted read only

The A/B root partitions enables an easy and reliable way to update the complete system. This is done by flashing the inactive partition with a new root filesystem and make this partition active. If this new filesystem does not boot the boot loader will fallback to the old partition.

The root file system should be as small as possible to reduce the update time later. To support future increase of the root file system the partition should contain some free space.

Boot loader

To support the A/B partition schema the U-Boot boot loader is used.

The configuration/script for the boot loader can be found in the boot.cmd. This will boot the active root partition and switch the active partition if the active one will not start.

This script also select the right kernel for old Raspberry PIs

The image contains a simple tool that resets the boot counter and switch the active partition from the running OS. The sources of the script can be found in the uboot.c.