Developer Blog

30/03/2026 by Sebastian Tellwe

Edge, The “Hello, World!” application

Background:

The Kvaser Edge is an embedded Linux platform, with integrated CAN hardware along with Ethernet, Wi-Fi, USB and more. It has hardware and core software by Kvaser, providing a foundation for building robust and secure embedded applications with minimal effort and maximum flexibility.

KEOS, the software stack, is built around LXC containers. In this article, we are going to cover the path from getting started, to running a working application on the Kvaser Edge.

This article is aimed at anyone who’s getting familiar with the unit and wanting to load a container to begin creating powerful and business critical applications for the Kvaser Edge, while avoiding the common pitfall of having their work erased by a factory reset.

Container/rootfs:

The container is the foundation of the system. In the case of LXC, the container is a full Linux system running in isolation. From your perspective as a developer, the container is a complete rootfs which gives endless possibilities. Alot can be said about the rootfs, and it is the core of how Linux systems are constructed. They are highly customizable, and with that also easy to break. There are containers available online, and in the KEOS Webhelp we cover how to setup a device using such an image. When you have downloaded a container, followed the steps and got into the serial terminal, you are in business, and setting up ssh is the final step before really starting to dig into the development side of things. And this is when you need to decide how you want to develop applications on your new device.

The container and factory reset:

The Edge comes with a factory reset feature, a powerful yet unforgiving feature. Like many things in Linux, the factory reset feature does what you ask without adding any safety steps. The feature simply erases your container and all the data that was stored, putting the Edge back to a factory state. If you did any coding or configuration on the device only, this work will now be lost forever. This is great when you want to reset, but awful if you put weeks into the application only on the device. This is where a development strategy comes into action, and now we are going to cover a very basic approach to this.

Updating the rootfs.tar.xz:

What you want is containers that contain your application so that when you go to factory reset, or you want to deploy your application to another device, it is just a matter of connecting the USB and downloading the container. Creating a custom container can be done in multiple ways, and our recommendation is to use some sort of build chain with tooling custom to the task. We like to use MKOSI, which is powerful and quite straight forward, though it has a learning curve.

Simply put, a custom container starts as a standard base image (for example, Debian bookworm for ARM64) that is then modified using a tool such as MKOSI. This tool makes changes to the container, but the changes are just updates to the rootfs file system that is the actual container. When it comes to adding files, this can be done without a tool: just unpack the rootfs.tar.xz, add your files and repack. This is the most basic and straightforward way to update a container, and in many cases is perfectly sufficient. There is some complexity to the process, however, so let’s run through a working example.

Unpack and repack:

When unpacking a rootfs.tar.xz, a lot of compression tools will not keep the file permissions, ownership, symbolic links etc. in the file system. This will cause the Linux root file system to break. A good rule of thumb is, if the tool does not understand Linux permissions, it should not be used to handle a Linux root file system.

So in this example, we will use WSL (Windows Subsystem for Linux) and tar for handling the unpack and pack.

What is WSL?

WSL (Windows Subsystem for Linux) is a feature in Windows that lets you run a real Linux environment directly on your Windows machine — without needing a virtual machine or dual boot setup. You can think of WSL as a bridge between Windows and Linux, instead of installing Linux separately, WSL allows you to:

  • Open a Linux terminal (like Ubuntu) inside Windows
  • Use common Linux tools such as bash, ssh, grep, git, and many others
  • Run Linux-based development workflows

For example, after installing WSL and Ubuntu, you can open a Linux shell and run:

1s

This command lists files in the current directory — just like on a normal Linux system. WSL is especially useful for:

  • Developers working with Linux-based servers
  • Open-source tools that are built primarily for Linux
  • Embedded, backend, or DevOps workflows

In short: WSL lets Windows users work as if they’re on Linux.

In this example, WSL2 is being used. For more information go to https://learn.microsoft.com/en-us/windows/wsl/install.

What is tar?

tar is a common Linux command used to bundle multiple files and folders into a single file. The name comes from Tape Archive, because it was originally used for backing up data to tape drives.

You can think of a .tar file as similar to a .zip file — but more common in Linux environments.

tar comes installed with most Linux distributions and is available when installing WSL.

The code and where to put it:

A final thing to mention before the example, what we will add and where we will put it. The only thing that we will do is to add code and scripts to the system, and these will be placed in the /opt directory, opt being the directory for optional/add-on software.

The example:

We want to add a simple CAN logger application to the Edge device. We will use shell scripts for this, to have something with minimal dependencies and complexity. This is the content of the scripts:

setup-can-logger.sh

#!/bin/sh

# Update package list apt update

# Install CAN tools
apt install -y can-utils

echo "Setup complete."
echo "You can now run the CAN logger script."

This script contains all the steps needed for the first boot. It makes an update and then installs can-utils, giving us some useful commands to interact with CAN traffic. In this example, we are using SocketCAN, which is included in the container that we have chosen further down in the example.

After this, we will need the actual logger script. This is the code that we want to run on the device:

can-logger.sh

#!/bin/sh

# CAN interface and bitrate IFACE="can0" BITRATE="250000"

# Log file location LOG_FILE="/var/can_log.txt"

# Configure CAN interface
ip link set "$IFACE" down 2>/dev/null
ip link set "$IFACE" type can bitrate "$BITRATE" ip link set "$IFACE" up

# Log CAN frames (one frame per line) candump "$IFACE" >> "$LOG_FILE"

This is a minimal shell-script that:

  • Initializes a can interface to 250kb/s
  • logs the frames to a file

Now, with these two files, we are ready to add them to our container.

Open a WSL terminal on your computer. Guide to install wsl

Create a working directory for the unpack and pack operation.

mkdir kvaser-edge-container
cd kvaser-edge-container

Now, we want to create a directory structure to keep the process clean

mkdir base out overlay work

This should result in a directory structure that looks like this:

.
├── base
├── out
├── overlay
└── work

Now, we want to download a base container, and we will use the one that’s mentioned in the documentation for Edge, and download it using wget. There are new versions of these containers being released continuously, so you may browse for different dates. The thing you are looking for is the rootfs.tar.xz

wget -P base https://images.linuxcontainers.org/images/debian/bookworm/arm64/default/20260107_05:24/rootfs.tar.xz

Next, we create our two scripts to the overlay directory. Here we do it from the terminal, but you can do this via another editor as well. In that case skip to Directory Structure.

touch overlay/setup-can-logger.sh overlay/can-logger.sh

Open the files and add the code, I will use the nano terminal editor in this example.

nano overlay/setup-can-logger.sh

You should be able to copy the code of the script and then just right-click in the terminal to paste the code.

Exit nano using Ctrl + x followed by y and Enter

Do the same operation for the other file

nano overlay/can-logger.sh

Directory Structure

The directory structure should now look like this

.
├── base
│	└── rootfs.tar.xz
├── out
├── overlay
│	├── can-logger.sh
│	└── setup-can-logger.sh
└── work

Now we are ready to create the modified Linux root filesystem. We unpack the base rootfs into the work directory.

mkdir work/rootfs
tar -xJf base/rootfs.tar.xz -C work/rootfs

When the unpack command is done (it will take some time) you should have the filesystem unpacked like this

.
├── base
│	└── rootfs.tar.xz
├── out
├── overlay
│	├── can-logger.sh
│	└── setup-can-logger.sh
└── work
    └── rootfs
         ├── bin -> usr/bin
         ├── boot
         ├── dev
         ├── etc
         ├── home
         ├── lib -> usr/lib
         ├── media
         ├── mnt
         ├── opt
         ├── proc
         ├── root
         ├── run
         ├── sbin -> usr/sbin
         ├── srv
         ├── sys
         ├── tmp
         ├── usr
         └── var

Now we will copy the script files to the rootfs.

mkdir -p work/rootfs/opt/can-logger
cp -a overlay/. work/rootfs/opt/can-logger/

And finally, we will pack the rootfs back to the output directory.

tar -C work/rootfs -cJf out/rootfs.tar.xz .

In the out directory you should now have a rootfs.tar.xz ready.

From the documentation we can see that we need two more files to have the complete container for the Edge, meta.tar.xz and container-config.yaml

The meta.tar.xz is downloaded from the same place as the rootfs.tar.xz

wget -P out https://images.linuxcontainers.org/images/debian/bookworm/arm64/default/20260107_05:24/meta.tar.xz

And we create the container-config.yaml like this

touch out/container-config.yaml
nano out/container-config.yaml

And paste the following content

name: kvaser-edge-%S
interfaces:
       - eth0
       - mlan0
       - mmlan0
users:
     root:
         password: root

(ctrl + x, y and Enter to exit nano)

This is a minimal, simple container configuration. To learn more about the contents of the container configuration files see The web help

Now out directory should look like this:

.
├── container-config.yaml
├── meta.tar.xz
└── rootfs.tar.xz

And now we are ready to download our custom container to the Edge.

  • Perform a factory reset of the Edge device. THIS WILL ERASE ALL DATA! Make sure that all the files that you wish to keep are copied off the device. For information on ways to move files from the device, see appendix Backup
  • Connect the USB to your computer
  • Put the content of the out/ directory to container/ on the Edge
  • Use the ‘Safely remove hardware and Eject Media’ function to safely remove the device from the computer.
  • Power cycle the device

After KEOS checks and activates the container, the device boots into your custom container. Now, when accessing the device via serial terminal, you should find that ls /opt/can-logger shows can-logger.sh setup-can-logger.sh, success!

To run the application for the first time, run

bash /opt/can-logger/setup-can-logger.sh

Which initializes the application and installs the necessary packages.

PS: The Edge needs a network connection to be able to fetch the packages. Ethernet is the active way as no Wi-Fi has been set up yet.

After the script is completed, run

bash opt/can-logger/can-logger.sh

You should see the LED for the activated CAN channel light up, and when CAN traffic is ready the LED will blink, indicating frames. This shows that the channel is active and the CAN logger script reads data and writes the frames to the file /var/can_log.txt

Congratulations, you have created a custom container with a CAN logger application that stores CAN frames to a file on the device.

The next steps to further improve the application would be:

  • File rotation and chunking of data.
  • Create and configure a service to start the script and manage it.
  • Add more configuration and dependency downloads to the setup script to simplify the startup.
  • Add start/stop of logging using the push buttons on the device.
  • Add indications using the custom LEDs on the device.
  • Remote connection over Wi-Fi to fetch or push the log files from the device.

When starting to do more advanced configurations of the container, this way of unpacking and repacking quickly becomes a bad approach that is prone to breaking the filesystem. Then, moving to other tool chains like MKOSI is the better solution.

Appendix: Backup

To backup files from the device, you can connect to it via ssh and use terminal commands such as scp or rsync. There are GUI applications that give you a visual of the filesystem on the device, such as WinSCP or MobaXterm, where you can find and copy files.

Author Image

Kvaser Marketing