Building and booting a custom Linux kernel for ARM using kw
Notes and lessons learned while installing the kw tool
Introduction
Following the MAC0470/5856 – Linux Kernel Development course at IME-USP, this is the second module in my series of notes. In the previous post, I set up a safe virtual machine environment using QEMU and libvirt on my Ubuntu 24.04 host.
This time, I followed the tutorial Building and booting a custom Linux kernel for ARM using kw to install the kw tool, build a custom ARM64 Linux kernel (focusing on the Industrial I/O subsystem), and boot it inside the VM.
kw (Kernel Workflow) is a very useful tool that automates many repetitive tasks in kernel development, saving a lot of time. The tutorial was generally clear and straightforward, but I ran into a few configuration issues — mostly related to my environment and PATH setup.
Note: I initially used an Ubuntu 24.04 cloud image for the VM, but after SSH-related problems in the first module, I switched to a Debian 12 image.
Tutorial 2
Building and Booting a Custom Linux Kernel for ARM using kw
Installing kw
I followed the installation steps from the tutorial. The installation completed successfully, but I immediately faced a problem when trying to run kw --version.
1
2
3
4
5
6
7
(DEV-LK) laura-arakaki@laura-arakaki-pc:/home/dev_lk/kw$ kw --version
/home/laura-arakaki/.local/bin/kw: linha 75: /usr/share/kw/lib/kw_include.sh: Arquivo ou diretório inexistente
/home/laura-arakaki/.local/bin/kw: linha 77: include: comando não encontrado
/home/laura-arakaki/.local/bin/kw: linha 109: signal_manager: comando não encontrado
/home/laura-arakaki/.local/bin/kw: linha 109: warning: comando não encontrado
/home/laura-arakaki/.local/bin/kw: linha 294: include: comando não encontrado
/home/laura-arakaki/.local/bin/kw: linha 296: kworkflow_version: comando não encontrado
Even though the files existed inside the source directory (./src/lib/kw_include.sh), the installed kw script could not find the library files. This was caused by an incorrect PATH configuration after installation.
1
2
(DEV-LK) laura-arakaki@laura-arakaki-pc:/home/dev_lk/kw$ find . -name "kw_include.sh"
./src/lib/kw_include.sh
Workaround for the PATH Issue
To work around this, I started using the full path to the kw executable for every command:
1
$KW_DIR/kw <command>
This allowed me to continue with the rest of the tutorial.
Other Issues Encountered
While trying to deploy modules to the VM, I got the following error:
1
2
3
4
5
6
(DEV-LK) laura-arakaki@laura-arakaki-pc:/home/dev_lk/iio$ $KW_DIR/kw ssh --get '~/vm_mod_list'
bash: line 1: rsync: command not found
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(232) [Receiver=3.2.7]
An error occurred while uploading the file(s). rsync return code: 12
The solution was simple but not mentioned in the tutorial: install rsync on both the host and the VM.
1
2
3
@VM
apt update
apt install rsync
Building the Kernel
The most important (and time-consuming) command in the tutorial is:
1
kw build
On my machine, the first build took about 1 hour. After that, I learned there are several ways to reduce build time (such as using ccache, limiting the number of jobs, or incremental builds), but I didn’t apply them yet.
Once the kernel was built, I proceeded with kw deploy --modules to install the modules into the VM and then booted the custom kernel.
What I Learned
kwis a powerful automation tool that simplifies kernel compilation, configuration, and deployment to a VM.- Proper PATH configuration is critical after installing tools from source, especially if you’re using Ubuntu as your main distro.. When in doubt, using the full path (
$KW_DIR/kw) is a reliable workaround. - Tools like
rsyncare often required for file transfer between host and VM but may not be installed by default in minimal cloud images. - The
kw buildcommand can be quite slow on the first run — planning for build time (or optimizing it) is important. - Switching the VM base image (from Ubuntu to Debian) affected some service names and package availability, reinforcing the importance of understanding distribution differences.
- Combining the environment from Module 1 (QEMU + libvirt) with
kwcreates a smooth workflow for testing custom kernels safely.
Overall, this module was a great next step after setting up the VM. I’m now able to build and test custom kernels for ARM64, which will be very useful for experimenting with the IIO subsystem.
Next, I’ll start making small changes to the kernel and testing them in the VM.
Licensed under CC BY 4.0.