Documentation

Doc quicklinks

Quick Start

For a super quick start, click here to launch the sample qemu device project in GitPod. Detailed steps and screenshots using GitPod available See gitpod

Once gitpod has created your workspace, you can skip ahead to the build instructions. If you wish to setup on your own docker environment, follow steps below.

No other Linux embedded environment will get you started as fast as Sabaton! The powerful tools shipped with Rust makes intgrating the build environment a breeze. The build environment is also written in Rust and integrates well with Rust tools.

The Sabaton NDK for aarch64 and armv7 are published on Docker Hub. It is recommended that you use Docker containers for development. This keeps the development environment self-sufficient and easy to manage.

Setting up

Ensure Docker is installed.

Preparing Development Container

First, create a Docker volume to use as the workspace. All the code and build artifacts will reside in this workspace volume. This makes it easy to update to a new version of the NDK.

docker volume create sabaton-workspace

Now run the NDK container with the previously created container mounted. There is no entry-point defined in the docker container; so to keep it running, we execute /bin/bash. Replace the <version> with the latest version available in docker hub. You will find the list of released images in Releases

docker run -it -v sabaton-workspace:/home/sabaton sabatonrs/sabaton-ndk-armv8a:<version> /bin/bash

Make sure you choose the right image name and version. NDK images may be hosted in Docker Hub or in an internal docker store.

Remember that the volume we created is mounted at /home/sabaton/ . All development activity must be limited to this folder (and sub-folders).

Install the Sabaton command-line utility

Check for the latest version of the Sabaton utility at https://developer.sabaton.dev/releases/#sabaton-command-line-tool

wget http://sabaton.systems/releases/sabaton/0/sabaton_0.1.1_amd64.deb
sudo dpkg -i sabaton_0.1.1_amd64.deb
rm sabaton_0.1.1_amd64.deb

Check that the Sabaton utility is running by typing sabaton in the shell.

sabaton@97bd600a34d3:~/workspace$ sabaton -h
πŸš—.....Sabaton Build Orchestrator.....πŸ¦€
Sabaton build orchestrator 1.0
Sojan James
Orchestrates Sabaton builds

USAGE:
    sabaton [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    build    build commands
    help     Prints this message or the help of the given subcommand(s)
    init     Initialize sample device

Creating a device template

The Sabaton utility can create a complete device configuration that can be the starting point for your device configuration. The default template device will create an image that can be booted into Qemu.

## Create a new working directory and change to it
mkdir sabaton
cd sabaton

## Create a template device in the current directory.
## We call the device "qemu"

sabaton init -d "qemu" 

You should see the following output,

sabaton@97bd600a34d3:~/sabaton$ sabaton init -d qemu
πŸš—.....Sabaton Build Orchestrator.....πŸ¦€
Initializing device qemu
Writing file /home/sabaton/sabaton/device/qemu/device.toml
Writing file /home/sabaton/sabaton/device/qemu/partition.toml
Writing file /home/sabaton/sabaton/device/qemu/initrd.toml
Writing file /home/sabaton/sabaton/ndk.toml
Writing file /home/sabaton/sabaton/device/qemu/boot.toml
Writing file /home/sabaton/sabaton/device/qemu/image.toml
Writing file /home/sabaton/sabaton/device/qemu/vendor.toml
Writing file /home/sabaton/sabaton/device/qemu/data.toml
Writing file /home/sabaton/sabaton/device/qemu/base_files.toml
Writing file /home/sabaton/sabaton/.cargo/config.toml
Writing file /home/sabaton/sabaton/device/qemu/files/lib/terminfo/l/linux
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/basic.target
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/debug-shell.service
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/default.target
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/multi-user.target
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/serial-getty@.service
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-journald.service
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-journald.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-networkd.service
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-networkd.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-udevd.service
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/tmp.mount
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/dbus.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-initctl.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-journald-audit.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-journald-dev-log.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-udevd-control.socket
Writing file /home/sabaton/sabaton/device/qemu/files/lib/systemd/system/systemd-udevd-kernel.socket
Writing file /home/sabaton/sabaton/device/qemu/files/usr/share/dbus-1/system.conf
Writing file /home/sabaton/sabaton/device/qemu/files/usr/share/dbus-1/system-services/org.freedesktop.locale1.service
Writing file /home/sabaton/sabaton/device/qemu/files/usr/share/dbus-1/system-services/org.freedesktop.network1.service
Writing file /home/sabaton/sabaton/device/qemu/files/usr/share/dbus-1/system-services/org.freedesktop.resolve1.service
Writing file /home/sabaton/sabaton/device/qemu/files/usr/share/dbus-1/system-services/org.freedesktop.systemd1.service
Writing file /home/sabaton/sabaton/device/qemu/files/kernel_config.release
Generating verity keys using openssl

pubout writing RSA key

pkcs8 out writing RSA key

Done.
Edit ndk.toml and .cargo/config.toml to match the NDK installation

The init sub-command will create a complete device configuration structure, including flash partitioning, kernel configuration, initrd and system partition and also the key-pair for verity protection.

The default configuration should be ok to use without modification unless you want to change the version of the NDK used. If you use a different version of the NDK, go ahead and edit ndk.toml accordingly. The current version is 0.4.

You can verify that a new device is available for build by typing sabaton build -l

sabaton@97bd600a34d3:~/sabaton$ sabaton build -l
πŸš—.....Sabaton Build Orchestrator.....πŸ¦€
Building device
Supported Devices
1 : qemu
sabaton@97bd600a34d3:~/sabaton$ 

You are now ready to build the image.

Build the Qemu image

Build the qemu image by typing sabaton build -d qemu -j 7. The 'j 7' can be tweaked depending on your CPU. It is passed through to the Kernel build.

sabaton@97bd600a34d3:~/sabaton$ sabaton build -d qemu -j 7
πŸš—.....Sabaton Build Orchestrator.....πŸ¦€
Building device
Building device:qemu
LINKER set to aarch64-sabaton-linux-ar
....
....
....
....<build continues>

Thats it! Wasn't that easy? A lot has happened under the hood.

  1. Initial Ram disk compilation and creation
  2. Kernel Build from source
  3. Creating Flash filesystem image with multiple partitions
  4. Building Rust applications and injecting the stripped binaries into partitions of the flash image
  5. Injecting the necessary systemd configuration so that the system can boot
  6. Creating dm-verity metadata for system and vendor partitions.
  7. Building uboot

You can find the created disk images in the the target folder target/aarch64-unknown-linux-gnu/release/__device/qemu/deploy/images/ Here is a description of the generated files.

FileDescription
disk.imgThis is the complete flash image. The qemu image has a 512MB flash as defined in the partitions.toml
u-boot.binThe path to this binary is passed to the -bios command line parameter of Qemu
run-qemu.shThis script can be used to boot the image in qemu. qemu-system-aarch64 must be in the path before running this
manifest.txtA manifest describing the whole image and its parts. This is used by the OTA tools to generate update packages
<other_images>All the constituent images that are part of the flash image are available here. The OTA tools can used it to create delta packages

You can boot the image into QEMU by running the run-qemu.sh script. You can either install qemu-system-aarch64 or used the version that is part of the Sabaton NDK. Here is an example running it using qemu that is part of the NDK.

sabaton@97bd600a34d3:~/sabaton/target/aarch64-unknown-linux-gnu/release/__device/qemu/deploy/images$ source /opt/sabaton/0.4/environment-setup-armv8a-sabaton-linux
sh ./run-qemu.sh

Qemu will load u-boot and then boot into the image. Once done, you will be presented with a shell prompt. zsh is the shell used by Sabaton.

You can now explore the device configuration and modify to your wish. You can even inject Rust application crates into the target. Look at image.toml to see how parsec and other crates are added to the device.

Welcome to Linux!
<<A lot of other messages are debug is turned on>>
Restricting namespace to: n/a.
Operating on architecture: arm
Blocking cgroup.
Blocking ipc.
Blocking net.
Blocking mnt.
Blocking pid.
Blocking user.
Blocking uts.
Operating on architecture: arm64
Blocking cgroup.
Blocking ipc.
Blocking net.
Blocking mnt.
Blocking pid.
Blocking user.
Blocking uts.
Operating on architecture: arm
Operating on architecture: arm64
Operating on architecture: arm
Operating on architecture: arm64
[  OK  ] Started Network Service.
[    6.026689] random: systemd-journal: uninitialized urandom read (16 bytes read)
[  OK  ] Started Journal Service.
[  OK  ] Reached target System Initialization.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Started D-Bus System Message Bus.
[  OK  ] Reached target Sabaton normal startup.

sabaton#       

Image builder

How did the list of devices get printed out in the previous step? Sabaton images are built using the imagebuilder tool. This tool expects the device manifests in the device subdirectory. The device manifest is a top-down definition of the system, starting with information such as which Kernel to use, what partition layout to use and ends with which files to include into the different images. See imagebuilder for detailed documentation. The builder is bundled into the Sabaton command line utility.

Sabaton NDK

Sabaton ships with a GCC toolchain and an SDK that consists of selected open-source libraries. Building and maintaining a toolchain is a lot of work. We use the industry standard Yocto to build the SDK. The yocto recipes for the Sabaton NDK is available at https://github.com/sabaton-rs/sabaton-ndk.git

Sabaton Middleware

Application developers use the Sabaton middleware to develop executables that run on the Sabaton platform. The middleware standardizes how topics and services are accessed by applications and also how data types and interfaces are defined.

Read more about the middleware

Sabaton Booting Sequence

Sabaton uses an initrd based startup sequence and separates the platform parts of the system from the hardware and product specific parts. See booting for detailed information on how a Sabaton system boots.