Embedded Linux System Generate Tool: Buildroot

Buildroot

Buildroot是什么?

官方手册:Buildroot is a tool that simplifies and automates the process of building a complete Linux system for an embedded system, using cross-compilation

Buildroot 是一个工具,它使用交叉编译来简化和自动化嵌入式Linux系统构建过程。为了达到上述目的,Buildroot 能够生成交叉编译工具链(a cross-compilation toolchain)、根文档系统(a root filesysystem)、Linux 内核映像(a Linux kernel image)和引导加载进程(a bootloader)。

Buildroot每3个月发布一次,2月、5月、8月、11月,发布号的格式为 YYYY.MM,例如 2013.02、2014.08。

Buildroot的Github链接

Buildroot如何使用?

通过 make menuconfig 进入菜单,配置选项。全部配置完成后,配置工具将会生成一个.config文件,这个文件将被顶层Makefile读取。然后就可以进行构建:make,该命令一般会执行如下步骤:

  • 下载源文件
  • 配置、构建、安装交叉编译链,或者简单地导入外部交叉编译链
  • 配置、构建、安装已勾选的目标包
  • 构建内核镜像(kernel image),如果已勾选
  • 构建引导加载程序镜像(bootloader image),如果已勾选
  • 创建选定格式的根文件系统(root filesystem)

Buildroot输出保存在output/. 目录下,这个目录包含如下几个子目录:

  • images:存放所有的images(kernel image、bootloader、root filesystem image),这些都是需要放到目标系统上的文件。
  • build:存放所有需要编译的应用,每个应用都以一个文件夹表示。
  • host:包含为主机构建的工具(主要是主机上Buildroot需要的工具和交叉编译工具)和目标工具链的sysroot(主要是用户交叉编译的头文件和库文件)。
  • staging:host目录内目标工具链sysroot的符号链接,其存在是为了向后兼容
  • target:包含了目标几乎完整的根文件系统。最后导入目标主机的根文件系统就是这个

make menuconfig 中,可以输入/ 进行目标搜索。当搜索到所有目标,可以通过按下目标的数字编号进行跳转。

buildroot/package 目录下,可以为自己的应用创建文件夹,文件夹下至少有两个文件:xxx.mkConfig.in

  • xxx.mk:这是一个Makefile文件,包含了对应用package的下载、配置、编译和安装
  • Config.in:这是一个配置工具描述文件的一部分,它描述了应用package的选项。

Buildroot手册链接

交叉编译工具链

交叉编译是什么?

因为你的目标主机(arm架构)的cpu、ram、rom都是极其有限的,无法在目标主机编译应用程序。所以我们一般在源主机(x86架构)上为目标主机(arm架构)编译应用程序,如果我们选择系统默认的编译链工具,编译出来的可执行文件只能在x86架构主机运行。若想在目标主机(arm架构)上运行应用程序,需要在源主机(x86架构)上安装交叉编译工具链。

编译工具链是什么?

编译工具链是一组可用于编译系统代码的工具。它由编译器、汇编器和链接器等二进制实用程序以及 C 标准库组成。

交叉编译工具链是什么?

一个在主机系统上运行但为 目标系统(和目标处理器)生成代码的编译工具链。例如,如果您的主机系统使用 x86 而目标系统使用 ARM,则主机上的常规编译工具链在 x86 上运行并为 x86 生成代码,而交叉编译工具链在 x86 上运行并为 ARM 生成代码。

Buildroot不提供编译工具链,需要用户自己安装。

Buildroot为交叉编译工具链提供了两种解决方案:

  • 内部工具链后端,Buildroot toolchain在配置界面调用。
  • 外部工具链后端,External toolchain在配置界面调用。

内部工具链后端

内部工具链后端是Buildroot 在为目标嵌入式系统构建用户空间应用程序和库之前自行构建交叉编译工具链的后端。

外部工具链后端

外部工具链后端允许使用现有的预构建交叉编译工具链。Buildroot 了解许多著名的交叉编译工具链(来自 Linaro for ARM、 Sourcery CodeBench for ARM、x86-64、PowerPC 和 MIPS),并且能够自动下载它们,或者可以指向自定义工具链,可下载或本地安装。

有三种使用外部工具链的解决方案:

  • 使用预定义的外部工具链配置文件,让 Buildroot 下载、提取和安装工具链。
  • 使用预定义的外部工具链配置文件,但不是让 Buildroot 下载并提取工具链,而是可以告诉 Buildroot 您的工具链已安装在系统上的位置。
  • 使用完全自定义的外部工具链。

初始化系统

init程序是内核启动的第一个用户空间程序(它的 PID 编号为 1),负责启动用户空间服务和程序(例如:Web 服务器、图形应用程序、其他网络服务器等)。

Buildroot 允许使用三种不同类型的 init 系统:

  • 第一个解决方案是BusyBox:在众多程序中,BusyBox 有一个基本init程序的实现,对于大多数嵌入式系统来说已经足够了。
  • 第二种解决方案是systemV:此解决方案使用旧的传统sysvinit程序,该程序在 Buildroot 中打包 package/sysvinit。这是大多数桌面 Linux 发行版中使用的解决方案,直到他们转向 Upstart 或 Systemd 等较新的替代方案。
  • 第三个解决方案是systemdsystemd它是新一代的 Linux 初始化系统。

Buildroot 开发人员推荐的解决方案是使用 BusyBox init,因为它对于大多数嵌入式系统来说已经足够了。systemd可用于更复杂的情况。

Kconfig

Kconfig是什么?

配置数据库是以树状结构组织的配置选项的集合。

注意:linux 在2.6版本以后将配置文件由原来的 Config.in 改为 Kconfig

Kconfig的功能?

Kconfig用来配置内核,它就是各种配置界面的源文件,内核的配置工具读取各个Kconfig文件,生成配置界面供开发人员配置内核,最后生成配置文件.config。通过配置界面进行勾选的项目将会以固定格式写入.config 文件。

执行命令:make menuconfig ,自动读取当前目录下的 Config.in,形成配置界面

Kconfig 语法

example:Config.in

1
2
3
4
5
6
7
8
9
10
11
menu "Network device support"
config BR2_PACKAGE_NETDEVICES
bool "Enable Net Devices"
depends on NET
select BR2_PACKAGE_LIBDEVICES
default y
help
This is help desciption。
...

endmenu

Network device support:主菜单

menu … endmenu:标签中间的成为子菜单,子菜单由关键字config定义。

其中config下面其他关键字是属性:bool、depends on、default、help,用于定义该菜单项的类型、依赖项、默认值、帮助信息等。

类型定义:

  • bool:布尔类型。显示 []
  • tristate:三态(内建Y、模块M、移除N)。显示 <>
  • string:字符串
  • hex:16进制。显示 ()
  • integer:整型

目录嵌套:子目录下的Kconfig必须添加到父目录中的Kconfig中。在父目录中的Kconfig类似语句:source "package/app/Kconfig"

用来包含(或嵌套)新的Kconfig文件,这样便可以使各个目录管理各自的配置内容,使不必把那些配置都写在同一个文件里,方便修改和管理

1
2
3
4
5
6
7
# 条目
config:生成可选项
menu/endmenu:生成菜单
choice/endchoice:将多个类似的配置选项组合在一起,供用户单选或多选。
comment:在界面的第一行显示帮助信息
if/endif:
source:用于读取另外一个Kconfig文件,一般读取子目录的Kconfig文件

makefile

.mk是一种android编译环境下的一种特殊的“makefile”文件

  • PKG_NAME:定义软件包的名称。通常与软件包源代码的目录名相同。
  • PKG_VERSION:定义软件包的版本号。
  • PKG_SOURCE:定义软件包源代码的下载链接或路径。可以是远程 URL 或本地路径。
  • PKG_SITE:定义软件包目录,它可以是一个url或者本地文件路径
  • PKG_HASH:定义软件包源代码的哈希值,用于验证下载文件的完整性。通常使用 MD5 或 SHA256 算法计算。
  • PKG_SITE_METHOD:定义拉取或者复制包源文件的方式
  • PKG_LICENSE:定义软件包的许可证类型。可以是单个许可证或多个许可证的组合。
  • PKG_BUILD_DIR:定义软件包构建过程中的临时目录。通常是 ${BUILD_DIR}/${PKG_NAME}-${PKG_VERSION}
  • PKG_INSTALL_DIR:定义软件包安装到目标系统的目录。通常是 ${TARGET_DIR}
  • PKG_CONFIG_DEPENDS:定义软件包构建过程中依赖的其他软件包。这些依赖将被自动解析和构建。
  • PKG_BUILD_CMDS结尾的变量会在 buildroot 框架编译的时候执行,用于给源码的 Makefile 传递编译选项和链接选项,调用源码的Makefile。
  • PKG_INSTALL_TARGET_CMDS结尾的变量是在编译完之后,自动安装执行,一般是让 buildroot 把编译出来的的 bin 或 lib 拷贝到指定目录。
  • $(eval $(autotools-package)):使用 Autotools 构建系统的软件包规则。适用于使用 configure 脚本的软件包。
  • $(eval $(cmake-package)):使用 CMake 构建系统的软件包规则。适用于使用 CMakeLists.txt 的软件包。
  • $(eval $(generic-package)):通用的软件包规则,适用于没有特定构建系统的软件包。需要手动定义构建和安装过程。
  • $(eval $(host-generic-package)):适用于主机(开发机)上构建的通用软件包规则。与目标系统无关。
  • $(eval $(python-package)):适用于 Python 软件包的规则。用于构建和安装 Python 模块。

注意:PKG是你的应用名称

内置变量

  • TOPDIR:buildroot 目录
  • TARGET_MAKE_ENV
  • TARGET_CC
  • TARGET_CXX

参考引用

[1、Kconfig Language](Kconfig Language — The Linux Kernel documentation)

2、Kconfig详解-文件的基本要素 - 江召伟 - 博客园 (cnblogs.com)