本文提供一种可行编译最新 Buildroot 系统的流程
在文章 Ubuntu22.04及以上版本buildroot SIGSTKSZ 报错问题 我提出了一种解决旧版本 buildroot 在一些比较新的编译环境下的报错途径,但是我实际操作后会发现,在整个编译过程中会不断出现各种包的错误,例如:在文章 解决 Builroot 系统编译 perl 编译报错问题 中我出现了 perl 这个工具的报错,因此想彻底解决旧 SDK 在新平台的编译报错问题,那么直接升级 SDK buildroot 是最高效的解决途径!
下面,一步一步带大伙走完该流程,也算我个人的一些笔记记录:
-
获取最新的 buildroot 源码,我们直接从 gitee 的镜像中下载,我当前记录的最新 buildroot 版本是
2025.02.x
:git clone -b 2025.02.x https://gitee.com/mirrors/buildroot.git
-
通过
menuconfig
配置 buildroot:-
首先是 Target:
Target Architecture
根据你实际的芯片架构选择,我使用的 RK3568 系统架构是 AArch64(arm64);
Target Architecture Varint
是芯片的内核 RK3568 CPU 是 4 核 Cortex-A55;
Target Binary Format
选择 ELF 格式;
剩下两个那默认即可,注意 MMU Page Size 你也可以查一下你的 datasheet 看一下你的 CPU 是的 MMU Page 是安装多大分页的,一般情况下都是 4K 这里我就使用默认了。 -
选择 Toolchain:
- Toolchain 推荐使用和 SDK 提供的 buildroot 采用同一个,目前暂不清楚不同的编译器类型会不会造成影响,后面我再测试一下。
Toolchain type
选择 External toolchain ;Toolchain
选择 Custom toolchain;Toolchain origin
选择 Pre-installed toolchain;- 然后是配置 交叉编译工具的路径,这使用绝对路径,例如:
/home/binwatson/rk3568/rk356x_linux/prebuilts/gcc/linux-x86/aarch64/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu
不需要带上二进制文件的 bin 路径; ($(ARCH)-linux) Toolchain prefix
设置工具链的前缀,可以进去 bin 目录看一下,例如:RK 有提供 ARCH 的软链接,因此我采用默认的即可。
External toolchain gcc version
选择你上面指定 SDK 中 GCC 的版本,我的是 9.x 版本的External toolchain kernel headers series
选择你 SDK 中 Linux 内核的版本,例如:我的是 4.19.232。大家可以通过读取 Makefile 中的定义获取版本:
External toolchain C library
这个选择 glibc 即可;
其它选项大家可以根据自己实际需求配置。
-
配置 System Configuration:
完成上面的
Target
、Toolchain
和System Configuration
三个配置就可以了,这里我们不适用 Buildroot 在编译 Linux kernel,我们采用 SDK 中自带的 kernel。 -
-
编译 buildroot,执行
make -j${nproc}
进行多线程编译。
在编译过程中大家可能会碰到,例如:我们前面指定的交叉编译工具 aarch-linux-cc1 这个工具缺少一些 .so 的动态链接库的问题,这个问题是我们使用的 SDK 中的交叉编译工具版本太老了导致的,它和我们目前编译环境中的 .so 版本匹配不上。
例如:我遇到的问题如下:home/binwatson/rk3568/rk356x_linux/prebuilts/gcc/linux-x86/aarch64/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu/bin/../libexec/gcc/aarch64-rockchip-linux-gnu/9.3.0/cc1: error while loading shared libraries: libisl.so.15: cannot open shared object file: No such file or directory make[2]: *** [scripts/Makefile.build:198: applets/applets.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [Makefile:372: applets_dir] Error 2 make[1]: Leaving directory '/home/binwatson/rk3568/buildroot/output/build/busybox-1.37.0' make: *** [package/pkg-generic.mk:273: /home/binwatson/rk3568/buildroot/output/build/busybox-1.37.0/.stamp_built] Error 2
这个问题出现在 cc1 这个工具上面,那么首先我们可以通过 ldd 查看 cc1 这个工具缺少那些库:
ldd /home/binwatson/rk3568/rk356x_linux/prebuilts/gcc/linux-x86/aarch64/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu/bin/../libexec/gcc/aarch64-rockchip-linux-gnu/9.3.0/cc1
如果查询出来发现后面的空的,或者和我图片上面的不一致,那么就是缺少了该动态库:
例如,我上面的报错中,表示错误原因是
error while loading shared libraries: libisl.so.15
缺少libisl.so.15
,我的解决办法就是创建一个 libisl.so.15 的软链接指向目前系统中带的 libisl.so.23:
然后再编译执行一下,发现就 OK 了!这个办法不一定可行,只是说一般新的会兼容旧的,大概率都能够解决,如果还是解决不了还有两条途径,第一,安装一个对应版本的libisl.so.15
这个动态库;第二,升级交叉编译工具; -
编译完成后,我们就需要制作 rootfs.img 镜像了,进入到
buildroot/output/images
中可以看到编译出来的rootfs.tar
,也可能是其它形式的压缩包取决于你在 buildroot menuconfig 中的配置,默认生成 tar。解压它会得到文件系统:
回到 output 目录,我们制作一个镜像,然后挂载到一个空目录,然后把文件系统拷贝到目录里面:mkdir rootfs # 创建一个 rootfs 目录 dd if=/dev/zero of=rootfs.img bs=1M count=1024 # 创建一个 rootfs.img 的镜像 mkfs.ext4 rootfs.img # 格式化镜像这里注意你使用的格式,我使用 ext4,基本上 linux 用这个格式不会错 sudo mount rootfs.img rootfs/ # 挂载 cp -rfp images/* rootfs/ # 将 images 里面解压的 rootfs.tar 里面的文件全部拷贝仅 rootfs 文件 umount rootfs/ # 卸载 e2fsck -p -f rootfs.img # 文件系统完整性检查并自动修复 resize2fs -M rootfs.img # 动态调整文件系统至 rootfs 所占大小
至此镜像就制作完毕了,建议大家先烧录 SDK 默认的带 buildroot 的镜像,然后在烧录我们的 rootfs 镜像进去,这里我前面忘记关闭 password 了,因此需要登录一下,不过可以看到 iTOP-RK3568 这个前面设置在 buildroot 中的文本正常打印出来了。