-
Notifications
You must be signed in to change notification settings - Fork 6
BUILDING
Building an L4Re system from scratch involves several Git repositories and multiple steps described in this document.
Depending on your host system, you might need to install some prerequisities.
On Debian 12 (Bookworm), make sure you have the required packages installed together with their dependencies by running the following command with sufficient privileges:
[somedir] $ apt-get install git make binutils liburi-perl libpar-packer-perl libgit-repository-perl libxml-parser-perl gcc g++ libc6-dev-i386 libncurses-dev qemu-system xorriso mtools flex bison pkg-config gawk device-tree-compiler dialog wget doxygen graphviz
On top of a fresh Fedora 27 install, you will need the following packages and their dependencies:
[somedir] $ dnf install perl-URI perl-PAR-Packer perl-Git-Repository-Plugin-AUTOLOAD perl-CPAN perl-Test perl-Text-Balanced gcc gcc-c++ glibc-devel.i686 ncurses-devel xorriso flex bison pkgconf-pkg-config gawk dtc
[somedir] $ cpan install XML::Mini::Document
On Arch Linux, the following packages need to be installed:
[somedir] $ pacman -S --needed base-devel dtc lib32-gcc-libs qemu qemu-arch-extra mtools
Additionally, these packages need to be installed from the AUR by a method of your choice:
[somedir] $ yay -S perl-par-packer perl-git-repository perl-xml-mini perl-uri
L4Re is composed of several loosely coupled Git repositories. While it is theoretically possible to manage them individually using Git alone, it is recommended to use ham to manage the whole set at once.
[somedir] $ git clone https://github.com/kernkonzept/ham.git
[somedir] $ cd ham
[somedir/ham] $ make
Make sure to include ham in your PATH.
Use ham to get the L4Re project manifest and all its constituent repositories:
[somedir/ham] $ cd ..
[somedir] $ ham init -u https://github.com/kernkonzept/manifest.git
[somedir] $ ham sync
If ham sync is terminated early or fails to sync refer to the troubleshooting information.
When building L4Re for the first time, you first need to create and configure a build directory:
[somedir] cd l4
[somedir/l4] $ make B=../build-amd64
[somedir/l4] $ cd ../build-amd64
[somedir/build-amd64] $ make oldconfig
Note that amd64 / x86_64 is the default, so no interactive selection is
necessary. If you want to check, please use make config
.
Also note that the build directory can be arbitrary. build-amd64 is used
as an example here.
The build directory is now ready and you can build the L4Re binaries:
[somedir/build-amd64] $ make # Optionally use -j X to make the build parallel
The release L4Re binaries reside in the bin subdirectory of the build directory. For the amd64 configuration, this is bin/amd64_gen/l4f:
[somedir/build-amd64] $ file bin/amd64_gen/l4f/hello
bin/amd64_gen/l4f/hello: bin/amd64_K8/l4f/hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=..., with debug_info, not stripped
For running the L4Re binaries, you are going to need the L4Re Microkernel microkernel, which is cloned by ham as part of the L4Re manifest.
Create and configure the Fiasco build directory:
[somedir/build-amd64] cd ../fiasco
[somedir/fiasco] $ make B=../build-fiasco-amd64
[somedir/fiasco] $ cd ../build-fiasco-amd64
[somedir/build-fiasco-amd64] $ make oldconfig # amd64 is the default architecture
The microkernel has some more feature to choose. You might check them with
make config
.
And finally, build the microkernel itself:
[somedir/build-fiasco-amd64] $ make # Optionally use -j X to make the build parallel
Like in the L4Re case above, the build directory is created and configured only once. The resulting microkernel binary is called fiasco.
Now that you have sucessfully built Fiasco and L4Re, it is time to verify that they were built correctly by running a simple demo scenario with a sample program called hello:
[somedir/build-fiasco-amd64] cd ../build-amd64
[somedir/build-amd64] $ make E=hello qemu MODULE_SEARCH_PATH="${PWD}/../build-fiasco-amd64"
This will run the scenario in QEMU without creating any bootable images. After a short while, you should see the message "Hello World!" printed in 1-second intervals on the virtual QEMU screen.
If you prefer having a bootable ISO instead, you can generate one like this:
[somedir/build-amd64] $ make E=hello grub2iso MODULE_SEARCH_PATH="${PWD}/../build-fiasco-amd64"
The generated ISO image can be found in the images subdirectory.
If you copy somedir/l4/conf/Makeconf.boot.example to somedir/l4/conf/Makeconf.boot and point the FIASCO_PATH-amd64 variable in there to your microkernel build directory, you wouldn't have to specify it in the MODULE_SEARCH_PATH environment variable on the command line everytime.
Makeconf.boot is also the place to tune various QEMU and platform-specific options.
In a similar way, you can create Makeconf.local in your build directory and define the variables used during the configuration phase (e.g. the cross-compiler configuration, see below) there.
If you are going to cross-compile L4Re for ARM, ARM64 (aarch64) or RISC-V, you'll need to install the respective QEMU packages for the target platforms and cross-compilers.
Your distribution most likely provides some cross-compiler packages for selected platforms. Debian cross-compilers (packaged in g++-arm-linux-gnueabihf, g++-aarch64-linux-gnu, g++-riscv64-linux-gnu) have been known to work with L4Re.
The cross-compilation of L4Re and Fiasco is similar to the normal build:
[somedir/l4] $ make B=../build-arm64
[somedir/l4] $ cd ../build-arm64
When cross-compiling, you have to specify the prefix of the cross-tools you wish to use in the CROSS_COMPILE variable at some point before the config phase.
For example, when cross-compiling for the 64-bit ARM Virt QEMU platform, you need to specify the CROSS_COMPILE variable in a file called Makeconf.local. Adjustments might be necessary for different cross-compilers and platforms:
[somedir/build-arm] $ echo "CROSS_COMPILE:=aarch64-linux-gnu-" > Makeconf.local
[somedir/build-arm] $ make config # Select ARM architecture, Cortex-A57 and QEMU virt platform
[somedir/build-arm] $ make
Alternatively, you can define the CROSS_COMPILE variable on the command line.
In both cases, don't forget to configure the system for the ARM64 architecture.
Cross-compiling the microkernel is analogous. Make sure to unselect the Virtualization option in this case:
[somedir/build-arm] $ cd ../fiasco
[somedir/fiasco] $ make B=../build-fiasco-arm64
[somedir/fiasco] $ cd ../build-fiasco-arm64
[somedir/build-fiasco-arm64] $ echo "CROSS_COMPILE:=aarch64-linux-gnu-" > Makeconf.local
[somedir/build-fiasco-arm64] $ make config # Select ARM processor family as Architecture, QEMU ARM Virtual Platform as Platform, ARM Cortex-A57 CPU as CPU
[somedir/build-fiasco-arm] $ make
When all is built, run the hello scenario in QEMU (assuming qemu-system-aarch64 is installed on the system):
[somedir/build-fiasco-arm] $ cd ../build-arm
[somedir/build-arm64] $ make E=hello qemu MODULE_SEARCH_PATH="${PWD}/../build-fiasco-arm64" PLATFORM_TYPE=arm_virt
Note that besides MODULE_SEARCH_PATH, also QEMU_OPTIONS and PLATFORM_TYPE can be conveniently specified in somedir/l4/conf/Makeconf.boot.
Building the microkernel and L4Re user-level is a procedure complex enough to offer many opportunities for things to go wrong. Here are the most common issues and their causes:
If ham sync is terminated early using Ctrl-C or encounters network errors such as the following an incomplete manifest may have been synced.
mk: fatal: The remote end hung up unexpectedly
mk: fatal: early EOF
mk: fatal: index-pack failed
It is usually best to start again with an empty directory. Alternatively, it may be possible to selectively force sync some packages listed in .ham/manifest.xml:
[somedir] $ ham sync --force-local-update <manifest package name>
If network issues are suspected try:
[somedir] $ ham sync --max-connections=1
If the ham sync operation was incomplete the mk package may be missing. In this case it's best to restart ham sync from an empty directory. Running make in the top-level directory results in this error indicating the top-level Makefile is missing:
make: *** No targets specified and no makefile found. Stop.
If you get the following error when creating a build directory on a 64-bit host, make sure that multilib (or libraries supplementing it, e.g. glibc-devel.i686 on Fedora) are installed:
/usr/include/linux/errno.h:1:23: fatal error: asm/errno.h: No such file or directory
#include <asm/errno.h>
^
compilation terminated.
If you forget to set the respective architecture during the configuration step before cross-compilation, you may get failures that look like:
arm-linux-gnueabihf-gcc: error: unrecognized command line option ‘-m32’
Makefile:372: recipe for target 'Makeconf.bid.local-internal-names' failed
make[5]: *** [Makeconf.bid.local-internal-names] Error 1