6. Buildroot用户手册-Buildroot配置

转载请注明原文链接:https://blog.csdn.net/haimo_free/article/details/107677667

6. Buildroot配置

make *config的所有配置项都有说明文本提供了有关该选项的详细信息。

make *config还提供了一个搜索工具。阅读不同的前端菜单中的帮助信息以了解如何使用它:

  • menuconfig 通过按/调用搜索工具
  • xconfig 通过按Ctrl+F调用搜索工具

搜索结果会显示匹配项的帮助信息。在menuconfig中,左侧栏的数字提供了相应配置项的快捷键,只要按下该数字键即可跳转到该配置项,或者由于缺少依赖项而跳转到包含该配置项的上一级菜单。

虽然菜单结构和帮助文本很容易理解,但仍有许多主题需要额外的说明,这些内容很难在帮助文本中介绍,因此在以下各节中介绍。

6.1 交叉编译工具链

编译工具链是一套为系统编译代码的工具。它由一个编译器(在我们的情况下是gcc)、二进制汇编和链接程序(在我们的情况下是binutils)和一个C标准库(例如GNU libc、uClibc-ng)组成。

一般宿主机安装的系统已经具有编译工具链,可以使用该编译工具链来编译能在宿主系统上运行的应用程序。如果使用的是PC,那么该编译工具链将在x86处理器上运行并为x86处理器生成代码。在大多数Linux系统上,编译工具链使用GNU libc(glibc)作为C标准库。该编译工具链称为“宿主机编译工具链”,其运行依赖的系统称为“宿主系统”。

宿主机编译工具链由Linux发行版提供,与Buildroot无关(除了使用它来构建交叉编译工具链和其他运行在宿主机上的工具之外)。

如前所述,宿主系统的编译工具链可在其上运行,并为宿主系统的处理器生成代码。由于嵌入式系统具有不同的处理器,因此需要交叉编译工具链——运行在宿主系统但为目标系统和目标处理器生成代码的编译工具链。例如,宿主系统使用x86,目标系统使用ARM,那么宿主机上的常规编译工具链在x86上运行并为x86生成代码,而交叉编译工具链在x86上运行但为ARM生成代码。

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

  • 内部工具链,配置界面中称之为 Buildroot toolchain
  • 外部工具链,配置界面中称之为 External toolchain

在Toolchain菜单中使用Toolchain Type选项在两种解决方案之间选择。选择任一种解决方案后,将出现许多配置选项,以下各节将详细介绍这些选项。

6.1.1 内部工具链

内部工具链是Buildroot在为目标嵌入式系统构建用户空间应用程序和库之前自己构建的一个交叉编译工具链。
该交叉编译工具链支持多个C库:uClibc、glibc和musl。

选择内部工具链后,将出现许多选项,重要的有:

  • 修改用于构建工具链的Linux内核版本。这个选项需要一些解释。C库会在构建交叉编译工具链的过程中构建,该库提供了用户空间应用程序和Linux内核之间交互的接口。为了知道如何与Linux内核“对话”,C库需要引用Linux内核头文件(即来自Linux内核的.h文件),这些头文件定义了用户空间和内核之间的接口(系统调用、数据结构等)。由于此接口是向后兼容的,因此用于构建工具链的Linux内核头文件版本不需要完全匹配你打算在嵌入式系统上运行的Linux内核版本,只需要具有与要运行的Linux内核相同或更低的版本即可。如果你使用的Linux内核头文件版本比嵌入式系统上运行的Linux内核版本更新,则C库可能使用Linux内核未提供的接口。
  • 修改gcc、binutils和C库的版本。
  • 选择工具链其他选项(仅uClibc):工具链是否拥有RPC支持(主要用于NFS)、宽字符支持、语言环境支持(用于国际化)、C++支持、线程支持。根据你选择的选项,在Buildroot菜单中可见的用户空间应用程序和库的数量将发生变化:许多应用程序和库需要启用某些工具链选项。当需要某个工具链选项才能选择某个软件包时,大多数软件包都会显示注释说明。如果需要,你可以通过运行make uclibc-menuconfig进一步优化uClibc配置。需要注意的是,Buildroot中的所有软件包都已针对默认的uClibc选项进行了测试。如果你删除了uClibc的某项配置,某些包可能不能编译。

值得注意的是,无论何时修改了这些选项,都必须重新构建整个工具链和系统。请参阅第8.2节“了解何时需要重新构建”。

该工具链的优点:

  • 与Buildroot良好集成
  • 快速,只构建必需的内容

该工具链的缺点:

  • 执行make clean后需要重新构建工具链,耗费时间。如果你想减少构建时间,请考虑使用外部工具链。

6.1.2 外部工具链

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

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

  • 使用预定义的外部工具链配置文件,并让Buildroot下载、提取并安装工具链。Buildroot已经知道一些CodeSourcery和Linaro的工具链,只需在Toolchain里选择即可。这绝对是最简单的解决方案。
  • 使用预定义的外部工具链配置文件,但不是让Buildroot下载并提取工具链,而是告诉Buildroot你的工具链在系统上的安装位置。只需在Toolchain里选择,不要勾选Download toolchain automatically,并将Toolchain Path指向你的工具链的安装位置。
  • 使用完全自定义的外部工具链。这对于使用crosstool-NG生成的工具链特别有用。为此,在Toolchain里选择Custom toolchain,并填写Toolchain path、Toolchain prefix和External toolchain C library选项。之后,你必须告诉Buildroot你的外部工具链支持哪些特性。如果你的工具链使用glibc库,则只需告诉Buildroot你的工具链是否支持C++,以及是否具有内置RPC支持。如果你的外部工具链使用uClibc库,那么你必须告诉Buildroot它是否支持RPC、宽字符、本地化、程序调用、线程和C++。在执行开始时,Buildroot会告诉你所选的选项是否与工具链配置不匹配。

Buildroot的外部工具链支持已经过CodeSourcery和Linaro工具链的测试,以及corsstool-NG生成的工具链和Buildroot生成的工具链的测试。通常,所有支持sysroot功能的工具链都可以工作,如果没有,请立即与开发人员联系。

Buildroot不支持OpenEmbeded或Yocto生成的工具链或SDK,因为这些工具链不是纯工具链(纯工具链只有gcc、binutils和C/C++库),这些工具链包含大量预编译的库和程序。因此Buildroot无法导入工具链的sysroot,因为它含有数百兆预编译的库。
我们也不支持使用发行版中的工具链(例如,宿主系统安装的gcc/binutils/C库)作为目标系统的工具链。这是因为发行版的工具链不是纯工具链(发行版的工具链仅包含C/C++库),因此我们无法将其正确导入到Buildroot构建环境中。因此,即使正在为x86或x86-64目标构建系统,也必须使用Buildroot或crosstool-NG生成的交叉编译工具链。

如果你想为项目生成自定义工具链(可用于Buildroot的外部工具链),Buildroot开发人员的建议是使用Buildroot进行构建,详情请参阅第6.1.3节“使用Buildroot构建外部工具链”。

外部工具链优点:

  • 允许使用众所周知且经过良好测试的交叉编译工具链。
  • 节省构建交叉编译工具链的时间,这在嵌入式Linux系统的总体构建时间中通常非常重要。

缺点:

  • 如果预构建的外部工具链存在BUG,那么除非使用的是Buildroot或crosstool-NG自己构建的外部工具链,否则可能很难从工具链供应商处获得帮助。

6.1.3 使用Buildroot构建外部工具链

Buildroot内部工具链选项可以用于创建外部工具链。以下是构建内部工具链并将其打包以供Buildroot自身(或其他项目)重用的步骤。

  • 为目标CPU体系结构选择适当的目标选项
  • Toolchain菜单,保留Buildroot toolchain里Toolchain type的默认选项,并根据需要配置工具链
  • System configuration菜单里,Init system选择None,/bin/sh选择None
  • Target packages菜单,禁用Busybox
  • Filesystem images菜单,禁用tar the root filesystem

然后,我们开始构建,并要求Buildroot生成SDK。这将方便的生成一个包含工具链的压缩包:

make sdk

这将在$(output)/images路径下生成SDK压缩包,命名类似于arm-buildroot-linux-uclibcgnueabi_sdk-buildroot.tar.gz。这就是可以在Buildroot中重复使用的外部编译-工具链。

在其他Buildroot项目的Toolchain菜单中:

  • Toolchain Type设置为External toolchain
  • Custom toolchain设置为Toolchain
  • Toolchain to be downloaded and installed设置为Toolchain origin
  • Toolchain URL设置为file:///path/to/your/sdk/tarball.tar.gz

使用外部工具链时,Buildroot会生成包装程序,该程序将适当的选项(根据配置)透明地传递给外部编译工具链。如果你需要调试此包装程序以检查传递的参数是否正确,可以将环境变量BR2_DEBUG_WRAPPER设置为以下值:

  • 0,为空或未设置:不调试
  • 1:在一行上跟踪所有参数
  • 2:每行跟踪一个参数

6.2 设备文件管理

在Linux系统上,/dev目录包含设备文件,这些文件允许用户空间的应用程序访问Linux内核管理的硬件设备。没有这些设备文件,即使Linux内核正确识别了硬件设备,用户空间的应用程序也无法使用它们。

在System configuration - /dev manament,Buildroot提供了四种不同的解决方案来处理/dev目录:

  • 第一种解决方案是使用静态设备表。这是旧版Linux系统处理设备文件的经典方法。使用这种方法,设备文件会永久存储在根文件系统中(即系统重新引导后它们仍然存在),并且当从系统中添加或删除设备时不会自动创建或删除这些文件。因此,Buildroot使用设备表创建了一组标准的设备文件,默认存储在Buildroot源码的system/device_table_dev.txt中。当Buildroot生成最终的根文件系统时将处理该文件,因此,设备文件在output/target目录中不可见。BR2_ROOTFS_STATIC_DEVICE_TABLE选项允许更改Buildroot使用的默认设备表,或者添加其他设备表,以便Buildroot在构建过程中创建其他设备文件。因此,如果使用这种方法,并且系统中缺少设备文件,则可以创建一个设备表文件,例如board///device_table_dev.txt,其中包含新增的设备文件的描述,然后设置BR2_ROOTFS_STATIC_DEVICE_TABLE为 system/device_table_dev.txt board///device_table_dev.txt。有关设备表文件格式的更多详细信息,请参阅第23章“Makedev语法文档”。
  • 第二种解决方式是仅使用devtmpfs动态处理。devtmpfs是Linux内核的一个虚拟文件,在2.6.32版本中引入(如果使用较旧的内核,则不能适用此选项)。挂载/dev目录后,当从系统中添加或删除设备时,该虚拟文件系统将自动使设备文件显示或消失。该文件系统在重启后不会持久存储,它由内核动态生成并填充。使用devtmpfs需要启用以下内核配置选项:CONFIG_DEVTMPFS和CONFIG_DEVTMPFS_MOUNT。当使用Buildroot为嵌入式设备构建Linux内核时,请确保启用了这两个选项。如果是在Buildroot之外构建Linux内核,则需要自行启用这两个选项(如果不启用,Buildroot系统将无法启动)。
  • 第三种解决方案是使用动态devtmpfs+mdev。此方法也需依赖devtmpfs虚拟文件系统(因此CONFIG_DEVTMPFS和CONFIG_DEVTMPFS_MOUNT仍然需要在内核上启用),但是在它上面增加了mdev用户空间程序。mdev是Busybox的一部分,内核每次添加或移除设备时都会被调用。由于/dev/mdev.conf配置文件的存在,mdev可以配置为例如对设备文件设置特定的权限或所有权、在设备出现或消失时调用脚本或应用程序等。基本上,它允许用户空间对设备添加和移除事件做出反应,例如mdev可用于在设备出现在系统上时自动加载内核模块。如果你的设备需要固件,它将负责将固件内容推送给内核。mdev是udev的轻量级实现(功能较少),有关mdev及其配置文件语法的更多详细信息,请参阅http://git.busybox.net/busybox/tree/docs/mdev.txt
  • 第四种解决方案是使用动态devtmpfs+eudev。此方法也需依赖devtmpfs虚拟文件系统,但在其上面添加了eudev用户空间守护程序。eudev是一个后台运行的守护程序,当系统添加或移除设备时,内核会调用该守护程序。与mdev相比,它是更重量级的解决方案,但具有更高的灵活性。eudev是udev的一个独立版本,是大多数桌面Linux发行版中使用的原始用户空间守护程序,该守护程序现在是Systemd的一部分。有关更多详细信息,请参阅http://en.wikipedia.org/wiki/Udev

Buildroot开发人员的建议是一开始仅使用动态devtmpfs的解决方案,直到需要在添加或移除设备时或需要固件时通知用户空间,在这种情况下,通常使用动态devtmpfs+mdev是一个比较好的解决方案。

请注意,如果init系统选择systemd,那么/dev管理将由systemd的udev程序提供。

6.3 初始化系统

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

Buildroot允许使用三种不同的初始化系统,可以在System configuation - Init System选择:

  • 第一种解决方案是使用BusyBox。在许多程序中,BusyBox都有一个基本的init程序,对于大多数嵌入式系统而言这已经足够了。启用BR2_INIT_BUSYBOX选项将确保BusyBox会生成并安装器init程序,这是Buildroot的默认解决方案。BusyBox的init程序将在引导启动时读取/etc/inittab文件以了解需要做什么。可以在http://git.busybox.net/busybox/tree/examples/inittab找到该文件的语法(请注意,BusyBox的inittab语法很特殊,请勿使用网上随意找到的inittab文档来了解BusyBox的inittab语法)。Buildroot的默认inittab保存在system/skeleton/etc/inittab。除了挂载一些重要的文件系统外,默认inittab的主要工作是启动/etc/init.d/rcS脚本,并启动getty程序(提供登录提示)。
  • 第二种解决方案是systemV。该方案使用旧的传统的sysvinit程序,该程序被Buildroot打包放在package/sysvinit目录。这是大多数桌面Linux发行版中使用的解决方案,直到他们切换到更新的替代版本为止(如Upstart或者Systemd)。sysvinit也需要inittab文件(语法与BusyBox中的语法略有不同)。使用此解决方案的默认inittab保存在package/sysvinit/inittab。
  • 第三种方案是使用systemd。systemd是用于Linux的新一代init系统。它的功能远不止传统init程序提供的功能:强大的并行化功能,使用Socket套接字和D-Bus激活来启动服务,按需启动守护程序,使用Linux控制组跟踪进程,支持快照和恢复系统状态等。systemd在相对复杂的嵌入式系统上很有用,例如需要D-Bus和服务相互通信的系统。需要注意的是,systemd引入了大量的大型依赖项:dbus、udev等等。有关systemd的更多详细信息,请参阅http://www.freedesktop.org/wiki/Software/systemd

Buildroot开发人员推荐的解决方案是使用BusyBox初始化程序,对于大多数嵌入式系统已经足够了。systemd可以用于更复杂的场景。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页