5. Debian image guide

As opposed to Yocto, Debian does not provide a completely integrated build experience by itself. Linux kernel and U-Boot have to be compiled manually and copied to the appropriate directory to be picked up by Debian build system.

This chapter will go through all neccessary steps, finally building a complete image using the debos Debian image builder. The result will be a fully-functional Debian system.

Alternatively, prebuilt images can be downloaded from https://downloads.embedded.cherry.de/ringneck/.

At the time of writing this document, the following Debian image variants are available for RINGNECK SOM-PX30-uQ7:

  • Debian 13 Trixie,

  • Debian 13 Trixie with Phosh graphical shell.

Note

While Debian is a great tool for fast prototyping of your product, it is highly recommended to use a distribution/image tailored to your need. This can be achieved by Yocto (Section 6 Building a Yocto image) or Buildroot for example.

5.1. Prepare the host PC

The debos Debian OS Builder is only available for Debian and Debian-based distributions (like Ubuntu). This chapter assumes you use Debian or a Debian-based distribution as the host PC.

Install packages for compiling the parts and the complete image:

sudo apt-get -y install debos git build-essential gcc-aarch64-linux-gnu make bison bc flex \
  libssl-dev device-tree-compiler python3-dev python3-pkg-resources swig fdisk \
  bmap-tools python-is-python3 python3-setuptools python3-pyelftools libgnutls28-dev \
  debhelper rsync

As debos internally uses kvm virtualization, your user must be a member of the kvm group:

sudo adduser "$(id -un)" kvm

Log out and back for the change to take affect. Then verify that kvm is listed in your groups:

id -Gn

Note

If you are not using Debian distribution on your host PC you need to use podman to build debos image:

sudo apt-get install podman

5.2. Compile TF-A

Get the source code and compile the Trusted Firmware-A (or TF-A) as follows:

# Set up cross-compilation
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

# Download the source code
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git

(
cd trusted-firmware-a || return

# Use most recent release, the latest annotated tag reachable from master
LAST_V_TAG=$(git describe --abbrev=0 --match "v?*.?*.?*")
# Find all tags from different branches that contain that latest tag reachable from master.
# This will return lts tags, of which we want to take the latest available.
# If no LTS tag, take the latest non-rc tag reachable from master.
LAST_LTS_TAG=$(git tag --sort -version:refname --contains "$LAST_V_TAG" 'lts-v?*.?*.?*' | head -1)
TAG=${LAST_LTS_TAG:-$LAST_V_TAG}
git checkout "$TAG"

# Compile
make PLAT=px30 bl31
)

# Make the resulting file available to later steps
export BL31="$PWD/trusted-firmware-a/build/px30/release/bl31/bl31.elf"

This step should take under 1 minute total.

5.3. Compile U-Boot

Note

The variable BL31 must be already set as described in Section 5.2 Compile TF-A .

Get the source code and compile the U-Boot bootloader as follows:

# Set up cross-compilation
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

# Download the source code
git clone https://git.embedded.cherry.de/ringneck-u-boot.git

(
cd ringneck-u-boot || return

# Compile
make ringneck-px30_defconfig
make -j"$(nproc)"
)

# Make the resulting file available to later steps
export RINGNECK_UBOOT_DIR="$PWD/ringneck-u-boot"

This step should take about 1 minute total.

5.4. Compile the Linux kernel

Get the source code and compile the Linux kernel as follows:

# Set up cross-compilation
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

# Download the source code
git clone https://git.embedded.cherry.de/ringneck-linux.git

(
cd ringneck-linux || return

# Compile
make ringneck-px30_defconfig
make -j"$(nproc)"
make KBUILD_IMAGE=arch/arm64/boot/Image -j"$(nproc)" bindeb-pkg
)

KERNELRELEASE=$(make -C ringneck-linux -s kernelrelease)
# We must take care to not match the "-dbg" package or older builds here
# shellcheck disable=SC2012
RINGNECK_LINUX_DEB=$(ls -1t "$PWD"/linux-image-"$KERNELRELEASE"_*.deb | head -1)
ls -l "$RINGNECK_LINUX_DEB"
export RINGNECK_LINUX_DEB

The time required for this step heavily depends on your internet connection and CPU power. On a quad-core 2.9GHz machine with an 1Gb/s internet connection, it takes about 20 minutes total.

Warning

It is essential the kernel modules installed on the system are built from the exact same sources as the kernel Image itself or the modules will fail to be detected by the kernel.

Note

One can install new modules without needing to recompile the debos image entirely by running the following command:

export IP=10.11.12.13 # set to the IP address of the device
rsync --delete --recursive overlay/lib/modules/ root@"$IP":/lib/modules

Update the kernel Image if there was some change made to it so that it will find the new modules upon reboot.

Reboot for the new modules to be loaded.

5.5. Building the debos image

5.5.1. Prepare required components

Note

The variables RINGNECK_UBOOT_DIR and RINGNECK_LINUX_DEB must be already set as described in Section 5.3 Compile U-Boot and Section 5.4 Compile the Linux kernel, respectively.

Get the source code for the debos recipe and copy necessary components built in previous steps:

# Download the source code
git clone https://git.embedded.cherry.de/debos-recipes.git
cd debos-recipes || return

# Make sure there's no deb package from previous kernel builds
rm --force ringneck/overlay/var/tmp/linux-*.deb

# Copy linux-image deb package into the ``ringneck`` folder.
# It will be installed from within debos.
mkdir --parents --verbose ringneck/overlay/var/tmp
cp --verbose "$RINGNECK_LINUX_DEB" ringneck/overlay/var/tmp

# Copy U-Boot binaries into the ``ringneck`` folder
cp "$RINGNECK_UBOOT_DIR"/u-boot-rockchip.bin ringneck

5.5.2. Build a complete image

Different variants of Debian images are available. You can build the one of your choice or all of them. Default variant is Debian 13 Trixie. Other variants can be chosen by setting the debos_variant environment variable when running build.sh.

Depending on your host PC and internet connection, this step should complete in about 5-10 minutes.

The resulting image is a file called sdcard-ringneck-debos-VARIANT.XXX.YYY.img and, for convenience, the symlink sdcard-ringneck-debos-VARIANT.img that always points to the latest version.

5.5.2.1. Debian 13 Trixie

# Build the image
build_board=ringneck ./build.sh

# Or: Build the image using podman (For host PCs not using Debian)
# build_board=ringneck debos_host=podman ./build.sh
#
# Or: Build the image using chroot (For inside virtual machines without nesting support)
# build_board=ringneck debos_host=chroot ./build.sh

# Make the resulting image available to later steps
export SDCARD_IMG="$PWD/sdcard-ringneck-debos-trixie.img"

Note

When running inside a virtual machine that does not support nesting, you may get an error like this:

open /dev/kvm: no such file or directory

In this case, use the debos_host=chroot example as given at the beginning of the section.

The debos_host=chroot mode uses sudo internally as it requires root permissions.

5.5.2.2. Debian 13 Trixie with Phosh graphical shell

This image variant is targeted for the Haikou-Video-Demo. Please see the DEVKIT ADDON CAM-TS-A01 User Manual for more information about the DEVKIT ADDON CAM-TS-A01.

More details about the Phosh graphical shell can be found in the Phosh graphical shell section.

# Build the image
build_board=ringneck debos_variant=trixie-phosh ./build.sh

# Or: Build the image using podman (For host PCs not using Debian)
# build_board=ringneck debos_variant=trixie-phosh debos_host=podman ./build.sh
#
# Or: Build the image using chroot (For inside virtual machines without nesting support)
# build_board=ringneck debos_variant=trixie-phosh debos_host=chroot ./build.sh

# Make the resulting image available to later steps
export SDCARD_IMG="$PWD/sdcard-ringneck-debos-trixie-phosh.img"

Note

When running inside a virtual machine that does not support nesting, you may get an error like this:

open /dev/kvm: no such file or directory

In this case, use the debos_host=chroot example as given at the beginning of the section.

The debos_host=chroot mode uses sudo internally as it requires root permissions.