This is an old revision of the document!
In this section we present a step-by-step guide of setting up a kernel development environment using qemu-system-aarch64. This emulator is very widely used, enables easy kernel debugging, and is extremely efficient. However, it is not a replacement for a hardware testing environment. If you want to develop a device driver and not say, an iptables plugin, you should probably be looking for a development board. Similarly, this emulator does away with most of the ARM boot process, meaning that you're not going to be able to test out the bootloaders studied during the first two sessions. This solution is strictly for kernel development.
This step is very straightforward. Just clone the Linux repo (with depth=1 to squash the commit history) and compile it for the arm64 target. Optionally, you can enable the generation of debug symbols & gdb helper scripts; the config options are CONFIG_DEBUG_INFO_DWARF5
and CONFIG_GDB_SCRIPTS
, found under Kernel hacking → Compile-time checks and compiler options
.
# clone the repo ~$ git clone --depth=1 https://github.com/torvalds/linux.git # generate a default config & compile # NOTE: the default target will also compile the modules linux$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig linux$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j $(nproc)
Unfortunately, the server does not have any foolproof method of inferring the structure of the project. For example, it has no idea whether you are using the arm64 or the x86 definition of a function. Luckily for us, the Linux build system contains a script that's able to generate a file names compile_commands.json
. This file contains all compiler invocations used during the boot and can deduce include paths, compiled source, macro definitions, etc. The language server will automatically load it and generate indices for the compiled source code.
Note that this script only forks for the Linux kernel. If you want to generate compile_commands.json
for other projects, consider using Bear. This is a tool that hooks the exec()
family of library calls via LD_PRELOAD hooking in order to extract the command arguments.
In this example setup we're going to be using debootstrap to generate a root filesystem based on Debian.
~$ mkdir rootfs ~$ sudo debootstrap --arch arm64 stable rootfs/ \ http://ftp.hosteurope.de/mirror/ftp.debian.org/debian/