前言
新冠疫情期间在家里无事可做,奈何手上没有现成的开发板,又想调试学习linux内核,于是就有了这一系列的文章。本系列文章包含以下内容:
- 在家学习嵌入式1-搭建qemu环境
- 在家学习嵌入式2-在qemu环境下使用uboot启动linux
- 在家学习嵌入式3-使用Buildroot构建编译系统
- 在家学习嵌入式4-Versatile Express开发板
- 在家学习嵌入式5-buildroot的使用
使用buildroot进行开发的问题
buildroot的正常操作是下载一个tar包,解压缩,配置,编译和安装tar包里面的软件组件。源码文件展开到output/build/<package>-<version>
路径下,这是一个临时的目录。当执行make clean
的命令后,这个目录将整个被删掉。当下次执行make
命令的时候,该目录又会被重新创建。即使将Git或Subversion存储库用作包源代码的输入,Buildroot也会从中创建一个tar包,然后像对待tar包一样正常工作。
以我们的uboot为例,当我们执行make
的时候,会从 https://gitee.com/wowothink/u-boot.git 仓库上下载uboot到dl/
目录中,然后将其打包到dl/uboot/uboot-v2017.01.tar.gz
的tar包,之后再解压该tar包到output/build/uboot-v2017.01/
目录,之后就编译该目录。
按照上述的行为,我们不能在dl/
目录下修改源码,因为该源码会从远程仓库下载,我们也不能修改output/build/
目录下的源码,因为当我们执行clean
的时候,这个目录就没了。很明显,buildroot这样做使用起来很不方便。buildroot的初衷是用作集成工具来构建和集成嵌入式Linux系统的所有组件,也就是希望尽量的稳定和减少修改。
buildroot针对此情形提供了一种特定的机制:<pkg>_OVERRIDE_SRCDIR
机制,Buildroot读取_override_
文件,该文件允许用户告诉buildroot某些软件包的源位置。当buildroot发现给定软件包已经定义了<pkg>_OVERRIDE_SRCDIR
时,它将不再尝试下载,提取和给软件包打patch。相反,它将直接使用指定目录中可用的源代码,并且make clean
不会触及该目录。这允许将buildroot指向你自己的目录,该目录可以由Git,Subversion或任何其他版本控制系统进行管理。为此,buildroot将使用_rsync_
将组件的源代码从指定的<pkg>_OVERRIDE_SRCDIR
复制到output/build/<package>-custom/
目录。接下来我们就使用该机制,来进行uboot、kernel源码位置的重新指定。
uboot、kernel源码位置重新指定
创建local.mk文件
1
2mkdir board/qemu/arm-vexpress/config/
vi board/qemu/arm-vexpress/config/local.mk在
local.mk
文件中指定uboot和kernel源码的位置。1
2LINUX_OVERRIDE_SRCDIR=$(CONFIG_DIR)/dl/linux/git
UBOOT_OVERRIDE_SRCDIR=$(CONFIG_DIR)/dl/uboot/git重新配置
BR2_PACKAGE_OVERRIDE_FILE
的路径文件。Build options的配置 1
(CONFIG_DIR)/board/qemu/arm-vexpress/config/local.mk) location of a package override file
按照上述步骤,就配置好了uboot和kernel的源码的位置,以后修改源码就可以在我们指定的目录上修改。比如说我们编译uboot,会看到这么一句话:
1 | victor@victor-linux:~/work/temp/buildroot$ make uboot-rebuild |
很明显我们可以看到,编译uboot的时候会调用rsync
命令,将dl/uboot/git/
目录拷贝到output/build/uboot-custom/
目录,然后再去编译uboot-custom/
目录。这样子我们每次修改dl/uboot/git/
的内容,在编译的时候都会同步反映到output/build/uboot-custom/
目录。
rsync
命令是一个拷贝命令,相较于cp
命令,它更加的快,并且每次只拷贝有更新的文件。具体差异我也不是很懂。
常用命令
make menuconfig
:配置buildrootmake linux-dirclean
:删除output/build/linux-xxx/
目录;make uboot-dirclean
:删除output/build/uboot-xxx/
目录;make uboot-rebuild
:单独编译uboot;make linux-rebuild
:单独编译linux kernel;
buildroot代码结构
- 顶层
Makefile
:处理配置并且构建编译; - 顶层
Config.in
:主要选项配置,包括其他目录的Config.in
; arch/
:Config.in.*
文件定义架构相关的配置(处理器类型、ABI、浮点处理);toolchain/
:产生或使用的toolchains;system/
:用于系统范围的功能的选项,例如init
,/dev
处理等;linux/
:linux.mk
,Linux kernel的包;package/
:所有用户空间的包,包括busybox
等;fs/
:生成各种格式的文件系统镜像;boot/
:启动相关的包;configs/
:各个平台默认的配置;board/
:板级专用文件(包含内核配置文件,内核补丁,镜像烧写脚本等);support/
:各式工具;utils/
:buildroot开发的工具;docs/
:文档目录;dl/
:虽然一开始并没有dl(download)目录,但是在开始使用Buildroot后,会自动生 成一个dl目录,它主要用于存放Buildroot工具下载的内容,因为Buildroot是一系列工具的 管理集合,它本身并不存在这些编译工具,所以在使用时它自动会下载需要的工具,比如交叉 编译器、依赖的库、以 及一些软件源码包等(以压缩包的形式存放,Buildroot在使用时会自动解压),都会放在dl目录下;output/
:虽然一开始Buildroot也并没有output目录,但是在开始使用Buildroot后,就会自 动生成output目录,它是编译出来的输出文件夹,里面存放着解压后的各种软件包编译完后的 现场。同时output目录下还有各种文件夹,如host文件夹是由各类源码编译后在主机上运行工具的安装 目录,如arm-linux-gcc就是安装在这里;build文件夹是所有源码包解压出来的文件 存放地和编译的发生地;images文件夹则是在我们编译完成后存放uboot、内核镜像、设备树以及文件系统等结果的。