Buildroot - part 2. Creating the configuration of your board; application of external tree, rootfs-overlay, post-build scripts
In this section, I consider some of the customization capabilities that I needed. This is not a complete list of what buildroot offers, but they are quite working and do not require intervention in the files of buildroot itself.
Using the EXTERNAL mechanism for customization
In the previous article, we considered a simple example of adding your configuration by adding the defconfig of the board and the necessary files directly to the Buildroot directory.
But this method is not very convenient, especially when updating buildroot. To solve this problem, there is an external tree mechanism . Its essence is that you can store board, configs, packages, and other directories in a separate directory (for example, I use the patches directory to apply patches to packages, more in a separate section) and buildroot will add them to those in its own directory.
Note: you can apply several external trees at once, there is an example in the buildroot manual
Create the my_tree directory next to the buildroot directory and transfer our configuration there. The output should be the following file structure:
[alexey@alexey-pc my_tree]$ tree
.
├── board
│ └── my_x86_board
│ ├── bef_cr_fs_img.sh
│ ├── linux.config
│ ├── rootfs_overlay
│ └── users.txt
├── Config.in
├── configs
│ └── my_x86_board_defconfig
├── external.desc
├── external.mk
├── package
└── patches
6 directories, 7 files
As you can see, in general, the structure follows the structure of buildroot.
The board directory contains files specific to each board in our case:
- bef_cr_fs_img.sh - a script that will be executed after building the target-file system, but before packing it into images. In the future we will use it
- linux.config - kernel configuration
- rootfs_overlay - directory to overlay on top of the target file system
- users.txt - file with a description of the created users
The configs directory contains the defconfigs of our boards. We have only one.
Package - a catalog with our packages. Initially, buildroot contains descriptions and rules for building a limited number of packages. Later we will add icewm window manager and Slim logon manager here.
Patches - allows you to conveniently store your patches for different packages. More details in a separate section below.
Now we need to add the description files of our external-tree. 3 files are responsible for this: external.desc, Config.in, external.mk.
external.desc contains the actual description:
[alexey@alexey-pc my_tree]$ cat external.desc
name: my_tree
desc: My simple external-tree for article
The first line is the name. In the future, buildroot create the variable $ (BR2_EXTERNAL_MY_TREE_PATH) , which must be used when configuring the assembly. For example, the path to the file with users can be set in the following way:
$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt
The second line is a brief, human-readable description.
Config.in, external.mk - files for the description of the added packages. If you do not add your packages, then these files can be left empty. So far we will do so.
Now we have our external-tree ready, containing the defconfig of our board and the files it needs. We’ll go to the buildroot directory, we will specify the use of external-tree:
[alexey@alexey-pc buildroot]$ make BR2_EXTERNAL=../my_tree/ my_x86_board_defconfig
#
# configuration written to /home/alexey/dev/article/ramdisk/buildroot/.config
#
[alexey@alexey-pc buildroot]$ make menuconfig
In the first command, we use the argument BR2_EXTERNAL = .. / my_tree / , indicating the use of an external tree. You can specify several external-trees for use at the same time. It is enough to do this once, after which an output / .br-external.mk file is created that stores information about the used external-tree:
[alexey@alexey-pc buildroot]$ cat output/.br-external.mk
#
# Automatically generated file; DO NOT EDIT.
#
BR2_EXTERNAL ?= /home/alexey/dev/article/ramdisk/my_small_linux/my_tree
BR2_EXTERNAL_NAMES =
BR2_EXTERNAL_DIRS =
BR2_EXTERNAL_MKS =
BR2_EXTERNAL_NAMES += my_tree
BR2_EXTERNAL_DIRS += /home/alexey/dev/article/ramdisk/my_small_linux/my_tree
BR2_EXTERNAL_MKS += /home/alexey/dev/article/ramdisk/my_small_linux/my_tree/external.mk
export BR2_EXTERNAL_my_tree_PATH = /home/alexey/dev/article/ramdisk/my_small_linux/my_tree
export BR2_EXTERNAL_my_tree_DESC = My simple external-tree for article
Important! In this file, the paths will be absolute!
The menu item External options appeared:
This submenu will contain our packages from our external-tree. Now this section is empty.
Now it’s more important for us to rewrite the necessary paths to use an external-tree.
Note that in the section Build options → Location to save buildroot config, there will be an absolute path to the saved defconfig. It is formed at the time of specifying the use of extgernal_tree.
Also in the System configuration section, fix the paths. For a table with user created:
$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt
In the Kernel section, change the path to the kernel configuration:
$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/linux.config
Now, the assembly will use our files from our external-tree. When transferring to another directory, updating buildroot, we will have a minimum of problems.
Adding root fs overlay:
This mechanism makes it easy to add / replace files in the target file system.
If the file is in root fs overlay but not in target, then it will be added.
If the file is in root fs overlay and in target, it will be replaced.
First, set the path to root fs overlay dir. This is done in the System configuration → Root filesystem overlay directories section:
$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/rootfs_overlay/
Now let's create two files.
[alexey@alexey-pc my_small_linux]$ cat my_tree/board/my_x86_board/rootfs_overlay/etc/hosts
127.0.0.1 localhost
127.0.1.1 my_small_linux
8.8.8.8 google-public-dns-a.google.com.
[alexey@alexey-pc my_small_linux]$ cat my_tree/board/my_x86_board/rootfs_overlay/new_file.txt
This is new file from overlay
The first file (my_tree / board / my_x86_board / rootfs_overlay / etc / hosts) will replace the / etc / hosts file on the finished system. A second file (cat my_tree / board / my_x86_board / rootfs_overlay / new_file.txt) will be added.
We collect and check:
Execution of customization scripts at different stages of system assembly
Often, you need to perform some actions inside the target file system before it is packaged into images.
Это можно сделать в разделе System configuration:
Первые два скрипта выполняются после сборки target-файловой системы, но до упаковки её в образы. Разница в том, что fakeroot-скрипт выполняется в контексте fakeroot, те имитируется работа от пользователя root.
Последний скрипт выполняется уже после создания образов системы. В нем можно выполнять дополнительные действия, например, скопировать нужные файлы на nfs-сервер или создать образ своей прошивки устройства.
В качестве примера я создам скрипт, который будет писать версию и дату сборки в /etc/.
Сначала укажу путь к этому файлу в моем external-tree:
А теперь сам скрипт:
[alexey@alexey-pc buildroot]$ cat ../my_tree/board/my_x86_board/bef_cr_fs_img.sh
#!/bin/sh
echo "my small linux 1.0 pre alpha" > output/target/etc/mysmalllinux-release
date >> output/target/etc/mysmalllinux-release
После сборки можно увидеть этот файл в системе.
На практике, скрипт может стать большим. Поэтому в реальном проекте я пошел более продвинутым путем:
- Created a directory (my_tree / board_my_x86_board / inside_fakeroot_scripts), in which scripts for execution, with serial numbers, lie. For example, 0001-add-my_small_linux-version.sh, 0002-clear-apache-root-dir.sh
- I wrote a script (my_tree / board_my_x86_board / run_inside_fakeroot.sh) that goes through this directory and sequentially runs the scripts in it
- This script indicated in the board settings in the System configuration -> Custom scripts to run inside the fakeroot environment ($ (BR2_EXTERNAL_my_tree_PATH) /board/my_x86_board/run_inside_fakeroot.sh)