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
-
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.
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.