Buildroot - 第 2 部分。创建您的主板配置; 使用外部树、rootfs-overlay、构建后脚本

在本节中,我将介绍一些我需要的自定义选项。 这不是 buildroot 提供的完整列表,但它们非常实用,并且不需要干预 buildroot 本身的文件。

使用EXTERNAL机制进行定制

在前面的文章 我们查看了一个简单的示例,通过将板的 defconfig 和必要的文件直接添加到 Buildroot 目录来添加您自己的配置。

但这种方法不太方便,尤其是更新buildroot时。 有一个机制可以解决这个问题 外部树。 它的本质是,你可以将 board、configs、packages 和其他目录存储在单独的目录中(例如,我使用 patch 目录将补丁应用于包,更多详细信息在单独的部分中),并且 buildroot 本身会将它们添加到它的目录。

注意:您可以一次覆盖多个外部树,buildroot 手册中有一个示例

让我们创建一个目录 my_tree,位于 buildroot 目录旁边,并将我们的配置传输到那里。 输出应该是以下文件结构:

[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

正如您所看到的,该结构总体上重复了 buildroot 的结构。

目录 在我们的例子中包含特定于每个板的文件:

  • bef_cr_fs_img.sh 是一个脚本,将在构建目标文件系统之后、将其打包成映像之前执行。 我们将来会用到它
  • linux.config - 内核配置
  • rootfs_overlay - 覆盖在目标文件系统之上的目录
  • users.txt - 描述要创建的用户的文件

目录 CONFIGS 包含我们主板的 defconfig。 我们只有一个。

小包装 - 我们的包装目录。 最初,buildroot 包含用于构建有限数量的包的描述和规则。 稍后我们将在这里添加icewm窗口管理器和Slim图形登录管理器。
补丁 — 允许您方便地存储不同包的补丁。 更多详细信息请参见下面的单独部分。
现在我们需要为外部树添加描述文件。 有 3 个文件负责此操作:external.desc、Config.in、external.mk。

外部.desc 包含实际描述:

[alexey@alexey-pc my_tree]$ cat external.desc 
name: my_tree
desc: My simple external-tree for article

第一行是标题。 在将来的buildroot中创建一个变量 $(BR2_EXTERNAL_MY_TREE_PATH),应在配置程序集时使用。 例如,用户文件的路径可以设置如下:

$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt

第二行是简短的、人类可读的描述。

配置.in、外部.mk — 描述添加的包的文件。 如果您不添加自己的包,那么这些文件可以留空。 现在,这就是我们要做的。
现在我们已经准备好外部树,其中包含板的 defconfig 及其所需的文件。 让我们进入buildroot目录并指定使用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

在第一个命令中我们使用参数 BR2_EXTERNAL=../my_tree/,表示使用外部树,可以同时指定多个外部树,此时只需要执行一次,之后会创建一个文件output/.br-external.mk,存储有关所使用的外部树的信息:

[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

重要的! 该文件中的路径将是绝对路径!

菜单中出现了一个外部选项项:

Buildroot - 第 2 部分。创建您的主板配置; 使用外部树、rootfs-overlay、构建后脚本

该子菜单将包含外部树中的包。 该部分目前为空。

现在对我们来说更重要的是重写必要的路径以使用外部树。

请注意,在“构建选项”→“保存构建根配置的位置”部分中,将有一个保存的 defconfig 的绝对路径。 它是在指定使用 extgernal_tree 时形成的。

我们还将更正系统配置部分中的路径。 对于已创建用户的表:

$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt

在 Kernel 部分中,更改内核配置的路径:

$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/linux.config

现在,我们的外部树中的文件将在组装过程中使用。 当移动到另一个目录或更新构建根目录时,我们将遇到最少的问题。

添加 root fs 覆盖:

这种机制允许您轻松地在目标文件系统中添加/替换文件。
如果文件位于根文件系统覆盖中,但不在目标中,则将添加该文件
如果该文件位于根文件系统覆盖层和目标中,则它将被替换。
首先,让我们设置根文件系统覆盖目录的路径。 这是在系统配置 → 根文件系统覆盖目录部分中完成的:

$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/rootfs_overlay/

现在让我们创建两个文件。

[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

第一个文件 (my_tree/board/my_x86_board/rootfs_overlay/etc/hosts) 将替换已完成系统上的 /etc/hosts 文件。 将添加第二个文件 (cat my_tree/board/my_x86_board/rootfs_overlay/new_file.txt)。

我们收集并检查:

Buildroot - 第 2 部分。创建您的主板配置; 使用外部树、rootfs-overlay、构建后脚本

在系统组装的不同阶段执行定制脚本

通常,在将目标文件系统打包到映像中之前,您需要在目标文件系统内执行一些工作。

这可以在系统配置部分完成:

Buildroot - 第 2 部分。创建您的主板配置; 使用外部树、rootfs-overlay、构建后脚本

前两个脚本在目标文件系统构建之后、打包成镜像之前执行。 不同之处在于 fakeroot 脚本是在 fakeroot 的上下文中执行的,它模拟 root 用户的工作。

最后一个脚本在创建系统映像后执行。 您可以在其中执行其他操作,例如,将必要的文件复制到 NFS 服务器或创建设备固件的映像。

例如,我将创建一个脚本,将版本和构建日期写入 /etc/.
首先,我将在外部树中指示该文件的路径:

Buildroot - 第 2 部分。创建您的主板配置; 使用外部树、rootfs-overlay、构建后脚本

现在是脚本本身:

[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

组装完成后,您可以在系统中看到该文件。

实际上,脚本可能会变得很大。 因此,在实际项目中我采取了更高级的路线:

  1. 我创建了一个目录(my_tree/board_my_x86_board/inside_fakeroot_scripts),其中有要执行的脚本,带有序列号。 例如,0001-add-my_small_linux-version.sh、0002-clear-apache-root-dir.sh
  2. 我编写了一个脚本(my_tree/board_my_x86_board/run_inside_fakeroot.sh),它遍历该目录并顺序执行其中包含的脚本
  3. 在系统配置 -> 要在 fakeroot 环境中运行的自定义脚本 ($(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/run_inside_fakeroot.sh) 部分的板设置中指定此脚本

来源: habr.com

添加评论