使用 Buildroot 构建您自己的嵌入式 Linux 系统

作者:Alexander Sirotkin

这一切都始于我为我的 FemtoLinux 项目订购了一块基于 ARM 的开发板,这是一个专门为超小型系统设计的 Linux 版本。最初,我曾考虑简单地使用 OpenWrt 开源项目支持的 Linksys WRT 路由器进行开发。但最终,我决定,因为这是一个商业项目,开发时间很重要,我打算额外花费 100-200 美元购买一块真正的、具有官方 Linux 支持的开发板,它应该配备嵌入式 Linux 开发人员所需的一切:交叉编译工具链、Linux 源代码和嵌入式 Linux 发行版(至少,我当时是这么认为的)。如果您的预算有限,并且正在为您的业余项目寻找廉价的嵌入式板,那么使用 Linksys WRT 路由器并不是一个坏主意。

选择合适的嵌入式 Linux 开发板本身就值得写一篇文章,但现在,我只想说,当您决定使用 WRT 时,您应该准备好自己构建软件开发环境,并期望从社区获得支持。对于商业板,我本以为会从供应商那里得到支持,但我没有。供应商所谓的 Linux 支持实际上只是一系列内核补丁,迫使我自己评估、选择和配置这个板的嵌入式 Linux 开发环境,结果这变成了一次非常有趣和有教育意义的经历。

嵌入式 Linux 发行版

首先,让我们从一些基本术语开始。嵌入式 Linux 发行版与您常用的 PC 发行版(如 Ubuntu 或 Fedora Core)有很大不同。它通常至少包括以下组件:

  • 适用于您的目标架构的交叉编译工具链,至少包括 gcc、g++ 和 ld。它通常在一个架构上运行,但生成用于不同架构的二进制文件——在我的例子中分别是 x86 和 ARM,因此称为交叉编译工具链。

  • 带有适用于您的板的 BSP(板级支持包)的内核源代码。

  • 文件系统骨架——即 /bin、/etc 以及所有标准配置文件,例如 /etc/fstab、/etc/inittabe 等。

  • 应用程序——init 和 shell 是最低要求,但大多数人需要更多才能做一些有用的事情。

目前,两个最广泛使用的嵌入式 Linux 发行版是 OpenEmbedded 和 Buildroot。本文是关于 Buildroot 的,因为这是我最熟悉的,自然也是我在我的项目中使用的。Buildroot 最大的优势是其简单性和灵活性,如果您要进行一些内核黑客技术或其他底层开发,这两点非常重要。另一方面,如果您是一名嵌入式应用程序开发人员,那么 OpenEmbedded 当然也是一个可行的选择。

Buildroot

即使您以前可能没有听说过 Buildroot,但它实际上并不是一个新项目。它已经存在很多年了,大部分时间都以 uClinux 的名称存在。最初,uClinux 是一项将 Linux 内核移植到没有 MMU 的处理器(如 Motorola MC68328)的工作。然而,它最终扩展到超出这个范围,增加了对更多处理器的支持、用于无 MMU 系统的二进制格式以及更多的用户空间功能,包括专门为低内存系统设计的 libc 版本——uClibc。最终,它演变成更先进和易于使用的嵌入式 Linux 发行版之一。

这就是混乱开始的地方,因为人们使用 uClinux 这个名称既指代无 MMU CPU 内核支持,也指代嵌入式发行版,这两者是非常不同的。许多无 MMU 补丁(例如,整个 armnommu 架构支持)最终被包含在标准内核树中,也加剧了这种混乱。最后,嵌入式 Linux 发行版部分被拆分成一个名为 Buildroot 的不同项目。uClibc 的开发继续独立进行,而父项目 uClinux 项目则在某种程度上失去了动力。

来自 Buildroot 网站:“Buildroot 是一组 Makefile 文件和补丁,可以轻松地为您的目标 Linux 系统生成交叉编译工具链和根文件系统,并使用 uClibc C 库。” 这并不完全正确,因为它也支持(在一定程度上,您稍后会看到)其他 libc 版本,如 glibc。它适用于许多嵌入式 CPU,包括 ARM、MIPS 和 PowerPC。

如果您想开始使用 Buildroot,请下载 tarball,解压缩并运行make help从其根目录。如果这一切对您来说看起来很熟悉,请等到您运行make menuconfig.

Roll Your Own Embedded Linux System with Buildroot

图 1. Buildroot 主菜单

正如您可能已经猜到的,Buildroot 使用与 Linux 内核相同的 Makefile 基础设施来配置和构建所有内容,包括应用程序和库。常用的命令顺序是

make clean
make menuconfig
make

如果您要更改某些配置参数,第一个命令非常重要——在这种情况下,增量构建可能有效也可能无效。最初,我打算建议您从一些默认配置开始工作,例如运行make integrator926_defconfig,这应该为 Integrator ARM 参考板配置 Buildroot。然而,事实证明,随着 Buildroot 开发的推进,大多数默认配置在某种程度上落后了,目前都无法开箱即用。我建议您运行make menuconfig,并手动选择以下选项

  • 目标架构:arm。

  • 目标架构变体:arm926t。

  • 内核:与 Linux 头文件相同的版本。

然后,浏览其他参数并检查您可能想要或需要修改的其他参数。这样做时要小心,并始终保存您最新的工作配置(.config 文件)。很容易最终得到一个无法正常工作的配置。

Buildroot 配置选项大致可以分为硬件相关、构建过程相关和软件相关,而软件相关选项又可以进一步分为内核、工具链和软件包。

硬件选项是定义您的 CPU 核心的“目标架构”(ARM、MIPS 等)。“目标架构变体”定义您正在使用的确切 CPU,“目标选项”定义板级相关参数,例如 UART 波特率等。您应该了解您的硬件参数,这里没什么可补充的,除了对于 ARM 架构,我建议使用 EABI 并确保您在所有地方都使用相同的 ABI 约定。

如果您是第一次运行 Buildroot,您可能应该避免更改“构建选项”。这些选项可能默认情况下就可以了;您可能想要更改的唯一事情是“同时运行的作业数”,如果您的构建 PC 是多核系统。此外,如果您想调试一些预装的应用程序,请选择“使用调试符号构建软件包”。

请记住,为了构建内核和软件包,Buildroot 首先需要为您的硬件构建交叉编译工具链。“工具链”菜单允许您选择 gcc 版本和其他工具链相关参数。错误的工具链配置可能会导致一些非常奇怪的错误,因此请小心。默认情况下,Buildroot 构建自己的工具链并与 uClibc 一起工作。有一个选项可以使用外部工具链,它可以是基于 glibc 的,但这超出了本文的范围,因此您应该将“工具链类型”设置为“Buildroot 工具链”。您可以从此菜单更改 gcc、binutils、uClibc 和内核头文件(但不是内核本身)的版本。您还可以决定编译 C++ (g++) 编译器和 gdb 支持(用于目标的 gdbserver 和用于主机的 gdb 客户端或用于目标的独立 gdb),这可能是您需要的。所有其他选项最好在这个阶段保持不变。

“目标软件包选择”是您可以选择哪些软件组件作为嵌入式文件系统镜像一部分的地方。在这里您可以相对自由地进行实验——即使您选择了一个在您的硬件上或在您选择的特定 Linux 和 gcc 版本上不受支持的应用程序,也很容易找到有问题的应用程序并禁用它。

首先是 BusyBox。它本身就值得写一篇文章,但基本上,它是标准 Linux 实用程序(如 shell 和 init)的集合,针对低内存占用系统进行了优化。您可以从创建一个仅包含 BusyBox 的文件系统开始。它包含启动和验证系统是否正常工作所需的一切。稍后,您可以添加更多软件包,范围从 MySQL 或 SQLite 数据库到 VLC 和 MPlayer 媒体播放器,以及 Perl、Python 和许多其他软件包。

“目标文件系统选项”允许您选择文件系统镜像的类型。几乎所有常用的(在嵌入式世界中)文件系统都受到支持,包括:cramfs、squashfs、jffs2、romfs 和 ext2。

如果您只是想进行实验,或者更喜欢手动创建文件系统镜像(如果您正在使用一些罕见的、不受支持的文件系统,例如 yaffs2),您可以选择“tar 根文件系统”选项,这将创建一个包含您的文件系统的 tar 归档文件。由于某些未知原因,引导加载程序配置也在此菜单下找到(目前仅支持 Das U-Boot),但我将跳过这个,假设您已经有一个正常工作的引导加载程序。

最后一个菜单是“内核”,这是可选的。如果您只对应用程序开发感兴趣,选择正确的内核头文件(见上文)就足够了。如果您决定修改内核,请记住保持内核版本和内核头文件版本(在“工具链”菜单中)同步。

完成后,退出 menuconfig,然后运行make。Buildroot 会自动下载它需要的一切,对其进行编译,并最终在 output/images/ 目录中创建文件系统镜像。如果您想修改文件系统镜像中的某些内容,例如,更改系统的 IP 地址,您可以修改文件系统骨架目录树,它通常位于 target/generic/target_busybox_skeleton。请注意,如果您不使用 BusyBox,或者如果您的硬件平台有自己的文件系统树骨架,则此位置可能不同。

uClibc、BusyBox 和内核配置

当您对 Buildroot 获得足够的经验并决定您足够勇敢去修改一些 uClibc、BusyBox 和/或内核参数时,方法是使用所有三者的默认设置编译 Buildroot,然后,运行以下命令来修改参数并最终重新编译所有内容

make uclibc-menuconfig
make busybox-menuconfig
make linux26-menuconfig

请注意,只有在主 Buildroot 配置菜单中启用 Linux 内核选项后,最后一个命令才会起作用。您很可能已经知道如何配置内核,并且 uClibc 配置很少需要调整,除非您想编译出某些功能以节省内存,因此我将只关注 BusyBox 配置。

Roll Your Own Embedded Linux System with Buildroot

图 2. BusyBox 配置菜单

BusyBox 菜单可以分为设置和小程序。我专注于后者,因为这可能是您首先想要修改的内容。小程序是 BusyBox 术语中的应用程序,但有一个小小的区别。为了节省空间,BusyBox 通常安装为单个二进制文件,其中包含您决定编译的所有实用工具:shell、ping、gzip 等。您可以通过将应用程序名称作为 BusyBox 的参数来启动单个小程序——busybox ping,例如——或者您可以创建一个符号链接,ln -s /bin/ping /bin/busybox,BusyBox 将根据执行它的链接自动选择正确的小程序。BusyBox 安装会自动为所有已编译的小程序创建链接。如果您好奇,您可以不带任何参数运行它,以查看编译了哪些小程序。您应该可以轻松地为您的项目选择合适的小程序集。唯一值得一提的是 shell。BusyBox 不支持标准 shell,例如 bash 或 tcsh;相反,您可以选择 ash、hush 和 msh,其中 ash 最接近 bash,也是我一直使用的。请注意,即使标准 bash 不是 BusyBox 的一部分,如果需要,Buildroot 也支持它。

当您完成嵌入式系统的配置后,运行make来编译所有内容。现在您已准备好将新编译的内核和文件系统镜像编程到您的板上并启动。实际的闪存编程取决于您的系统、引导加载程序、闪存类型等等,这超出了本文的范围。

如果您想编译自己的应用程序,您可以(并且应该)使用 Buildroot 创建的工具链。您可以获取(或构建)不同的工具链,但如果它不是基于 uClibc 的,或者它是使用不同的内核头文件编译的,则可能无法工作。为了使用 Buildroot 工具链,您只需将 output/staging/usr/bin/ 目录添加到您的路径,然后简单地运行arm-linux-uclibcgnueabi-gcc.

要记住的重要一点是,Buildroot 并非万无一失,因为相对容易创建一个无法工作甚至无法编译的配置。您不应期望每个参数组合都能工作,并始终保留您上次正常工作的配置文件。优点是这个项目背后有一个庞大而活跃的社区,他们很乐意提供帮助。

BSP

BSP 代表板级支持包。这个术语在某种程度上与 RTOS(如 VxWorks)相关联。因此,有些人更喜欢更“政治正确”的 LSP(Linux 支持包)。无论如何,BSP 通常是一组针对您的硬件的微小内核和引导加载程序修改。Intel x86 开发人员理所当然地认为所有 x86 系统都具有相同的基本硬件和外围接口,但这在嵌入式系统中并非如此。BSP 开发通常包括修复内存映射、配置中断控制器以及开发至少以下基本驱动程序:串口(用于控制台)、网络和闪存。

ARM ABI

应用程序二进制接口 (ABI) 描述了应用程序与操作系统和硬件之间的底层接口。ARM Linux 支持旧 ABI (OABI) 和嵌入式 ABI (EABI)。OABI 已弃用,建议您使用 EABI。由于此参数影响内核、编译器和标准库,因此在所有地方使用相同的 ABI 非常重要,即使可能支持混合 ABI。与 OABI 相比,EABI 定义了更高效的系统调用约定,提高了浮点性能,更改了结构体打包,取消了最小四字节大小限制以及其他一些细微的改进。

资源

FemtoLinux: femtolinux.com

uClinux: www.uclinux.org

uClibc: www.uclibc.org

Buildroot: buildroot.uclibc.org

OpenEmbedded: www.openembedded.org

Alexander (Sasha) Sirotkin 是一位活跃的 Linux 用户和开发人员,至今已超过 15 年。他参与的项目之一是 FemtoLinux,该项目旨在提高低端嵌入式系统的性能,并简化从传统 RTOS 的移植。他住在以色列特拉维夫,可以通过 “sasha AT femtolinux.com” 联系到他。

加载 Disqus 评论