Linux之buildroot(4)配置项目

Author:Onceday Date:2023年12月3日

漫漫长路,才刚刚开始…

全系列文章请查看专栏: buildroot编译框架_Once_day的博客-CSDN博客

参考文档:

1.自定义项目

对于给定的项目,可能需要执行的典型操作有:

  • 配置Buildroot,如构建选项(build options)和工具链(toolchain)、引导加载程序(bootloader)、内核(kernel)、包(package)和文件系统映像类型(filesystem image type)。

  • 配置其他组件,如Linux内核和BusyBox。

  • 定制生成的目标文件系统(target filesystem)。

    (1) 在目标文件系统(target filesystem)上添加或覆盖文件(使用BR2_ROOTFS_OVERLAY)。

    (2) 修改或删除目标文件系统(target filesystem)上的文件(使用BR2_ROOTFS_POST_BUILD_SCRIPT)。

    (3) 在生成文件系统映像之前运行任意命令(使用BR2_ROOTFS_POST_BUILD_SCRIPT)。

    (4) 设置文件权限和所有权(使用BR2_ROOTFS_DEVICE_TABLE)。

    (5) 添加自定义设备节点(使用BR2_ROOTFS_STATIC_DEVICE_TABLE)。

  • 添加自定义用户帐户(使用BR2_ROOTFS_USERS_TABLES)。

  • 生成文件系统映像后运行任意命令(使用BR2_ROOTFS_POST_IMAGE_SCRIPT)。

  • 向某些包添加特定于项目的补丁(使用BR2_GLOBAL_PATCH_DIR)。

  • 添加特定项目的包,一般是自编写的程序应用。

关于此类特定项目的自定义,如果是对其他开发者也非常有益的配置,Buildroot社区强烈建议并鼓励向官方Buildroot项目提供改进、软件包和主板支持。

本章描述了如何在builroot中进行这些特定项目的自定义,以及如何以一种可重复的方式存储它们,即使在运行make clean之后也可以构建相同的映像。通过遵循推荐的策略,甚至可以使用相同的Buildroot树来构建多个不同的项目!

1.1 推荐目录结构

在为项目自定义builroot时,将创建一个或多个需要存储在某处的特定项目文件。虽然它们的路径可以在Buildroot配置中指定,但Buildroot开发人员建议使用本节中描述的特定目录结构。与此目录结构不同,你可以选择将此目录放置在任意位置,如在Buildroot树中或者使用br2-external树。

简单来说,就是目录结构最好是固定的树结构,但目录存放的位置可以任意自定义,一般都是采用br2-external外部,这样可以保持buildroot内部树结构的干净。外部树(br2-external)结构一般如下:

+-- board/
| 	+-- <company>/
| 		+-- <boardname>/
|			+-- linux.config
| 			+-- busybox.config
| 			+-- <other configuration files>
| 			+-- post_build.sh
| 			+-- post_image.sh
| 			+-- rootfs_overlay/
| 			| 	+-- etc/
| 			| 	+-- <some files>
| 			+-- patches/
| 				+-- foo/
| 				| 	+-- <some patches>
| 				+-- libbar/
| 					+-- <some other patches>
|
+-- configs/
| 	+-- <boardname>_defconfig
|
+-- package/
| 	+-- <company>/
| 		+-- Config.in (if not using a br2-external tree)
| 		+-- <company>.mk (if not using a br2-external tree)
| 		+-- package1/
| 		| 	+-- Config.in
| 		| 	+-- package1.mk
| 		+-- package2/
| 		+-- Config.in
| 		+-- package2.mk
|
+-- Config.in (if using a br2-external tree)
+-- external.mk (if using a br2-external tree)
+-- external.desc (if using a br2-external tree)

如果选择将此结构置于Buildroot树之外,即在br2-external树中,则<company><boardname>组件可能是多余的,可以省略。

一个用户有几个相关的项目部分需要相同的定制,这是很常见的。建议使用分层自定义方法,而不是为每个项目重复这些自定义。几乎所有在builroot中可用的自定义方法,如构建后脚本(post-build scripts)和根文件系统覆盖(root filesystem overlays),都接受空格分隔的项列表。

指定的项总是按从左到右的顺序处理。通过创建多个这样的项,一个用于公共定制,另一个用于真正特定项目的定制,可以避免不必要的重复。每一层通常由board/<company>/中的一个单独的目录体现,甚至可以引入两个以上的层。

一个用户有两个自定义层commonfooboard的目录结构示例如下:

+-- board/
	+-- <company>/
		+-- common/
		| 	+-- post_build.sh
		| 	+-- rootfs_overlay/
		| 	| 	+-- ...
		| 	+-- patches/
		| 		+-- ...
		|
		+-- fooboard/
			+-- linux.config
			+-- busybox.config
			+-- <other configuration files>
			+-- post_build.sh
			+-- rootfs_overlay/
			| 	+-- ...
			+-- patches/
				+-- ...

例如,如果用户将BR2_GLOBAL_PATCH_DIR配置选项设置为:

BR2_GLOBAL_PATCH_DIR="board/<company>/common/patches board/<company>/fooboard/patches"

首先应用来自组件层的补丁(board/<company>/common/patches)。

然后是来自fooboard层的补丁(board/<company>/fooboard/patches)。

关于具体的br2-external树例子,可以参考官方manual手册,9.2.1.7 Example layout,内容挺多,就不复制过来了

1.2 buildroot外部树(br2-external)

可以将特定项目的自定义文件放置在两个位置:

  • 直接在Buildroot树中,通常使用版本控制系统中的分支来维护它们,以便很容易升级到较新的Buildroot版本。
  • 在Buildroot树之外,使用br2-external机制。这种机制允许将包配置(package recipes)、板支持(boadr support)和配置文件保存在Buildroot树之外,同时仍然将它们很好地集成在构建逻辑中,这个位置称为为buildroot外部树(br2-external tree)。

通过将BR2_EXTERNAL (make变量)设置为要使用的br2-external树的路径,可以告诉builroot使用一个或多个br2-external树。它可以传递给任何Buildroot make调用,并且会自动保存在输出目录(output/)的隐藏文件.br2-external.mk中,因此不需要在每次make调用时都传递BR2_EXTERNAL的值。不过,它可以在任何时候通过传递一个新值来更改,也可以通过传递一个空值来删除。

br2-external树的路径可以是绝对路径,也可以是相对路径。如果它作为相对路径传递,请务必注意,它是相对于主Buildroot源目录而不是Buildroot输出目录进行解释的。

例如,可以通过以下命令指定br2-external树的路径:

$ make BR2_EXTERNAL=/path/foo menuconfig
$ make legal-info						 # 这个时候, 会使用/path/foo中的br-external树
$ make BR2_EXTERNAL=/path/newfoo xconfig # 这个时候, 会使用/path/newfoo中的br-external树

如下可以同时指定多个br2-external树的路径:

$ make BR2_EXTERNAL=/path/foo:/path/newfoo menuconfig

如下可以关闭所有br2-external树的路径:

 $ make BR2_EXTERNAL= xconfig

一个br2-external树必须至少包含这三个文件:

external.desc external.mk Config.in

除了这些强制文件之外,br2-external树中可能还有其他可选的内容,比如configs/providers/目录。

1.2.1 external.desc文件

该文件描述了br2-external树: 该br2-external树的名称(name)和描述(description)。

该文件的格式是基于行的,每行以一个关键字(keyword)开头,后跟一个冒号和一个或多个空格,然后是分配给该关键字的值。目前可识别的关键字有两个:

  • Name(必选),定义br2-external树的名称。该名称只能使用集合[A-Za-z0-9_]中的ASCII字符,禁止使用其他字符。builroot将变量BR2_EXTERNAL_$(NAME)_PATH设置为br2-external树的绝对路径,这样就可以使用它来引用br2-external树。这个变量在Kconfig中可用,因此可以使用它来获取Kconfig文件,也可以在Makefile中使用它来包含其他Makefile文件,或者从br2-external树中引用其他文件(如数据文件)。

    由于可以同时使用多个br2-external树,因此builroot使用此名称为每个树生成变量。该名称用于标识对应的br2-external树,因此请尝试想出一个真正描述该br2-external树的名称,以便它相对唯一,这样它就不会与另一个br2-external树的名称冲突,特别是如果计划以某种方式与第三方共享br2-external树或使用来自第三方的br2-external树。

  • Desc(可选),它提供了br2-external树的简短描述。它应该适合单行,大部分是自由格式的,并且在显示关于br2-external树的信息时使用(例如,在defconfig文件列表上方,或者在menuconfig中提示); 因此,它应该相对简短(40个字符可能是一个不错的上限)。该描述在BR2_EXTERNAL_$(NAME)_DESC变量中可用。

下面是一个示例说明:

br2-external名字		BR2_EXTERNAL_$(NAME)_PATH值
	FOO					BR2_EXTERNAL_FOO_PATH
	BAR_42				BR2_EXTERNAL_BAR_42_PATH

BR2_EXTERNAL_$(NAME)_PATHBR2_EXTERNAL_$(NAME)_DESC在Kconfig文件和Makefiles中都是可用的。它们也在环境中导出,因此可以在构建后(post-build)、镜像后(post-image)和fakeroot脚本(in-fakeroot)中使用。

1.2.2 Config.in和external.mk

这些文件(可能每个都是空的)可以用来定义包配置(例如foo/Config.infoo/foo.mk),或其他自定义配置选项或make逻辑。

builroot自动包含Config.in。从每个br2-external树中取出external.mk,使其出现在顶层配置菜单中,并将每个br2-external树中的external.mk与其余的makefile逻辑一起包含在内。

主要用途是存储包配置。推荐的方法是编写一个Config.in在文件中,如下填写(external树里自定义包的配置):

source "$BR2_EXTERNAL_BAR_42_PATH/package/package1/Config.in"
source "$BR2_EXTERNAL_BAR_42_PATH/package/package2/Config.in"

external.mk的内容如下所示(通配符自动读取,也可以直接写明绝对路径来获取):

include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/package/*/*.mk))

然后在$(BR2_EXTERNAL_BAR_42_PATH)/package/package1$(BR2_EXTERNAL_BAR_42_PATH)/package创建正常的Buildroot包配置。如果愿意,还可以将包分组到名为<boardname>的子目录中,并相应地调整上述路径,也可以在Config.in中定义自定义配置选项,在external.mk中自定义make逻辑。

1.2.3 configs目录

可以在br2-external树的configs子目录中存储builroot的defconfigs(生成的默认配置文件)。

builroot将自动在make list-defconfigs的输出中显示它们,并允许使用正常的make <name>_defconfig命令加载它们。它们将在make list-defconfigs输出中可见,位于External configs标签下方,该标签包含定义它们的br2-external树的名称。

如果defconfig文件存在于多个br2-external树中,则使用最后一个br2-external树中的defconfig文件。因此,可以覆盖绑定在builroot或其他br2-external树中的defconfig。

1.2.4 provides目录

对于某些包,builroot提供了两种(或更多)与api兼容的实现之间的选择。例如,可以选择libjpegjpeg-turbo,或者openssllibressl之间选择一个。

br2-external可以通过提供一组定义这些选择的文件来扩展这些选择:

  • provides/toolchains.in,定义预配置的工具链,然后在工具链选择中列出。
  • provides/jpeg.in,定义了libjpeg的替代实现。
  • provides/openssl.in,定义了可选的openssl实现。
  • provides/skeleton.in,定义了可选的骨架实现。
  • provides/init.in,在定义可选的初始化系统实现时,可以使用它为初始化选择默认框架。
1.2.5 其他内容

可以将所有特定于主板的配置文件存储在那里,例如内核配置(kernel configuration)、根文件系统覆盖层(root filesystem),或者Buildroot允许设置位置的任何其他配置文件(通过使用BR2_EXTERNAL_$(NAME)_PATH变量)。

例如,可以设置全局补丁目录、rootfs覆盖目录和内核配置文件的路径,如下所示(运行make menuconfig并填写这些选项):

BR2_GLOBAL_PATCH_DIR=$(BR2_EXTERNAL_BAR_42_PATH)/patches/
BR2_ROOTFS_OVERLAY=$(BR2_EXTERNAL_BAR_42_PATH)/board/<boardname>/overlay/
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=$(BR2_EXTERNAL_BAR_42_PATH)/board/<boardname>/kernel.config

还可以在br2-external树根目录下的linux/目录里添加额外的Linux内核扩展内容。

1.3 保存配置(savedefconfig)

可以使用命令make savedefconfig来存储builroot配置。

这通过删除默认值的配置选项来剥离builroot配置。结果存储在一个名为defconfig的文件中。如果想将其保存在另一个地方,请更改Buildroot配置本身中的BR2_DEFCONFIG选项,或者使用如下命令:

make savedefconfig BR2_DEFCONFIG=<path-to-defconfig>

存储这个defconfig的推荐位置是configs/<boardname>_defconfig。如果你遵循这个建议配置将在make list-defconfigs中列出,并且可以通过命令make <boardname>_defconf重新设置,或者可以将文件复制到任何其他位置,并使用下面命令重构:

make defconfig BR2_DEFCONFIG=path-to-defconfig
1.4 保存软件包的配置

BusyBoxLinux kernelBareboxU-BootuClibc的配置文件如果更改了,也应该存储起来。对于每一个组件,都有一个builroot配置选项指向一个输入配置文件,例如BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE。为了存储它们的配置,将这些配置选项设置为想要保存配置文件的路径,然后使用下面描述的命令来实际存储配置。建议存放这些配置文件的路径如下:

board/<company>/<boardname>/foo.config

确保在更改BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE等选项之前创建了一个配置文件。否则,builroot将尝试访问这个配置文件,它还不存在,并且会失败。可以通过命令make linux-menuconfig创建配置文件。

通过软件包配置,buildroot可以额外支持make xxx-menuconfig目标,用来配置指定软件包,以下是内建支持的软件包

  • make linux-update-defconfig,保存Linux配置到BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE路径文件里。
  • make busybox-update-config,保存busybox配置到BR2_PACKAGE_BUSYBOX_CONFIG路径文件里。
  • make uclibc-update-config,保存uClibc配置到BR2_UCLIBC_CONFIG路径文件里。
  • make barebox-update-defconfig,保存barebox配置到BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE路径文件里。
  • make uboot-update-defconfig,保存U-Boot配置到BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE路径文件里。
1.5 定制目标文件系统

除了通过make *config更改配置之外,还有一些其他方法可以定制生成的目标文件系统。推荐的两种方法是根文件系统覆盖和构建后脚本,它们可以共存:

(1) Root filesystem overlays (BR2_ROOTFS_OVERLAY),文件系统覆盖层是一个文件树,在构建目标文件系统之后直接复制到目标文件系统上。要启用此功能,将配置选项BR2_ROOTFS_OVERLAY(在System configuration菜单中)设置为overlay的根目录。可以指定多个覆盖,以空格分隔。

如果指定一个相对路径,它将相对于Buildroot树的根。版本控制系统的隐藏目录(如.git.svn.hg),.empty空文件和以~结尾的文件被排除在拷贝之外。

当启用BR2_ROOTFS_MERGED_USR时,覆盖层必须不包含/bin/lib/sbin目录,因为builroot会将它们创建为指向/usr中相关文件夹的符号链接。在这种情况下,如果覆盖层有任何程序或库,它们应该放在/usr/bin/usr/sbin/usr/lib中。

(2) Post-build scripts (BR2_ROOTFS_POST_BUILD_SCRIPT),构建后脚本是在buildrot构建所有选定软件之后,但在组装rootfs映像之前调用的shell脚本。要启用此功能,请在配置选项BR2_ROOTFS_PoST_BUILD(在系统配置菜单中)中指定一个以空格分隔的构建后脚本列表。如果指定一个相对路径,它将相对于Buildroot树的根。

使用构建后脚本,可以删除或修改目标文件系统中的任何文件。但是,应该谨慎使用此功能。每当发现某个包生成错误或不需要的文件时,应该修复该包,而不是使用一些构建后清理脚本来解决它。该脚本的推荐路径如下:

board/<company>/<boardname>/post_build.sh

运行后构建脚本时,将主Buildroot树作为当前工作目录。目标文件系统的路径作为每个脚本的第一个参数传递。如果配置选项BR2_ROOTFS_POST_SCRIPT_ARGS不为空,这些参数也将传递给脚本。所有脚本都将被传递完全相同的参数集,不可能向每个脚本传递不同的参数集。此外还可以使用下面这些环境变量:

  • BR2_CONFIG,buildroot配置文件.config的路径。
  • CONFIG_DIR,包含.config文件的目录,对应顶级buildroot Makefile使用的配置文件(对于树内和树外构建都是正确的)。
  • HOST_DIR, STAGING_DIR, TARGET_DIR,分别对应全局hoststagingtarget目录路径。
  • BUILD_DIR,软件包实际源文件和编译目录。
  • BINARIES_DIR,存储所有二进制文件(又名映像)的位置。
  • BASE_DIR,基本输出目录。

下面将描述另外三种定制目标文件系统的方法,但不推荐使用。

(1) Direct modification of the target filesystem,对于临时修改,可以直接修改目标文件系统并重新构建映像。目标文件系统在output/target/下可用。在进行更改之后,运行make来重新构建目标文件系统映像。

该方法允许对目标文件系统执行任何操作,但是如果需要使用make clean清理Buildroot树,那么这些更改将丢失。这种make clean在一些情况下是必要的,因此,此解决方案仅对快速测试有用: 更改无法在make clean命令下存活。一旦验证了更改,应该确保它们在make clean(使用根文件系统覆盖或构建后脚本)之后将持续存在。

(2) Custom target skeleton (BR2_ROOTFS_SKELETON_CUSTOM),根文件系统映像是从目标框架创建的,所有包都在其上安装它们的文件。在构建和安装任何包之前,文件框架(skeleton)被复制到目标目录output/target。默认的目标框架提供标准的Unix文件系统布局和一些基本的初始化脚本和配置文件。

如果默认框架(在system/skeleton下可用)不符合需求,通常会使用根文件系统覆盖或构建后脚本来调整它。但是,如果默认框架与需要的框架完全不同,那么使用自定义框架可能更合适。

要启用此特性,请启用配置选项br2_rootfs_skeleton,并将BR2_ROOTFS_SKELETON_CUSTOM设置为自定义框架的路径。这两个选项在System configuration菜单中都可用。如果指定一个相对路径,它将相对于Buildroot树的根目录。

自定义框架不需要包含/bin/lib/sbin目录,因为它们是在构建过程中自动创建的。当启用BR2_ROOTFS_MERGED_USR时,自定义框架必须不包含/bin/lib/sbin目录,因为builroot会将它们创建为指向/usr中相关文件夹的符号链接。在这种情况下,如果框架有任何程序或库,它们应该放在/usr/bin/usr/sbin/usr/lib中。

不推荐使用这种方法,因为它会复制整个框架,这会妨碍利用在以后的builroot版本中对默认框架所做的修复或改进。

(3) Post-fakeroot scripts (BR2_ROOTFS_POST_FAKEROOT_SCRIPT),当聚合最终映像时,该过程的某些部分需要root权限:在/dev中创建设备节点,设置文件和目录的权限或所有权。为了避免需要实际的根权限,builroot使用fakeroot来模拟根权限。这并不能完全替代实际的root身份,但足以满足Buildroot的需要。

Post-fakeroot scripts脚本是在fakeroot阶段结束时调用的shell脚本,就在调用文件系统映像生成器之前。因此,它们在fakeroot上下文中被调用。如果您需要调整文件系统以进行通常只有root用户才能进行的修改,那么Post-fakeroot脚本可能非常有用。

建议使用现有的机制来设置文件权限或在/dev中创建条目或创建用户。 post-build脚本和fakeroot脚本的区别在于,post-build脚本不会在fakeroot上下文中调用。

使用fakeroot并不能完全替代实际的root身份。Fakeroot只获取文件访问权限和类型(常规、块或字符设备…)以及uid/gid,这些是在内存中模拟的。

1.6 设置文件权限和归属

添加自定义设备节点有时需要在文件或设备节点上设置特定的权限或所有权。例如,某些文件可能需要由root拥有。由于后构建脚本不是以root身份运行的,因此不能从那里进行此类更改,除非在后构建脚本中使用显式的fakeroot

相反,builroot提供了对所谓的权限表的支持。要使用此特性,请将配置选项BR2_ROOTFS_DEVICE_TABIE设置为一个以空格分隔的权限表列表,即遵循makedev语法的常规文本文件。如果使用的是静态设备表(即不使用devtmpfsmdeveudev),那么可以使用相同的语法在所谓的设备表中添加设备节点。要使用此特性,请将配置选项BR2_ROOTFS_STATIC_DEVICE_TABLE设置为一个以空格分隔的设备表列表。

这些文件的推荐位置是board/<company>/<boardname>/。应该注意的是,如果特定的权限或设备节点与特定的应用程序相关,则应该在包的.mk文件中设置变量FOO_PERMISSIONSFOO_DEVICES

makedev语法通常形式如下(可在buildroot maunal手册第25章中浏览详细描述):

name 	 type mode uid  gid  major minor start inc count
/dev/hda b    640  root root 3     1     1     1   15
1.7 设置自定义用户

有时需要在目标系统中添加特定的用户。为了满足这一需求,builroot提供了对所谓用户表的支持。要使用此特性,请将配置选项BR2_ROOTFS_USERS_TABLES设置为一个以空格分隔的用户表列表,即遵循makeusers语法的常规文本文件。

这些文件的推荐位置是board/<company>/<boardname>/。应该注意的是,如果自定义用户与特定的应用程序相关,则应该在包的.mk文件中设置变量FOO_USERS

makeusers语法通常形式如下(可在buildroot maunal手册第26章中浏览详细描述):

username uid group gid password home      shell   groups      comment
foo      -1  bar   -1  !=blabla /home/foo /bin/sh alpha,bravo Foo user
1.8 镜像后处理操作

在构建文件系统映像、内核和引导加载程序之前可以运行后构建(post-build)脚本,但在创建所有映像之后,还可以使用后镜像(post-image)脚本执行一些特定的操作。

例如,后镜像脚本可用于自动提取NFS服务器导出位置中的根文件系统tarball,或创建一个特殊的固件映像,将根文件系统和内核映像捆绑在一起,或用于项目所需的任何其他自定义操作。

要启用此功能,请在配置选项BR2_ROOTFS_POST_IMAGE_SCRIPT(在系统配置菜单中)中指定一个以空格分隔的后映像脚本列表。如果指定一个相对路径,它将相对于Buildroot树的根目录。就像后期构建脚本一样,后期镜像脚本以主Buildroot树作为当前工作目录运行。

镜像输出目录(output/images)的路径作为每个脚本的第一个参数传递。如果配置选项BR2_ROOTFS_POST_SCRIPT_ARGS不为空,这些参数也将传递给脚本。所有脚本都将被传递完全相同的参数集,不可能向每个脚本传递不同的参数集。同样,就像构建后脚本一样,脚本可以访问环境变量BR2_CONFIGHOST_DIRSTAGING_DIRTARGET_DIRBUILD_DIRBINARIES_DIRCONFIG_DIRBASE_DIR

后镜像(post-image)脚本将作为执行builroot的用户执行,通常不应该是根用户。因此,在这些脚本中任何需要root权限的操作都需要特殊处理(使用fakerootsudo),这将留给脚本开发人员。

1.9 提供patch补丁文件

在builroot中提供的补丁之上,有时对包应用额外的补丁是有用的。例如,这可能用于支持项目中的自定义特性,或者在处理新体系结构时。BR2_GLOBAL_PATCH_DIR配置选项可用于指定包含包补丁的一个或多个目录的空格分隔列表。

对于特定包<package name>的特定版本< packag version >,补丁从BR2_GLOBAL_PATCT应用如下:

  1. 首先尝试BR2_GLOBAL_PATCH_DIR定义的全局补丁目录(可有多个),即global-patch-dir>中确定package-patch-dir目录。

    (1) 如果<global-patch-dir>/<package name>/<package version>/目录存在,该目录作为package-patch-dir目录。

    (2) 否则,尝试使用<global-patch-dir>/<packagename>目录作为package-patch-dir目录。

  2. 然后尝试使用package-patch-dir目录下的补丁。

    (1) 如果包目录中存在序列补丁文件(series files),则按照系列文件的顺序应用补丁;

    (2) 否则,*.patch文件将按字母顺序应用补丁。因此,为了确保它们以正确的顺序应用,强烈建议将补丁文件命名为:

    <number>-<description>.patch # 其中<number>指的是应用顺序
    

BR2_GLOBAL_PATCH_DIR选项是为包指定自定义补丁目录的首选方法。它可用于为built_root中的任何包指定补丁目录。它还应该用来代替自定义补丁目录选项,这些选项可用于U-Boot和Barebox等软件包。通过这样做,它将允许用户从一个顶层目录管理他们的补丁。

除了BR2_GLOBAL_PATCH_DIR是指定自定义补丁的首选方法之外,也可用BR2_LINUX_KERNEL_PATCH来指定在URL上可用的内核补丁。BR2_LINUX_KERNEL_PATCH指定在BR2_GLOBAL_PATCH_DIR中可用的补丁之后应用的内核补丁,因为它是从Linux包的补丁后钩子(post-patch)完成的。

1.10 提供hash文件

builroot捆绑了一个哈希列表,根据它来检查下载存档的完整性,或者从VCS签出本地生成的完整性。然而,它只能对已知的版本这样做,对于可以指定自定义版本的包(例如自定义版本、远程tarball URL或VCS存储库位置和变更集),builroot不能为这些包携带哈希值。

对于关心此类下载完整性的用户,可以提供一个哈希列表,Buildroot可以使用它来检查任意下载的文件。这些额外的哈希与上面的额外补丁相似。

对于BR2_GLOBAL_PATCH_DIR中的每个目录,第一个存在的文件用于检查包下载:

  • <global-patch-dir>/<packagename>/<packageversion>/<packagename>.hash
  • <global-patch-dir>/<packagename>/<packagename>.hash

utils/add-custom-hashes脚本可用于生成这些文件。

1.11 添加自定义包

通常,任何新包都应该直接添加到包目录中,并提交给builroot上游项目。项目可能需要一些专有的软件包,而这些软件包不能被上游化,因此这些特定项目的包需要保存在特定项目的目录中

项目特定包的推荐位置是package/<company>/。如果正在使用br2-external树特性,建议将它们放在br2-external树中名为package/的子目录中。

但是,除非执行一些额外的步骤,否则buildrot将不会知道这个位置中的包。在Buildroot中的包基本上由两个文件组成:.mk文件(描述如何构建包)和一个Config.in文件(描述这个包的配置选项)。

builroot会自动将.mk文件包含在包目录的第一级子目录中(使用模式匹配package/*/*.mk)。如果我们想要Buildroot从更深的子目录(如package/<company>/packagel)中包含.mk文件,只需要在第一级子目录中添加一个.mk件,其中包括这些额外的内层.mk文件。因此,创建一个package/<company>/<company>.mk中包含以下内容(假设在package/<company>/下面只有一个额外的目录级别):

include $(sort $(wildcard package/<company>/*/*.mk))

对于Config.in文件,创建一个package/<company>/Config.in,其中包括在所有软件包中的Config.in文件。由于kconfig的源命令中不支持通配符,因此必须提供详尽的列表。例如:

source "package/<company>/package1/Config.in"
source "package/<company>/package2/Config.in"
1.12 操作快速指南

前面已经描述了进行自定义项目的不同方法。本节将通过提供存储自定义项目的分步操作说明来总结所有这些内容。

  1. make menuconfig,配置toolchainpackageskernel

  2. make linux-menuconfig,更新Linux内核配置,其他工具busybox/uclibc都可以类似操作。

  3. mkdir -p board/<manufacturer>/<boardname>,创建自定义项目的目录。

  4. board/<manufacturer>/<boardname>/<package>.config,在该文件里配置一下参数(如果用到的话)。

    BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
    BR2_PACKAGE_BUSYBOX_CONFIG
    BR2_UCLIBC_CONFIG
    BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE
    BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE
    BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
    
  5. 执行make xxx-config写入对应软件配置到步骤4中指定配置文件中去,如下:

    make linux-update-defconfig
    make busybox-update-config
    make uclibc-update-config
    cp <output>/build/at91bootstrap3-*/.config board/<manufacturer>/<boardname>/at91bootstrap3.config
    make barebox-update-defconfig
    make uboot-update-defconfig
    
  6. 创建目录board/<manufacturer>/<boardname>/rootfs-overlay/,然后按需填充该目录,例如添加etc/inittab文件。同时需要把BR2_ROOTFS_OVERLAY变量值设置为该目录。

  7. 创建post-build脚本board/<manufacturer>/<boardname>/post_build.sh,同时设置BR2_ROOTFS_POST_BUILD_SCRIPT值为该脚本的路径。

  8. 如果必须设置额外的setuid权限或必须创建设备节点,请创建board/<manufacturer>/<boardname>/device_table.txt并将该路径添加到BR2_ROOTFS_DEVICE_TABLE中。

  9. 如果需要添加自定义的用户账户,请创建board/<manufacturer>/<boardname>/users_table.txt,并添加该路径到BR2_ROOTFS_USERS_TABLES中。

  10. BR2_GLOBAL_PATCH_DIR设置为board/<manufacturer>/<boardname>/patches/并在以包命名的子目录中为每个包添加补丁。每个补丁应该命名为<packagename>-<num>-<description>.patch

  11. 特别是对于Linux内核,还存在BR2_LINUX_KERNEL_PATCH选项,其主要优点是它也可以从URL下载补丁。如果不需要,首选BR2_GLOBAL_PATCH_DIR。UBoot, Barebox, at91bootstrap和at91bootstrap3也有单独的选项,但这些没有提供任何优于BR2_GLOBAL_PATCH_DIR的优势,将来可能会被删除。

  12. 如果需要添加特定项目的包,请创建package/<manufacturer>/并将包放在该目录中。创建一个整体<manufacturer>.mk文件,包含所有包的.mk文件。创建一个整体Config.in文件并包含所有包的Config.in文件。在Buildroot的package/Config.in文件里包含这个整体Config.in`文件。

  13. make savedefconfig,保存以上定制的buildroot配置。

  14. cp defconfig configs/_defconfig,拷贝该配置文件到预期目录中保存起来。

2. 杂项问题
2.1 NFS引导镜像启动

要实现nfs引导,在filesystem images菜单中启用tar root filesystem。完成构建后,只需运行以下命令来设置NFS-root目录:

sudo tar -xavf /path/to/output_dir/rootfs.tar -C /path/to/nfs_root_dir

记得把这个路径添加到/etc/exports然后,可以从目标执行NFS-boot

2.2 Live CD引导镜像启动

要构建live CD映像,请在Filesystem images菜单中启用iso image选项。请注意,此选项仅在x86和x86-64体系结构上可用,且使用builroot构建内核。

可以使用IsoLinuxGrubGrub 2作为引导加载程序来构建live CD映像,但是只有IsoLinux支持将该映像既可用作live CD又可用作live USB(通过构建混合映像(hybrid image)选项)。

可以使用QEMU测试live CD映像:

Qemu-system-i386 -cdrom output/images/rootfs.iso9660

或者使用它作为一个硬盘驱动器镜像,如果它是一个混合的ISO:

Qemu-system-i386 -hda output/images/rootfs.iso9660

它可以很容易地用dd保存到USB驱动器:

Qemu-system-i386 -hda output/images/rootfs.iso9660
3. 附加信息
3.1 fakeroot介绍

Fakeroot 是一个 Linux 工具,它允许用户执行一些需要 root 权限的操作,尽管用户实际上并没有 root 权限。它通过提供一个虚假的 root 环境来达到这个目的,使得在这个环境中的命令行操作看起来好像是由 root 用户执行的。

Fakeroot 通过拦截系统调用并修改相关的返回值来工作,让调用者认为他们具有真正的 root 权限。例如,一个普通用户通常无法更改只读文件的所有者,但在 fakeroot 环境中,用户可以执行此操作(尽管实际上并未发生改变)。

Fakeroot 的一个常见用途是在软件包制作过程中。许多 Linux 发行版的软件包管理系统要求软件包文件和目录拥有特定的所有者和权限。使用 fakeroot,包维护者可以创建看似具有这些所有者和权限的文件和目录,然后将它们打包成一个软件包。这样,用户在安装软件包时就会看到正确的所有者和权限。

简单的使用示例如下:

fakeroot bash  # 进入一个新的 bash shell,该 shell 会提供一个虚假的 root 环境

在此环境中,用户可以执行需要 root 权限的命令,例如 chownchmod

尽管 fakeroot 可以模拟 root 用户的行为,但它并不能提供真正的 root 权限。如果用户试图执行真正需要 root 权限的操作(例如安装全局软件或更改系统文件),这些操作将会失败。

此外,fakeroot 也不会提供任何额外的安全或隔离。所有在 fakeroot 环境中执行的操作都是在用户的实际权限下进行的。所以,fakeroot 不应被视为一种安全工具或用于沙箱环境。

3.2 序列补丁文件(series files)

在 Linux 和 Unix 系统中,series 文件通常用于描述一系列补丁的应用顺序。这个文件通常存在于用于源代码包管理的情况,尤其是在 Slackware Linux 发行版及其衍生版本中。

series 文件位于 /patches 目录中,其中列出的每一行通常代表一个补丁文件。在构建过程中,这些补丁会按照在 series 文件中的顺序被逐个应用到源代码上。

这是一个简单的 series 文件示例:

patch1.diff
patch2.diff
patch3.diff

在这个例子中,patch1.diff 补丁会首先被应用,然后是 patch2.diffpatch3.diff。这样可以确保补丁以正确的顺序被应用,特别是当某些补丁依赖于其他补丁的情况下。

注意,series 文件并不是所有 Linux 或 Unix 系统都会使用,它主要出现在一些特定的源代码包管理环境中。

3.3 NFS-boot引导

NFS-boot 是一种在网络上启动和运行系统的方法,通常用于无盘工作站或者网络启动。NFS 是 Network File System(网络文件系统)的缩写,它允许一台计算机在网络上共享它的文件系统。在 NFS-boot 的情况下,操作系统的根文件系统(root filesystem)实际上位于网络上的另一台计算机上,并通过 NFS 共享。

具体来说,当一台计算机进行 NFS-boot 时,它会通过网络启动协议(如 BOOTP 或 DHCP)获取其 IP 地址和其他网络设置。然后,它会使用这些信息来通过 NFS 挂载其根文件系统。此时,所有的文件操作(如读取、写入)实际上是在远程的 NFS 服务器上执行的。

NFS-boot 的主要优点是,你可以在没有本地存储(或者只有有限的本地存储)的计算机上运行完整的操作系统。此外,由于文件系统位于网络服务器上,所以在多台计算机之间共享文件和应用程序相对较为简单。

然而,NFS-boot 也有一些缺点。首先,网络性能可能会影响到系统的整体性能,尤其是在网络带宽有限或网络延迟较高的情况下。其次,如果网络连接中断,或者 NFS 服务器出现问题,那么 NFS-boot 的计算机可能会无法正常运行。

在设置 NFS-boot 时,通常需要在 NFS 服务器上配置共享的文件系统,并在客户端上配置网络启动。具体的设置步骤可能会根据使用的操作系统和网络环境的不同而有所不同。

3.4 Live CD启动

Live CD 是一种包含完整操作系统的光盘,它可以在不改变计算机硬盘上的数据的情况下,直接从光盘启动操作系统。这种技术不仅适用于 CD,也可以用于 DVD、USB 驱动器等可启动的媒体。

Live CD 在启动时,通常会在 RAM 中创建一个临时的、可写的文件系统,所以用户可以正常地使用操作系统,而不会影响计算机的硬盘。当用户关闭系统时,所有的更改(包括系统设置和用户数据)都会丢失,除非特别地保存到其他的存储设备上。

Live CD 的一些常见用途包括:

  • 故障恢复:当计算机的主要操作系统无法启动或者有问题时,可以使用 Live CD 来修复系统或者恢复数据。

  • 系统测试和演示:可以通过 Live CD 来尝试新的操作系统或者软件,而不需要实际地安装到计算机上。

  • 安全和隐私:由于 Live CD 不会保存任何数据,所以它们经常被用于处理敏感信息,例如在线银行或者密码管理。

  • 安装系统:许多操作系统的安装程序都是通过 Live CD 提供的,用户可以先在 Live CD 中体验系统,然后再决定是否要安装到硬盘上。

统,并在客户端上配置网络启动。具体的设置步骤可能会根据使用的操作系统和网络环境的不同而有所不同。

12-04 07:15