Building Embeded Linux Systems (2) Building SDK with Buildroot

Building Embeded Linux Systems (2) Building SDK with Buildroot

基于之前文章制作的toolchain,本文使用buildroot搭建一个可用的sdk。原材料有:buildroot-2018.5,上文中制作的外部arm-gcc toolchain,可用的linux kernel源码(linux-3.10),uboot源码。
buildroot是一个用来搭建sdk的极好的开源工具。它功能很多,并且有详细的文档。本文只用到了一小部分功能,并只对我自己用到部分进行记录和分享。

br2-external

buildroot提供了br2-external功能来添加外部定制的工程目录。外部的目录叫做external-tree。详细的手册地址是:
https://buildroot.org/downloads/manual/manual.html#br2-external-converting chapter 9。

建立工作路径

sdk根目录如图下图,其中dl是下载的源码包所在目录,是运行start.sh后生成的buildroot的一个目录。buildroot-2018.05是buildroot源码目录,out是编译工作目录,platform是external-tree,toolchain是外部toolchain目录。
在这里插入图片描述
platform是根据文档中推荐的外部目录结构建立的目录层次。详细见手册
在这里插入图片描述

工作过程

在start.sh脚本中执行

make -C ${BUILD_ROOT_DIR} O=${OUT_DIR}  BR2_EXTERNAL=${PLATFORM_DIR} arm2416_defconfig

O是制定编译工作目录,BR2_EXETERNAL制定外部目录。执行时会自动外部目录configs下的arm2416_defconfig默认配置文件。在输入BR2_EXTERNAL参数时 有
在这里插入图片描述
support/scripts/br2-external查找platform目录下的external.desc 文件读入name和desc
在这里插入图片描述
在out目录下生成**.br-external.mk** 包含外部定制信息的几个变量。BR2_EXTERNAL_MKS是外部的external.mk文件,作为外部makefile的入口。还有是BR2_EXTERNAL_arm2416_PATH和BR2_EXTERNAL_arm2416_DESC,
下图中会根据这两个值生成kconfig需要包含的文件,这个将作为外部kconfig的入口,它会source外部目录下的Config.in 文件。
在这里插入图片描述
external.mk是这一条指令,还可以其他需要的。
在这里插入图片描述
外部Config.in的内容作为一个例子可以是
在这里插入图片描述

其他

在platform需要建立local.mk,它包含一些本地定制化的makefile指令,比如需要使用本地的kernel和uboot就需要设置
在这里插入图片描述
设置这四个变量指示uboot和kernel的源码都从本地制定路径获取。
在packages中建立了audio_sample例子package,这个属于自己的package。audio_sample的audio_sample.mk文件和Config.in如下
在这里插入图片描述
在这里插入图片描述
执行start.sh后,进入out目录执行make menuconfig,就可以修改配置,此时可以看到会生成如下external options
在这里插入图片描述
进入external options有
在这里插入图片描述
make menuconfig中可以修改的重要配置都有:
target options
build options :配置保存defconfig的路径,配置dl下载源码的路径,host主机工具的路径,外部local.mk的路径
toolchain:配置外部toolchain的路径,交叉编译器的前缀,外部gcc的版本,kernel头文件的版本,外部使用的C库类型
kernel : 可以配置外部默认配置的路径
target packages: 可以配置busybox使用的外部默认配置文件和其他需要的内部package
filesystem images: 可以配置使用的文件系统类型

buildroot 执行过程

buildroot将所有需要的mk脚本都include到顶层makefile中,它的所有主要功能都在顶层makefile中执行。
主要脚本:
support/kconfig: kconfig 解释器目录
support/scripts/br2-external: 生成external配置信息的shell脚本
support/misc/util.mk: 提供一些简单的makefile函数,如去掉两端空白,大小写转换等
boot/common.mk 是处理uboot等启动相关package的makefile文件
linux/linux.mk是处理kernerl package的makefile文件。
fs/comon.mk: 构造rootfs的mk脚本,会包含fs//.mk,根据不同的rootfs类型配置,制定的脚本会执行。
system/system.mk:提供创建target rootfs目录的makefile函数
package/Makefile.in: 处理不同类型package的顶层makefile会包含下面的
package/pkg-*.mk: 相应类型包的处理函数文件
pkg-utils.mk 提供pkgdir和pkgname函数

pkg-generic.mk

通用类型包是其他类型包的实现基础。它为目标板target package和主机host package提供编译架构,通过pkg-generic.mk, 我们可以使用buildroot提供的软件包构造目标板程序,也可以构造运行在host上的工具程序。
在这里插入图片描述
内部调用的inner-generic-package函数。它的依赖关系图如下:
在这里插入图片描述
该依赖关系图可以基本描述该函数的执行过程,其他细节需要到源码中充实,尤其是可以在各个过程中间添加HOOK。
注意事项:
在make package-reconfigure 和 make package-rebuild都会有删除.stamp_rsync的动作。也就是两个指令都会进行源码同步。因为buildroot 中使用rsync -au u的作用是或略比原始文件新的修改文件。所以源码同步动作在执行两个指令时对于在build目录下的修改都不会被覆盖。所以这时如果希望恢复到source源码的话,需要先make package-dirclean, 然后再make package.

目标文件系统目录的构建

在使用pkg-generic时有几个重要的变量。
$(2)_ADD_SKELETON_DEPENDENCY 设为YES,是在编译这个package时要先构造出目标文件系统的目录结构。

ifeq ($(4),target)
ifeq ($$($(2)_ADD_SKELETON_DEPENDENCY),YES)
$(2)_DEPENDENCIES += skeleton
endif
ifeq ($$($(2)_ADD_TOOLCHAIN_DEPENDENCY),YES)
$(2)_DEPENDENCIES += toolchain
endif
endif

构造目标文件系统目录时依赖skeleton,在package目录下有skeleton目录,还有skeleton-init-common和skeleton-init-sysv,在skeleton包中会添加skeleton-init-sysv的依赖,而skeleton-init-sysv依赖skeleton-init-common。
在pkg-virtual.mk中,这里设置了skeleton对sysv的依赖。

ifeq ($(4),target)
$(2)_DEPENDENCIES += $$(call qstrip,$$(BR2_PACKAGE_PROVIDES_$(2)))

sysv目录下config.in

config BR2_PACKAGE_SKELETON_INIT_SYSV
	bool
	select BR2_PACKAGE_HAS_SKELETON
	select BR2_PACKAGE_SKELETON_INIT_COMMON

config BR2_PACKAGE_PROVIDES_SKELETON
	default "skeleton-init-sysv" if BR2_PACKAGE_SKELETON_INIT_SYSV

sysv下.mk文件

SKELETON_INIT_SYSV_ADD_TOOLCHAIN_DEPENDENCY = NO
SKELETON_INIT_SYSV_ADD_SKELETON_DEPENDENCY = NO

SKELETON_INIT_SYSV_DEPENDENCIES = skeleton-init-common

SKELETON_INIT_SYSV_PROVIDES = skeleton

define SKELETON_INIT_SYSV_INSTALL_TARGET_CMDS
	$(call SYSTEM_RSYNC,$(SKELETON_INIT_SYSV_PKGDIR)/skeleton,$(TARGET_DIR))
endef

$(eval $(generic-package))

根目录system目录有构造目标文件系统相关的文件,其中skeleton是文件系统根目录基本框架。其中system.mk 提供了构建目标文件系统相关的makefile函数。
skeleton-init-common包构建基本目录层次,skeleton-init-sysv包添加sysv启动相关的文件。

toolchain 依赖

在generic-package中toolchain依赖默认是开启的,就是说所有的编译对象都会依赖toolchain。 buildroot中的toolchain有两种选择内部toolchain和外部toolchain。
先以制作好的外部toolchain为例。

$(2)_ADD_TOOLCHAIN_DEPENDENCY	?= YES

在toolchain/toolchain/toolchain.mk 中处理toolchain编译target。 根据配置会依赖外部toolchain-external

ifeq ($(BR2_TOOLCHAIN_BUILDROOT),y)
TOOLCHAIN_DEPENDENCIES += toolchain-buildroot
else ifeq ($(BR2_TOOLCHAIN_EXTERNAL),y)
TOOLCHAIN_DEPENDENCIES += toolchain-external
endif
.......
$(eval $(virtual-package))

在toolchain/toolchain-external/pkg-toolchain-external.mk处理toolchain-external编译target,在编译toolchain-external的过程中会封装toolchain,设置编译器链接,拷贝toolchain sysroot, 编译中间目录staging是一个链接指向sysroot。

附上 bootlin buildroot trainning的链接,非常详细。

重新构建rootfs快捷指令

在$(BR2_EXTERNAL)中添加两条指令,rr和rp 用来重新构建rootfs.

rr:
	find $(BASE_DIR)/build/ -name "\.stamp_target_installed" -type f -print | xargs rm -f
	rm -rf $(BASE_DIR)/target
	$(MAKE) -C $(BASE_DIR)
	
rp:	
	find $(BASE_DIR)/build/ -name "\.stamp*" -type f -print | xargs rm -f
	rm -rf $(BASE_DIR)/target
	$(MAKE) -C $(BASE_DIR)

未完待续

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值