16. Buildroot根文件系统的构建¶
注意
当前仅支持使用LubanCat_Gen_SDK构建基于RK3576和RK3562主芯片的鲁班猫板卡的buildroot镜像
注意
包含buildroot组件的LubanCat_Gen_SDK仅提供源码压缩包,可通过百度网盘获取。压缩包名称为LubanCat_Linux_Generic_Full_SDK.tgz,此源码压缩包无法通过网络进行在线更新。
错误
buildroot相关内容不提供技术支持,仅供有能力自行开发的用户使用!!!
buildroot相关内容不提供技术支持,仅供有能力自行开发的用户使用!!!
buildroot相关内容不提供技术支持,仅供有能力自行开发的用户使用!!!
16.1. 什么是Buildroot?¶
Buildroot是Linux平台上一个开源的嵌入式Linux系统自动构建框架。整个Buildroot是由Makefile脚本和Kconfig配置文件构成的。 你可以和编译Linux内核一样,通过buildroot配置,menuconfig修改,编译出一个完整的可以直接烧写到机器上运行的Linux系统软件。
借助LubanCat_Gen_SDK,可以更方便的进行Buildroot根文件系统的构建和Buildroot系统镜像的制作。
LubanCat_Gen_SDK使用了Buildroot-2024.02作为基础版本, 并在此基础上修改和添加了一些由Rockchip开发的适用于RK处理器软件包,以及由野火添加的适配LubanCat板卡功能的软件包, 其包含了基于Linux系统开发⽤到的各种系统源码,驱动,⼯具,应⽤软件包。
Buildroot 有以下⼏点优势:
通过源码构建,有很⼤的灵活性;
⽅便的交叉编译环境,可以进⾏快速构建;
⽅便各系统组件配置及定制开发。
使⽤ Buildroot最出名的项目就是OpenWrt,由它制作出的镜像可以跑在搭载16Mb SPI Flash的路由器上, 系统基本没包含多余的东西。得益于Buildroot的简单化,整个Buildroot project 可以在⼀个git仓库维护。 Buildroot使⽤kconfig和make,⼀个defconfig配置代表⼀种BSP⽀持。
16.1.1. SDK目录说明¶
app:存放供buildroot构建使用的应用demo
buildroot:存放buildroot源码
external:存放供buildroot使用的第三方仓库
16.2. Buildroot构建¶
由于LubanCat_Gen_SDK中就已经包含了编译所需的Buildroot源码和工具链,可以直接进行编译。
在构建Buildroot根文件系统前,先要根据对应的板卡选择SDK配置文件
目前LubanCat_Gen_SDK中的buildroot项目支持以下板卡:
鲁班猫1HS系列,使用RK3562/RK3562J(工业级)主芯片
鲁班猫3系列,使用RK3576主芯片
1 2 3 4 5 | # 选择将要构建的板卡使用的主芯片
./build.sh chip
# 选择将要使用的配置文件
./build.sh lunch
|

每个芯片可选的buildroot配置文件有两个,分别是:
LubanCat_(主芯片型号)_buildroot_extboot_defconfig
LubanCat_(主芯片型号)_buildroot_rkboot_defconfig
这两个配置文件的主要差异是使用的分区打包格式不同,导致功能有差异。 有关rkboot和extboot的详细差异请查看章节 LubanCat_Chip_SDK - extboot与rkboot分区对比 此处仅列出buildroot镜像的差异
分区格式 |
extboot |
rkboot |
支持板卡 |
所有使用同一主芯片的LubanCat板卡 |
指定型号的LubanCat板卡 |
配置文件 |
高度适配LubanCat板卡 |
基于官方配置简单修改,仅作为示例,无法直接使用 |
使用方式 |
直接使用 |
需要基于目标板卡修改设备树和buildroot配置文件 |
自动切换设备树 |
支持 |
不支持 |
设备树插件 |
支持 |
不支持 |
支持OTA |
不支持 |
支持 |
功能适配 |
部分RK开发的特性不支持 |
完整支持 |
开发难度 |
高(学习和体验Buildroot) |
超高(资深开发者进行功能高度定制) |
有关rkboot配置文件的修改,将会在本章后面的内容介绍
选择了exboot分区的配置文件之后,就可以开始编译构建了。
1 2 3 4 5 | # 一键编译完整的Buildroot系统镜像
./build.sh
# 只构建Buildroot根文件系统
./build.sh buildroot
|


提示
在buildroot构建时,会下载大量的软件包源码存放在buildroot/dl目录下, 我们已经将buildroot默认的软件源修改为国内镜像源,但是由于仍然有部分源码服务器位于国外, 所以编译时请保证网络畅通和较高的源码压缩包下载速度,否则会导致构建时间过长或构建失败。
buildroot的构建目录在buildroot/output目录下,这里存放了所有被编译的软件包的源码和构建文件。 通过配置文件的命名来区分不同方案的构建目录,这样可以支持多个方案切换而不用清空构建好的内容,提升开发效率。
buildroot/output/latest指向最后一次构建的方案路径,以rockchip_rk3576_lubancat为例
build:软件包源码解压及编译的目录,包括宿主机所需的⼯具和目标系统所需的软件包
host:包含交叉编译工具链、构建工具和宿主机所使用的工具
images:最终生成的buildroot相关镜像保存目录
staging:目标系统的开发环境,包含编译软件包所需的库和头文件,软链接到了host/aarch64-buildroot-linux-gnu/sysroot目录
target:根文件系统环境,软件包编译后生成的产物将会被安装到这里,最终打包为根文件系统镜像。
构建生成的buildroot根文件系统镜像:buildroot/output/latest/images/rootfs.ext4
一键构建完成的完整系统镜像:output/firmware/update.img
16.3. Buildroot开发流程¶
16.3.1. 修改Buildroot配置文件¶
buildroot的每一个配置文件就是一个构建方案,配置文件保存在buildroot/configs目录下
鲁班猫板卡使用的配置文件是:
rockchip_rk3576_lubancat_defconfig
rockchip_rk3562_lubancat_defconfig
通过观察配置文件,发现配置文件使用了 #include “xxx.config” 的方式来引用其他配置文件。 这是由于Rockchip对配置文件的格式做了修改,便于用户切换预定义的组件。
除 #include 外的其他内容就是野火针对LubanCat板卡做的修改。
可以手动修改configs目录下的配置文件,也可以使用SDK提供的配置文件修改命令。 对于rk这套#include没有深入了解的不建议手动修改,以防止配置出现冲突。
1 2 | # SDK配置
./build.sh bconfig
|
Buildroot使用kconfig进行配置,其使用方法与kernel的配置基本相同,可以按层级打开或关闭配置,也可以直接搜索

当修改完成配置以后,多次按Esc键,退出图形配置界面,如果提示是否保存配置文件,选择Yes

使用./build.sh bconfig修改完成配置文件以后,会自动覆盖原有的配置文件。
16.3.2. buildroot构建清理¶
由于buildroot的构建机制导致所有生成的文件都会被安装到target目录下并打包成rootfs镜像。 当修改配置文件之后,buildroot仅会将新选择的软件包编译并安装,如果在配置文件中移除了一些软件包, 或者由于依赖关系,一些软件包已经不再需要时,buildroot不会主动去清理这些软件包。
并且,buildroot不会去检测软件包是否被修改,如果修改了某个已经编译过的软件包的内容,在构建时不会重新构建这个修改过的软件包。
为了让修改能被应用,可以先清理之前构建时生成的文件。
根据之前对输出目录的介绍,可知build和target目录一定要清理,images目录下的内容会被覆盖, host目录为宿主机使用的工具一般不用清理。
由于Rockchip对buildroot的make进行了修改,有些原生buildroot支持的make命令无法使用,这里可以使用手动删除的方法。
找到选择的配置文件对应的输出目录,如rockchip_rk3576_lubancat_defconfig对应的输出目录是buildroot/output/rockchip_rk3576_lubancat, 删除这个目录下对应的要清理的目录即可
16.3.3. Rootfs-Overlay¶
除了通过软件包向根文件系统安装文件以外,还可以通过rootfs-overlay的方式, 在rootfs镜像打包前将文件覆盖到target目录中。
rootfs-overlay方式主要是用来覆盖或写入一些配置文件或脚本。
可以通过buildroot的BR2_ROOTFS_OVERLAY选项来进行配置,例如 rockchip_rk3562_lubancat_defconfig 配置文件
1 | BR2_ROOTFS_OVERLAY="board/rockchip/common/base board/rockchip/rk3562/fs-overlay/ board/rockchip/common/lubancat/"
|
设置了三个路径,中间用空格隔开,在buildroot打包镜像前会按顺序进行覆盖,在配置时需要注意文件覆盖顺序。
16.3.4. 编译单个软件包¶
如前文所说,buildroot不会去检测软件包是否被修改,如果修改了某个已经编译过的软件包的内容,在构建时不会重新构建这个修改过的软件包。
由于buildroot的编译过程很慢,如果每次都清除整个build目录重新编译,这将耗费大量时间,尤其是使用软件包较多的项目。
可以只对单个软件包进行操作。命令格式为 make <package>-<command>
source |
从网络获取源代码 |
depends |
构建和安装构建此软件包所需的依赖 |
extract |
将源代码放在包构建⽬录中(解压、复制源代码等) |
patch |
应⽤补丁,如果有的话 |
configure |
运⾏configure命令,仅部分软件包支持 |
build |
运⾏编译命令 |
install-staging |
安装软件包 |
install |
执行build和install-staging |
show-depends |
显⽰构建软件包所需的依赖 |
clean |
从host和target⽬录中卸载软件;仅部分软件包支持 |
dirclean |
删除整个包构建⽬录 |
rebuild |
重新运⾏编译命令 |
reconfigure |
重新运⾏配置命令 |
reinstall |
重新安装软件包 |
在buildroot目录下执行以下命令,以vim软件包为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 获取软件包,如果本地dl目录中不存在会从网络获取
make vim-source
# 解压软件包到build目录,然后向解压到build目录的软件包打补丁
# 常常在软件包开发调试时使用
make vim-extract
make vim-patch
# 编译软件包
make vim-configure
make vim-build
make vim-install
# 清除软件包
make vim-dirclean
# 重新编译软件包
make vim-reconfigure
make vim-rebuild
make vim-reinstall
|
16.3.5. 添加新的软件包¶
在buildroot的开发过程中,有时需要添加一些自己的软件包,这里以野火为LubanCat板卡添加的lbc-firmware软件包为例
在合适的位置创建一个目录,为了和Rockchip的修改统一,在buildroot/package/rockchip目录下创建lbc-firmware目录
16.3.5.1. Config.in¶
将软件包加入buildroot配置工具的管理
1 2 3 4 | config BR2_PACKAGE_LBC_FIRMWARE
bool "lbc-firmware"
help
copy lubancat firmware to rootfs
|
添加Config.in文件以后,就可以通过buildroot的menuconfig的BR2_PACKAGE_LBC_FIRMWARE来选择开启和关闭配置项。
这里需要注意,配置选项的命令需要遵循一定的规则,软件包的开启和关闭一般以 BR2_PACKAGE_(软件包所在目录的全大写)
除了开启或关闭软件包之外,还可以添加选项来配置软件包的编译条件,这里的示例比较简单,更复杂的可以参考buildroot其他软件包的Config.in
16.3.5.2. .mk¶
.mk文件对软件包的下载、配置、构建、安装等细节进行了描述。mk⽂件的内容比较灵活,需要根据实际软件包的编译工具使⽤不同的结构。
1 2 3 4 5 6 7 8 9 10 11 | LBC_FIRMWARE_VERSION = 1.0
LBC_FIRMWARE_SITE_METHOD = local
LBC_FIRMWARE_SITE = $(TOPDIR)/../external/firmware
FIRMWARE_DIR := $(TARGET_DIR)/lib/firmware
define LBC_FIRMWARE_INSTALL_TARGET_CMDS
mkdir -p $(TARGET_DIR)/lib/firmware
cp -r $(LBC_FIRMWARE_SITE)/* $(FIRMWARE_DIR)
endef
$(eval $(generic-package))
|
.mk文件的文件名应与软件包所在的目录一致,如软件包配置文件保存的目录是lbc-firmware,则mk的名称应该是lbc-firmware.mk。
在mk文件内,配置项的名称也与mk文件的名称保持一致,但是要使用字母全部大写的格式,并且要将分隔符 - 变为分隔符 _
VERSION:软件包的版本
SITE_METHOD:软件包源码保存地址的类型,local为本地软件包,还有git、svn等,如果不指定默认为tarball
SITE:软件包源码路径,local需要指定本地路径,git、svn、tarball等还要指定网址,如果不指定的话默认从buildroot自己的软件源中下载。
INSTALL_TARGET_CMDS:软件包安装命令
这里简单对mk文件的配置进行了说明,如果有更复杂的功能需要实现,可以参考其他软件包的mk文件或查看buildroot官方文档
16.4. rkboot配置文件的修改¶
根据前文描述,rkboot配置仅基于官方配置进行了简单适配,以使资深开发者在LubanCat板卡上进行Rockchip原生buildroot固件的开发。
注意
此配置选项不提供任何技术支持,仅提供给有开发能力的用户使用
为了进一步适配用户手中的LubanCat板卡,需要对一些文件及配置进行修改。
16.4.1. LubanCat_(主芯片型号)_buildroot_rkboot_defconfig¶
此文件为SDK配置文件
1 2 3 4 5 6 7 8 9 | RK_ROOTFS_HOSTNAME_CUSTOM=y
RK_ROOTFS_HOSTNAME="LubanCat"
RK_ROOTFS_INSTALL_MODULES=y
# RK_WIFIBT is not set
RK_UBOOT_SPL=y
RK_KERNEL_PREFERRED="6.1"
RK_KERNEL_CFG="lubancat_linux_rk3576_defconfig"
RK_KERNEL_DTS_NAME="rk3576-lubancat-generic"
RK_USE_FIT_IMG=y
|
RK_ROOTFS_HOSTNAME:设置hostname为LubanCat
RK_ROOTFS_INSTALL_MODULES:将内核编译的ko文件安装到rootfs
# RK_WIFIBT is not set:不使用rk-wifibt驱动,使用内核中的
RK_KERNEL_PREFERRED:指定内核版本为6.1
RK_KERNEL_CFG:指定内核配置文件为lubancat_linux_rk3576_defconfig,根据芯片选择
RK_KERNEL_DTS_NAME:设备树名称
用户需要将RK_KERNEL_DTS_NAME修改为自己板卡的设备树,具体名称可以查看:kernel-6.1/arch/arm64/boot/dts/rockchip/Makefile
RK_KERNEL_CFG不建议修改,如果要增删内核驱动的话用./build.sh kconfig直接修改已经指定的配置文件即可。
16.4.2. buildroot配置文件¶
rkboot使用了Rockchip官方的buildroot配置文件,未进行修改。配置文件保存在buildroot/configs目录下
用户如果要修改配置文件可以使用./build.sh bconfig去修改。
LubanCat的修改内容可以参考 rockchip_(主芯片型号)_lubancat_defconfig
16.4.3. 板卡设备树¶
由于rkboot不支持设备树插件,因此一些硬件功能需要用户自行添加并编译到镜像中。
打开前面配置文件指定的设备树,此处以LubanCat-3为例。打开文件kernel-6.1/arch/arm64/boot/dts/rockchip/rk3576-lubancat-3.dts
在设备树文件靠前的位置,已经添加了一些常用的外设配置,通过#include的方式引用。
1 2 3 4 5 | // #include "rk3576-lubancat-3-dsi-1080x1920-5-5inch-ebf410125.dtsi"
// #include "rk3576-lubancat-3-dsi-1024x600-7inch-ebf410173.dtsi"
// #include "rk3576-lubancat-3-dsi-800x1280-10-1inch-ebf410177.dtsi"
#include "rk3576-lubancat-3-csi.dtsi"
|
如上所示,#include了几个dtsi文件,其中有三个屏幕配置,需要将实际使用的屏幕配置取消注释(删除//)。
需要注意,一般同一类型的dtsi文件同一时间只可开启一个,上方代码中有三个使用dsi接口的不同屏幕,就只能选择一个。 如果配置了两个不同的dsi接口,则有时可以同时开启两个(还需根据其他情况具体决定)。
除此还要注意,有些dtsi文件原本是搭配设备树插件使用的,里面的节点并未“okay”而是处于“disabled”的状态。 这时就需要参考设备树插件来开启对应的节点。
打开kernel-6.1/arch/arm64/boot/dts/rockchip/uEnv/rk3576/uEnvLubanCat3.txt文件, 这里保存了所有LubanCat-3板卡所能使用的设备树插件的列表。 设备树插件保存在kernel-6.1/arch/arm64/boot/dts/rockchip/overlay目录下
如果要在设备树中开启相应的功能,可以参考设备树插件中配置的设备树节点手动在板卡设备树中开启。
例如设备树插件rk3576-lubancat-3-dp-disabled-ovetlay.dts的作用是关闭Type-C接口的DP视频输出, 源文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/display/drm_mipi_dsi.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
fragment@0 {
target = <&dp>;
__overlay__ {
status = "disabled";
};
};
fragment@1 {
target = <&dp0>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&dp0_in_vp0>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <&dp0_in_vp1>;
__overlay__ {
status = "disabled";
};
};
fragment@4 {
target = <&dp0_in_vp2>;
__overlay__ {
status = "disabled";
};
};
fragment@5 {
target = <&vp1>;
__overlay__ {
status = "disabled";
};
};
fragment@6 {
target = <&route_dp0>;
__overlay__ {
status = "disabled";
};
};
fragment@7 {
target = <&dp0_sound>;
__overlay__ {
status = "disabled";
};
};
fragment@8 {
target = <&spdif_tx3>;
__overlay__ {
status = "disabled";
};
};
};
|
那么如何移植到板卡设备树rk3576-lubancat-3.dts中呢?需要在板卡设备树中搜索所有设备树插件里 target = <&xxx>; 对应的节点, 例如在rk3576-lubancat-3.dts中搜索 &dp ,将 &dp 中的 status 改为和设备树插件一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | &dp {
status = "disabled";
};
&dp0 {
status = "disabled";
};
&dp0_in_vp0 {
status = "disabled";
};
&dp0_in_vp1 {
status = "disabled";
};
&dp0_in_vp2 {
status = "disabled";
};
&vp1 {
status = "disabled";
};
&route_dp0 {
status = "disabled";
connect = <&vp1_out_dp0>;
};
&dp0_sound {
status = "disabled";
};
&spdif_tx3 {
status = "disabled";
};
|
有时会出现在板卡设备树没有设备树插件中同样节点的情况,这时在板卡设备树的最后手动追加即可
例如设备树插件rk3576-lubancat-uart8-m2-overlay.dts的功能是开启uart8并使用m2这一组引脚
设备树插件内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&uart8>;
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart8m2_xfer>;
};
};
};
|
在板卡设备树rk3576-lubancat-3.dts中搜索发现并没有 &uart8 这个节点,此时就需要在板卡设备树的最后手动追加
将设备树插件中的对应节点复制,删除画红线的部分,最后整理一下格式

1 2 3 4 5 | &uart8 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart8m2_xfer>;
};
|
修改完设备树以后使用 ./build.sh kernel命令重新打包boot分区就会应用修改后的设备树
16.5. 参考资料¶
《Rockchip_Developer_Guide_Buildroot_CN.pdf》
《The Buildroot user manual》 https://buildroot.org/downloads/manual/manual.html