The example images
EB corbos Linux comes with arm64 based example images for rpi4 and nxp s32g boards at the moment. To ease development and testing we also provide QEMU arm64 images.
For arm64/qemu we provide example images for EB corbos Linux (EBcL) and for Ubuntu Jammy and Ubuntu Noble. The difference between EBcl and Ubuntu is, that EBcL provides some additional components, like the crinit init-manager and the elos logging and event framework, and that EBcL provides a qualified security maintenance release every three months, while Jammy is proving updates continuously, using less strict qualification and documentation. Additionally there is are amd64 and arm64 example image provided for application development. You can find more about application development in later chapters.
Build-flow for QEMU images
QEMU requires three artifacts to run an image. These artifacts are a kernel binary, a initrd.img binary, and a disc image providing a root filesystem. The build flow, to get these artifacts, is the same for all QEMU images, and we defined it in images/tasks/QEMU_image.yml.
...
build:
desc: Build and run the qemu image
cmds:
- task: boot:extract_kernel
- task: root:build
- task: root:config
- task: initrd:build
- task: embdgen:build
method: none
...
The build steps are:
- The boot:extract_kernel task of the BootGenerator.yml runs the boot_generator to extract the kernel.
- The root:build task of the RootGenerator.yml runs the root_generator to install the defined packages.
- The root:config task of the RootGenerator.yml runs the root_generator to apply the configuration.
- The initrd:build task of the InitrdGenerator.yml runs the initrd_generator build the initrd.img.
- The embdgen:build task of the Embdgen.yml runs the Embdgen to generate the image.raw disc image.
This generic QEMU build task is used by all QEMU images.
The ebcl_1.x QEMU image
In images/arm64/qemu/ebcl_1.x you can find a basic example image demonstrating how to use the EB corbos Linux SDK. The root.yml and the boot.yaml and initrd.yaml include the common images/common/qemu/arm64/base.yaml, which defines the kernel package and the APT repositories used by all QEMU arm64 EBcL images.
The boot.yaml further includes the images/common/qemu/boot.yaml, which describes how to extract the kernel binary in an architecture independent way. Using this includes makes reading the specification a bit harder to ready, but it is a really good way to avoid redundancy and simplify the maintenance of related images.
The initrd.yaml includes the common images/common/qemu/initrd.yaml and images/common/qemu/initrd_jammy.yaml files. The file images/common/qemu/initrd.yaml defines the common parts of all initrd.img used by QEMU, and the file images/common/qemu/initrd_jammy.yaml adds some specifics for the images based on the EBcL 1.x and Ubuntu 22.04 packages. There is another images/common/qemu/initrd_noble.yaml which does the same for the EBcL 2.x and Ubuntu 24.04 packages.
The root.yaml includes the common images/common/arm64/crinit/root.yaml. This file describes the common root filesystem configuration for all arm64 images using the crinit init manager, and also brings in the common crinit and elos runtime configuration.
These includes mechanism and hierarchy allows to structure the runtime configuration of an image as reusable features, similar to the layer mechanism used by Yocto, and the sharing of these configurations allows building up a base of easy usable features, which can be easily integrated in any Debian package based image, using our SDK approach.
Lets take a close look at these configuration fragments. The file images/common/qemu/arm64/base.yaml looks like:
# CPU architecture
arch: 'arm64'
# Kernel package to use
kernel: linux-image-generic
use_ebcl_apt: true
This yaml file defines the used target architecture as arm64, and the used kernel package as linux-image-generic.
The line use_ebcl_apt: true
is a convenience function to specify the EB corbos Linux public APT repository,
and it makes use of the arch parameter.
The kernel package specification is used by the boot_generator, to find the right deb package containing the kernel binary,
and by the initrd_generator to decide which kernel modules ar used.
The file images/common/qemu/boot.yaml looks like:
# Download dependencies of the kernel package - necessary if meta-package is specified
download_deps: true
# Files to copy from the packages
files:
- boot/vmlinuz*
- boot/config*
# Do not pack the files as tar - we need to provide the kernel binary to QEMU
tar: false
The download_deps parameter enables the download of packages specified as dependencies in the Debian package metadata. Setting this flag to true allow using a meta-package like linux-image-generic, instead of a specific kernel version. The files define a list of glob-matches for files which shall be copied to the build folder. This is used to make the kernel binary available for QEMU, and also to get the kernel configuration for information and inspection. If the tar parameter is set to true, the extracted file will be put into a tar archive, which helps to preserve the file attributes, but is not needed for using the kernel with QEMU.
The file images/common/qemu/initrd.yaml looks like:
# Root device to mount
root_device: /dev/vda1
# List of kernel modules
modules:
# virtio modules
- virtio_blk
- failover
- net_failover
- virtio_net
# graphics support
- sysimgblt
- sysfillrect
- syscopyarea
- fb_sys_fops
- drm
- drm_kms_helper
template: init.sh
packages:
# Tools for checking ext4 partitions.
- e2fsprogs
It specifies the root device as /dev/vda1
and a bunch of kernel modules required for full QEMU support.
Without virtio_blk, the boot for QEMU would fail, because the root partition is provided as VirtIO device.
The template parameter allows to provide a user specific init.sh
script,
and the path is relative to the configuration file.
You can find the used script at images/common/qemu/init.sh.
The package e2fsprogs to fix an ext4 filesystem which was mounted in an unclean way,
and without this tools in the initrd.img, you can brick your image by killing QEMU or doing a power cut.
Please be aware that the initrd_generator only extracts the packages and not runs any install scripts.
We handle it this way, because our initrd is intended to be as small as possible,
and therefore misses a lot of packages which are expected to be available for any Debian root filesystem.
The file images/common/qemu/initrd_jammy.yaml add a bunch of additional kernel modules, required for the the firewall, Docker, Podman, graphics support and systemd.
# List of kernel modules
modules:
# virtio modules
- veth
# bridge support - requried by dockerd and podman
- br_netfilter
# nttabes kernel modules - required by dockerd and podman
- nft_compat
- xt_addrtype
- nft_counter
- nf_conntrack_netlink
- nft_chain_nat
- xt_conntrack
- xt_comment
- xt_MASQUERADE
- overlay
- xfrm_user
# dm-verity modules
- dm-verity
# graphics support
- cec
- virtio-gpu
# systemd
- autofs4
The file images/common/arm64/crinit/root.yaml looks like:
base: ../root.yaml
# Additional packages for the crinit variant
packages:
# Init manager
- crinit
- crinit-ctl
# Elos for logging
- elos
- elos-coredump
- elos-plugin-backend-json
- elos-plugin-backend-dummy
- elos-plugin-scanner-kmsg
- elos-plugin-scanner-syslog
- elos-plugin-scanner-shmem
- elos-plugin-client-tcp
# Network manager
- netifd
- udhcpc
- netbase
# NTP time client
- ntpdate
# Crinit configuration
host_files:
- source: config/*
# Scripts to configure the root tarball
scripts:
- name: config_root.sh # Name of the script, relative path to this file
env: chroot # Type of execution environment
It adds the crinit and elos specific packages, and the common packages defined in images/common/root.yaml. Please be aware that the file images/common/root.yaml resets the kernel package because we don’t want to have it installed in the root filesystem. The host_files and the scripts specify the runtime configuration for the packages, which is added during the root filesystem configuration step. These parameters also support glob, and the paths are also relative to the yaml file.
The arm64 Jammy image
In images/arm64/qemu/jammy you can find a basic example image demonstrating how to use the EB corbos Linux SDK to build images for other Debian distributions. It makes use of images/common/qemu/arm64/jammy.yaml, which looks like:
# CPU architecture
arch: 'arm64'
# Kernel package to use
kernel: linux-image-generic
# CPU architecture
apt_repos:
- apt_repo: http://ports.ubuntu.com/ubuntu-ports
distro: jammy
components:
- main
- universe
- apt_repo: http://ports.ubuntu.com/ubuntu-ports
distro: jammy-security
components:
- main
- universe
- apt_repo: http://ports.ubuntu.com/ubuntu-ports
distro: jammy-updates
components:
- main
- universe
The difference to the ebcl_1.x image is, that instead of the EB corbos Linux apt repositories,
the Ubuntu Jammy arm64 APT repositories are used.
The boot and initrd specifications are identical to the ebcl_1.x image,
only the root specification is different, because the systemd init manager instead of crinit is used.
Additionally, another config folder is specified, which overwrites the /etc/hostname
file form the common configuration.
The arm64 Noble image
The arm64 Ubuntu Noble image is identical to the arm64 Ubuntu Jammy image, except two deviations. Instead of the Jammy APT repositories, the Noble APT repositories are specified in images/common/qemu/arm64/noble.yaml, in for the initrd, instead of the Jammy specific kernel modules, the Noble specific kernel modules are used.
This image also gives an example how easy EB corbos Linux images can be upgraded to newer versions or even other base distributions. The restriction that the packages are considered as the smallest building blocks of a image, and that no patching or re-compiling is allowed, results in a highly reduced maintenance effort.