在本节中,我将考虑一些我需要的自定义功能。 这不是buildroot提供的功能的完整列表,但是它们相当有效,并且不需要干预buildroot本身的文件。
使用EXTERNAL机制进行自定义
在上一篇文章中,我们考虑了一个简单的示例,该示例通过将开发板的defconfig和必需的文件直接添加到Buildroot目录中来添加配置。
但是此方法不是很方便,尤其是在更新buildroot时。 为了解决这个问题,有一个外部树机制。 其本质是您可以将电路板,配置,软件包和其他目录存储在单独的目录中(例如,我使用patchs目录将补丁程序应用于软件包,更多内容在单独的部分中),并且buildroot会将它们添加到其自己的目录中。
注意:您可以一次应用多个外部树,buildroot手册中有一个示例
在buildroot目录旁边创建my_tree目录,然后在此处转移我们的配置。 输出应为以下文件结构:
[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目录包含我们主板的defconfigs。 我们只有一个。
软件包 -包含我们软件包的目录。 最初,buildroot包含用于构建数量有限的软件包的描述和规则。 稍后,我们将在此处添加icewm窗口管理器和Slim登录管理器。
补丁程序 -使您可以方便地存储不同软件包的补丁程序。 更多详细信息,请参见下面的单独部分。
现在,我们需要添加外部树的描述文件。 这由3个文件负责:external.desc,Config.in,external.mk。
external.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
第二行是简短的,易于阅读的描述。
Config.in,external.mk-用于描述所添加软件包的文件。 如果您不添加软件包,则这些文件可以保留为空。 到目前为止,我们将这样做。
现在我们已经准备好外部树,其中包含板的defconfig及其所需的文件。 我们将转到buildroot目录,我们将指定使用外部树:
[alexey@alexey-pc buildroot]$ make BR2_EXTERNAL=../my_tree/ my_x86_board_defconfig
在第一个命令中,我们使用参数BR2_EXTERNAL = .. / my_tree / ,指示外部树的使用,您可以同时指定多个外部树以供使用,只需执行一次即可,然后创建一个输出/ .br-external.mk文件,该文件存储有关使用的外部树的信息:
[alexey@alexey-pc buildroot]$ cat output/.br-external.mk
重要! 在此文件中,路径将是绝对的!
出现菜单项“外部选项”:

该子菜单将包含来自外部树的软件包。 现在此部分为空。
现在,对于我们来说,重写使用外部树的必要路径更为重要。
请注意,在“构建选项”→“保存buildroot配置的位置”部分中,将存在保存的defconfig的绝对路径。 它是在指定使用extgernal_tree时形成的。
同样在“系统配置”部分中,修复路径。 对于用户创建的表:
$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt
在“内核”部分中,将路径更改为内核配置:
$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/linux.config
现在,程序集将使用外部树中的文件。 当转移到另一个目录,更新buildroot时,我们将遇到的问题降到最低。
添加根fs覆盖:
这种机制使在目标文件系统中添加/替换文件变得容易。
如果文件在根fs覆盖中,但不在目标中,则将其添加
如果该文件位于根fs覆盖中并且位于目标中,则它将被替换。
首先,将路径设置为root fs overlay dir。 这是在系统配置→根文件系统覆盖目录部分中完成的:
$(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)。
我们收集并检查:

在系统组装的不同阶段执行定制脚本
通常,在将目标文件系统打包到映像中之前,您需要执行一些操作。
这可以在“系统配置”部分中完成:

前两个脚本是在构建目标文件系统之后但将其打包到映像之前执行的。 不同之处在于fakeroot脚本是在fakeroot的上下文中执行的,它们模拟了root用户的工作。
创建系统映像后执行最后一个脚本。 您可以在其中执行其他操作,例如,将必要的文件复制到nfs服务器或创建设备固件的映像。
例如,我将创建一个脚本,该脚本将在/ etc /中写入版本和构建日期。
首先,我将在我的外部树中指示此文件的路径:

现在脚本本身:
[alexey@alexey-pc buildroot]$ cat ../my_tree/board/my_x86_board/bef_cr_fs_img.sh
组装后,您可以在系统中看到此文件。
实际上,脚本可以变大。 因此,在一个真实的项目中,我采用了更高级的方法:
- 创建了一个目录(my_tree / board_my_x86_board / inside_fakeroot_scripts),其中包含用于执行的脚本(带有序列号)。 例如,0001-add-my_small_linux-version.sh,0002-clear-apache-root-dir.sh
- 我编写了一个脚本(my_tree / board_my_x86_board / run_inside_fakeroot.sh),该脚本会遍历此目录并依次在其中运行脚本
- 该脚本在系统配置->自定义脚本中的板设置中指示,以在fakeroot环境中运行($(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/run_inside_fakeroot.sh)