Build a minimal Raspberry Pi OS from source
Raspberry Pi DIY
The detLFS project provides an ideal foundation for compiling Linux from source code, either to experience the fundamentals of how Linux works or to prepare an operating system for a project with very specific requirements.
The Linux From Scratch (LFS) project has been around for more than 20 years [1]. It does not deliver software as a result, but detailed instructions on how to create an executable Linux system from the source code itself. Why might you want to take this route? (1) You might be a masochist with too much time on your hands. (2) You have a project with very specific requirements. (3) You want to learn fundamentally how Linux works. The detLFS [2] project by Thomas Dettbarn answers these needs.
Unlike the pure theory of LFS, detLFS makes life far easier for anyone wanting to take on the challenge because the project provides a set of scripts instead of a manual. The scripts create a runnable, minimal Linux system for the Raspberry Pi almost without interaction. As a prerequisite you need a desktop Linux with the usual build tools (i.e., a compiler and make
), as well as ImageMagick/Netpbm for your own kernel logo. These tools can be found on any normal developer's computer; if in doubt, install them from your package manager. They are typically pseudo-packages named build-essentials, or something similar.
Simply downloading the repository and running the scripts is boring and basically pointless, because nobody gains anything from the minimal system the process creates. Understanding the process and knowing how to adapt it to your own needs is far more important.
How Linux Works
Whether on a Raspberry Pi or on a supercomputer, Linux basically always works in the same way. First, the hardware boots the kernel from disk. This part depends heavily on the platform. Without firmware, also known as BIOS in the desktop area, nothing works.
After startup, the kernel initializes its subsystems and drivers then passes control to the init process by starting the /sbin/init
program with process ID 1. On modern Linux systems, the systemd process adopts this ID shortly afterward. The init program then gradually starts all the application programs and processes that make up a system. The kernel itself remains in the background as a silent worker, stepping in whenever a program needs access to resources, such as during a program startup or for reading a file (Figure 1).
A minimal system comprises three components: the firmware, a kernel, and at least one init program. For a Raspberry Pi, whose only task is to control and switch something, this setup might be enough. detLFS is not quite as minimal. In addition to the init program, standard Linux programs or honed down versions (e.g., ls
, cp
, etc.) are also present.
To create your own minimal system with very little overhead, a script first collects all the required program sources. Subsequently, a second script generates a cross compiler along with companion programs, which are needed because you want to create an executable kernel and application programs for the Raspberry Pi ARM architecture on an x86 system. The schematic flow is shown in Figure 2. All scripts need to run within a single session; otherwise, you will have to repeat the export
commands, which are valid only within a single session.
Improvements
For this project, I provide a fork of the original scripts on GitHub [3], mainly because various bugfixes and optimizations significantly speed up the download and the process of building the system. Furthermore, the fork supports all hardware variants of the Raspberry Pi, not just versions 2 and 3. You can retrieve the software with the commands:
$ git clone https://github.com/bablokb/pi-detLFS $ rm -fr /data/projects/detLFS $ cp -a pi-detLFS/detLFS /data/projects $ cd /data/projects/detLFS
The last two commands copy the directory with the scripts to a suitable project directory and change to that location. If the directory is on a filesystem formatted with XFS or Btrfs, all of the later scripts run faster and they require less space because these filesystems only copy the references when duplicating files, not the data blocks.
After these preparations, run:
$ export BRANCH=rpi-4.19.y $ ./0_getit.sh |& tee 0_getit.log
The optional first line specifies the kernel branch the script fetches from the repository (various lines of development exist in separate branches). Without the export
command, the script uses the current default branch. Instead of setting the branch manually, you can alternatively copy the kernel configuration file .config
from a running Raspberry Pi into the detLFS directory:
$ sudo modprobe configs $ zcat /proc/config.gz > .config
The 0_getit.sh
script in the earlier set of commands downloads about 1.1GB of compressed sources, which when unpacked add up to about twice that. For each download, the script creates a file in the Downloads/
directory that follows the pattern .detlfs.<xxx>
(e.g., .detlfs.kernel
) (Figure 3). If you want to download something again, maybe because you want to try out a different kernel version, delete the file in question beforehand. In any case, check the 0_getit.log
file after execution – this applies in kind to all further steps.
Only the downloaded source packages end up in the Downloads/
directory. With the exception of the kernel, these are archives. The script immediately copies or unpacks the sources into the Sources.
directory. The scripts downstream of this step then make use of them.
Toolbox
The second step in the workflow creates the tools that the downstream scripts need and relates primarily to the cross compiler, which runs on a desktop system (x86), but generates code for the ARM variant:
$ ./1_buildtools.sh | & tee 1_buildtools.log
Fortunately, the normal desktop compiler also builds this cross compiler in the most time-consuming step in the whole process. Ready-made cross compilers can be found online and from the Raspberry Pi Foundation, but users report in forums having difficulties with these tools time and time again. Therefore, the detLFS project prefers building the programs itself.
The computer I used in this project, an AMD Ryzen 5 2400G, is not necessarily a top performer; in fact, it is basically geared toward office work with its integrated GPU. The quad-core processor claims to be an eight-core CPU to the operating system because of hyperthreading. If all the cores are used (to find out, use the -j 8
option with make
), the call described above takes about 18 minutes. If only one core is doing the work, it takes 62 minutes. However, hyperthreading doesn't offer too many benefits with this CPU because of the fairly small CPU cache: with four cores, the compiler run takes 22 minutes, which is only marginally longer than with the full core count.
Once created, the tools do their job no matter how many different kernel and system versions you want to try, so the runtime is only consumed once.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Linux Kernel 6.13 Offers Improvements for AMD/Apple Users
The latest Linux kernel is now available, and it includes plenty of improvements, especially for those who use AMD or Apple-based systems.
-
Gnome 48 Debuts New Audio Player
To date, the audio player found within the Gnome desktop has been meh at best, but with the upcoming release that all changes.
-
Plasma 6.3 Ready for Public Beta Testing
Plasma 6.3 will ship with KDE Gear 24.12.1 and KDE Frameworks 6.10, along with some new and exciting features.
-
Budgie 10.10 Scheduled for Q1 2025 with a Surprising Desktop Update
If Budgie is your desktop environment of choice, 2025 is going to be a great year for you.
-
Firefox 134 Offers Improvements for Linux Version
Fans of Linux and Firefox rejoice, as there's a new version available that includes some handy updates.
-
Serpent OS Arrives with a New Alpha Release
After months of silence, Ikey Doherty has released a new alpha for his Serpent OS.
-
HashiCorp Cofounder Unveils Ghostty, a Linux Terminal App
Ghostty is a new Linux terminal app that's fast, feature-rich, and offers a platform-native GUI while remaining cross-platform.
-
Fedora Asahi Remix 41 Available for Apple Silicon
If you have an Apple Silicon Mac and you're hoping to install Fedora, you're in luck because the latest release supports the M1 and M2 chips.
-
Systemd Fixes Bug While Facing New Challenger in GNU Shepherd
The systemd developers have fixed a really nasty bug amid the release of the new GNU Shepherd init system.
-
AlmaLinux 10.0 Beta Released
The AlmaLinux OS Foundation has announced the availability of AlmaLinux 10.0 Beta ("Purple Lion") for all supported devices with significant changes.