Buildroot-part 1. General information, minimum system build, setup via menu
Introduction
In this series of articles, I want to review the Buildroot build system and share my experience of customizing it. Here you will have practical experience in creating a small OS with a graphical interface and minimal functionality.
First of all, do not confuse the build system and distribution. Buildroot can build a system from a set of packages offered to it. Buildroot is built on makefiles and therefore has huge customization possibilities. Replace the package with another version, add your package, change the package build rules, customize the file system after installing all the packages? Buildroot can do all of these.
The purpose of the work is to build a distribution with live download, icewm interface, and browser. The target platform is VirtualBox.
Why do you need to build your own distribution? Often you need limited functionality with limited resources. Even more often, in automation, you need to create firmware. Adapting a General-purpose distribution by cleaning out unnecessary packages and turning it into firmware is a more time-consuming way than building a new dB. The use of Gentoo also has its limitations.
Buildroot is a very powerful system, but it won’t do anything for you. It can only enable and automate the build process.
Alternative build systems such as yocto, open build system, etc. are not considered or compared.
Where to get started
Project website-buildroot.org. Here you can download the current version and read the manual. There you can also contact the community. There are bugtracker, mail-lists, and IRC-channel.
Buildroot operates defconfig for the target build Board. Defconfig is a configuration file that stores only options that do not have default values. It determines what will be collected and how. You can configure the busybox, Linux-kernel, uClibc, u-boot, and barebox configs separately, but they all will be linked to the target Board.
After unpacking the downloaded archive or cloning from git, we get the Buildroot ready to work. You can read more about the directory structure in the manual. I will tell you about the most important:
board — a directory with files specific for each Board. These can be scripts for creating system images (iso, sdcart, cpio, etc.), the overlay directory, kernel config, and so on
configs — the actual defconfig of the Board. Defconfig is an incomplete Board configuration. It stores only parameters that differ from default settings
dl — a directory with the downloaded source codes/files for the build
output/target — an assembled file system of the received OS. Subsequently, images are created from it for download/installation
output/host — host-build utilities
output/build — collected packages
The Assembly is configured via KConfig. The same system is used to build the Linux kernel. List of the most frequently used commands (run in the Buildroot directory):
- make menuconfig-call the build configuration. You can also use the graphical interface (make nconfig, make xconfig, make gconfig)
- make linux-menuconfig-call the kernel configuration.
- make clean-clean the build results (everything that is stored in the output)
- make-build the system. It does not perform reassembly of already assembled processes
- make defconfig_name-switch the configuration to a specific defconfig
- make list-defconfigs-show list of defconfigs
- make source — only to download the installation files without an Assembly.
- make help-pull up the list of possible commands
Important notes and useful tips
Buildroot does not rebuild packages that have already been built! Therefore, there may be a situation where a complete reassembly is required.
You can rebuild a separate package with the make packagename-rebuild command. For example, you can rebuild the Linux kernel:
make linux-rebuild
Buildroot stores the state of any data package.stamp files in the output/build/$packagename directory:
Therefore, it is possible to rebuild the root fs and images without rebuilding the packages:
rm output/build/host-gcc-final-*/.stamp_host_installed;rm-rf output/target;find output/ - name ".stamp_target_installed"|xargs rm-rf ; make
Useful variables
Buildroot has a set of variables for easy configuration:
- $TOPDIR is the root directory of the Buildroot
- $BASEDIR — the directory OUTPUT
- HOST_DIR,HOSTDIR,STAGING_DIR, $TARGET_DIR-build directories like host fs, staging fs, target fs.
- $BUILD_DIR- a directory with unpacked and assembled packages
Visualization
In Buildroot, there is a possibility for visualization. You can build a dependency diagram, a build time graph, and a package size graph in the final system. The results will be as pdf files (you can choose svn, png) in the output/graph directory.
Examples of visualization commands:
'make graph-depends
' build a dependency tree'make <pkg> - graph-depends
' build a dependency tree for a specific package'BR2_GRAPH_OUT=png make graph-build
' construct a build time graph with output in PNG'make graph-size
' plot the size of packages
Useful scripts
The Buildroot directory has a subdirectory utils with useful scripts. For example, there is a script that checks the correctness of the package description. This can be useful when adding your packages (I’ll do it later). The utils/readme file.txt has a description of these scripts.
Build a stock distribution
It is important to remember that all operations are performed on behalf of a normal user, not root.
All commands are performed in the Buildroot root. The Buildroot package already has a set of configurations for many common boards and virtualization.
See the list of configurations:
Switch to the qemu_x86_64_defconfig config
make qemu_x86_64_defconfig
And run the build
make
The build is completed successfully, look at the results:
Buildroot has collected images that can be run in Qemu to make sure they work.
qemu-system-x86_64 -kernel output/images/bzImage -hda \ output/images/rootfs.ext2-append "root=/dev/sda rw" -s -S
The result is a system running in qemu:
Creating a custom Board configuration
Adding the Board files
See the list of configurations:
In the list, you can see pc_x86_64_bios_defconfig. We will create our Board by copying it from the configuration:
cp configs/pc_x86_64_bios_de`fconfig configs/my_x86_board_defconfig
Immediately create a directory for the Board to store your scripts, rootfs-overlay, and other necessary files:
mkdir board/my_x86_board
Switch to this defconfig:
make my_x86_board_defconfig
Thus, now the configuration of the Assembly (stored in .config in the root of the buildroot directory) corresponds to the target x86–64 legacy machine (bios) boot.
Copy the Linux-kernel configuration (you will need this down the road):
cp board/pc/linux.config board/my_x86_board/
Configuring build parameters via KConfig
Run the setup:
make menuconfig
The KConfig window opens. It is possible to configure with a graphical interface (make nconfig, make xconfig, make gconfig):
Included in the first section of the Target Options. Here you can select the target architecture for which you will build.
Build options-there are various build settings here. You can specify the directory with the source code, the number of threads of the Assembly, the mirrors to download the source code, and other settings. Let’s leave the default settings.
Toolchain-here you can configure the build Toolkit itself. We will discuss it further.
Toolchain type — the type of used toolchain. This can be built into buildroot or an external toolchain (you can specify a directory with already collected or specify a download url). There are additional options for different architectures. For example, for arm, you can simply select the Linaro version of the external toolchain.
C library-the choice of C library. The whole system depends on it. Glibc is usually used, which supports all possible functionality. But it may be too big for the built-in system, therefore, we often choose uClibc or musl. We will choose glibc (this will be required in the future to use systemd).
Kernel Headers and Custom Kernel Headers series-must match the version of the kernel that will be in the assembled system. For kernel headers, you can also specify a tarball path or a git repository.
GCC COMPILER VERSIONS-select the compiler version that will be used for the build
Enable C++ support-choose to build with support for c++ libraries in the system. We will need it in the future.
Additional gcc options — you can set additional compiler options. So far, we don’t need to.
System configuration allows you to set future parameters of the created system:
Based on their names,the meaning of most items is clear. Let’s pay attention to the following points:
Path to the users tables — table with created users (https://buildroot.org/downloads/manual/manual.html#makeuser-syntax).
Sample file. The user will be created with the admin password, automatically gid/uid, /bin / sh shell, default user group, root group member, foo user comment
[alexey@alexey-pc buildroot]$ cat board/my_x86_board/users.txt
user -1 user -1 =admin /home/user /bin/sh root Foo user
Root filesystem overlay directories — a directory overlaid on top of the assembled target-fs. Adds new files and replaces existing ones.
Custom scripts to run before creating filesystem images — Scripts performed immediately before folding the file system into images. The script itself will be left blank for now.
Let’s move to the Kernel section
Kernel settings are set here. The kernel itself is configured through make linux-menuconfig.
You can set the kernel version in different ways: choose from the proposed ones, enter the version manually, specify the repository or a ready-made tarball.
Kernel configuration — the path to the kernel config. You can choose the default configuration for the selected architecture or defocnfig from Linux. Linux sources have a set of defconfig’s for different target systems. You can find the one you need by [looking directly at the source here] (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch). For example, for the beagle bone black board, you can [select the config] (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/configs/omap2plus_defconfig?id = v4.13).
The Target packages section allows you to select which packages will be installed on the system you’re building. Let’s leave it unchanged for now. Later we will add our packages to this list.
Filesystem images — a list of file system images to be collected. Add iso image
Bootloaders — the selection of assembled bootloaders. Select isolinix
Configuring Systemd
Systemd becomes one of the Linux posts, along with kernel and glibc. Therefore, I made its configuration in a separate paragraph.
It is configured through make menuconfig, then Target packages → System tools → systemd. Here you can specify which systemd services will be installed and run at the system startup.
Saving the system configuration
Save this config via KConfig.
Then save our defconfig:
make savedefconfig
Linux kernel configuration
The linux kernel configuration is invoked with the following command:
make linux-menuconfig
Add support of the Virtualbox graphics card
Add the Virtualbox Guest integration support
Save and exit. IMPORTANT: the configuration will be saved in output / build / linux- $ version / config, but not in board / my_x86_board / linux.config
So you need to manually copy the config to the storage location:
cp output/build/linux-4.19.25/.config board/my_x86_board/linux.config
With this command, I copy the FULL kernel config, which is not always necessary. The more correct way is to safe the kernel defconfig:
make linux-update-defconfig
Next, we will perform a complete reassembly of the entire system. Since Buildroot does not reassemble what has already been collected, you must manually specify the packages for reassembling. In order not to lose time and nerves, it is easier to rebuild the whole small system):
make clean;make
Upon the build’s completion, run VirtualBox (tested on versions 5.2 and 6.0) with booting from the cd-drive. System parameters:
Starting from the assembled iso: