配置是构建内核的第一步。有许多方法和各种选项可供选择。内核将在进程结束时生成一个 .config 文件,并生成一系列符号链接和文件头,系统其余部分将使用这些文件来完成配置。
Linux内核是任何安装的核心,无论是嵌入式还是桌面,它负责分配内存、创建进程、管理和调度数据,以及支持与其他系统交互所需的协议。Linux 桌面和服务器系统需要支持大量外围设备,因为无法预测与每个操作系统相关的硬件。同样,此类系统还必须支持广泛的通信和数据交换协议,以便它们可以用于大量不同的目的。嵌入式设备通常需要支持一组特定的设备、外围设备和协议,具体取决于给定设备中的硬件。
Linux 内核在支持它的处理器和设备的体系结构方面是高度可配置的。嵌入式设备的特定架构、处理器和硬件要求的配置是任何 Linux 项目的基础。优化内核以支持特定硬件和协议,最大限度地减少其存储大小和内存需求,从而对性能产生积极影响。
内核配置允许您选择要包含在进程中的各种选项。有些选项可用,有些则不可用,这取决于嵌入式架构。无论硬件架构如何,可用于分析然后包含在处理配置中的主要选项如下:
- 代码成熟度级别选项
- 常规设置
- 支持可加载模块
- 块层
- 联网
- 设备驱动程序
- 文件系统
- 内核黑客
- 安全
- 文字学
- 库例程
内核可以包括各种安全选项,作为美国国家安全局 (NSA) 实施的 SELinux 堆栈的一部分。Security-Enhanced Linux (SELinux) 是一组选项,可应用于 Linux 和 BSD 等类 Unix 操作系统;实际上,它是 Linux Kernel 的一个模块,提供了一系列工具来实现安全协议。一个更重要的选项是您选择最适合目标的处理器架构的确切实例。名称根据其架构而有所不同。在表 1 中有一个内核选项和体系结构的列表,这些选项和体系结构根据通过使用 Makefile 内核识别的体系结构名称设置变量“ARCH”而正确选择的处理器。
可以使用的前端配置很多,主要参考2.6及以后的内核:
- 构建目标文件以渲染内核映像:选择组件后,构建内核需要以下步骤:
- 生成依赖头文件信息(哪个.c文件依赖哪个.h文件)。对于 2.6 及更高版本的内核,这不是必需的。
- 使用 make clean 命令,清理除配置信息外的所有目标文件、内核映像和所有中间文件。
- 创建内核映像。内核映像的名称是 vmlinux。然而,编译内核并不止于此。通常需要进行一些后处理,例如压缩、添加引导代码等。实际上,后处理将创建稍后将在目标中使用的图像。
- 使用 make modules 命令构建可动态加载的模块。通常,在嵌入式系统上,构建过程会进一步定制,原因如下:在单独的目录中添加 BSP 并修改配置,以便 kbuild 可以构建板所需的软件组件;为构建过程添加您自己的链接器、编译器和汇编器;构建内核映像后自定义后处理;在 kbuild 中构建协议以进行系统范围的构建。
使用内核
Linux 内核可以通过以下两种方式之一使用外围驱动程序:编译到内核中或按需动态加载。可加载内核模块 (LKM) 被编译为目标文件,随后被编译为与特定内核一起工作,以便动态加载以响应新的硬件要求。
可加载内核模块(或 LKM)是一个目标文件,其中包含扩展正在运行的内核的代码;它通常用于添加对新硬件和/或文件系统的支持,或添加系统调用。
LKM 作为文件存储在内核之外,存储在物理文件系统或内核可以访问的内存中。
虽然内核模块的动态加载确实有一些开销,但该开销的成本被 LKM 在开发和部署期间提供的灵活性所抵消。因此,内核和相关的设备驱动程序配置主要是区分强制设备和按需协议的问题。在 Linux 桌面或服务器系统上,对 PATA 或 SATA 硬盘驱动器等日常设备的支持通常编译到内核中,因为这些设备存在于大多数计算机系统中。作为一般规则,引导系统所需的硬件外围驱动程序通常内置在 Linux 内核中,以便它们可以自动可用。一旦系统启动,Linux 就可以访问内存或文件系统,并可以通过 LKM 加载几乎任何其他硬件的驱动程序。
Linux 内核使用称为 kconfig 的集成机制进行配置,该机制通过自动满足不同驱动程序之间的依赖关系来简化架构、处理器和设备驱动程序的选择。Timesys Desktop 提供内置的 kconfig 支持,还将其扩展为 Linux 嵌入式开发项目其他部分的简单配置机制,例如操作系统基础架构和应用程序选择和支持。
现代 Linux 系统不是通过预先创建(和保留)每个可能的设备节点来浪费空间,而是支持一种按需创建节点的机制,称为 udev。当检测到新硬件时,该守护进程创建强制设备节点来运行适用于检测到的特定硬件或设备类别的一个或多个规则。
动态创建设备的完整性取决于Linux系统初始化和识别硬件的顺序,这可能并不总是以相同的顺序发生。如果不考虑,这可能会导致以太网接口以不同的顺序命名。这将使系统难以配置以不同方式管理设备或将它们用于特定目的。为了消除此类问题,在静态和动态设备创建之间提供正确的折衷方案,udev 守护程序会为某些类别的检测到的设备创建更新并保存一组规则。当 Linux 系统重新启动时,这些规则与任何其他 udev 规则一样用于响应硬件检测。但是,由于它们还包含特定的命名分配,因此每次系统重新启动后设备映射都是相同的。
对于仅访问一组特定设备的嵌入式设备,为硬件预先创建静态节点消除了运行 udev 的需要,从而减少了内存和存储需求。另一方面,在设计用于与不一定预期的外围设备一起使用的嵌入式设备中,例如 USB 设备,udev 机制提供了默认系统最初所需的设备节点。
交叉编译准备:“ARCH”和“CROSS_COMPILE”
内核对架构的选择是通过两个变量进行的。变量是“ARCH”和“CROSS_COMPILE”,默认值显示在存储在源根目录中的 Makefile 中(图 2)。变量 'ARCH' 以特定内核格式指示目标体系结构的名称:i386(arch / 子目录将给出不同体系结构的概念)。'CROSS_COMPILE' 变量是不言自明的,用工具链前缀增强:也就是说,如果我们考虑 x86_64-pc-linux-gnu-gcc,那么写 x86_64-pc-linux-gnu 就足够了。/lib 库目录是根据附加变量“INSTALL_MOD_PATH”创建的,其中还存储了每个所需模块在编译时所需的所有模块。系统的准备以两种方式进行:通过修改 Makefile 或通过从命令行评估变量。也可以通过脚本 (xmake) 设置命令并在内核编译期间运行它们(图 3)。
配置方法
Linux 内核构建系统 (kbuild) 包括对多种配置方法的支持,例如:
make config,它提供了一个命令行界面,提示您设置每个选项。如果配置配置文件已经存在,则该文件用于设置默认值。
make oldconfig,具有现有文件的配置,仅用于先前未配置的选项。这与 make config 形成对比,后者需要所有选项,甚至是以前配置的选项。开发人员经常使用此选项来更新他们的配置,而无需重新配置整个内核。
make menuconfig(图 4):在终端上显示配置菜单。如果存在 .config 文件,则它用于设置默认值,例如 make config。
make xconfig(图 5),它显示基于 Tk 的 X Window 配置菜单(Tk 工具包是用于在 X Window 系统下构建 GUI 的编程环境)。如果存在 .config 文件,则它用于设置默认值,就像 make config 和 menuconfig 一样。
这些中的每一个都可用于配置内核。它们都在根内核源目录中生成一个 .config 文件(该文件包含所选选项的完整详细信息)。
很少有开发人员真正使用 makeconfig 命令来配置内核。相反,大多数使用 make menuconfig 创建初始配置或修改现有配置。要查看内核配置菜单,您必须在命令行中键入适当的命令并使用正确的参数。例如,要编译用于集成 ARM 系统的 Linux 内核,可以使用以下命令行: $ Make ARCH = arm CROSS_COMPILE = arm-linux-menuconfig。
配置内核后,内核配置系统会要求您保存新配置。除了创建 .config 文件之外,还会创建一些头文件和符号链接。也可以在不进行任何更改的情况下退出内核配置。
除了主要的配置选项外,内核架构支持通常包括用于某些目标的标准模型配置。对于标准 ARM 处理器尤其如此。在这些情况下,内核提供的默认值将用于生成 .config 文件。
通常需要测试使用相同内核源的不同配置。但是,更改内核配置会破坏以前的配置,因为所有配置文件都被内核配置实用程序覆盖。要保存配置以供将来使用,您需要保存以前创建的 .config 文件。然后可以重用这些文件来恢复以前的内核配置。
您还可以轻松地保存 .config 文件,即将内核配置实用程序创建的配置文件复制到备用位置以供将来使用。要使用已保存的配置,您需要将之前保存的 .config 文件复制回内核根目录,然后使用 Makefile oldconfig 命令使用新复制的 .config 文件配置内核。
与内核一样,应用程序也必须使用开发工具来构建。大多数开源程序都遵循 GNU 编译标准,该标准是几个工具的集合,下面列出了其中最重要的工具。
– autoconf:提供一个通用的可移植性框架,基于编译时主机系统特性的测试。
– automake:允许开发人员编写简化的 Makefile。
– libtool:创建共享库的标准化方法
测试内核
一般来说,有很多方法可以测试 Linux 内核:
- 带有内核的试用版。
- 通过在新内核上将测试套件作为 LTP 运行。
- 通过使用新安装的内核测量系统性能。
第一个测试阶段包括使用 init = / bin / bash 在功能齐全的配置中引导系统。从那里,您可以检查文件系统是否正确挂载和卸载,并且可以尝试一些更复杂的内核功能,例如以最小配置挂起到磁盘或 RAM。接下来,您可以将系统引导到运行级别 3(通常,将数字 2 作为参数传递给内核)。在此配置中,您可以检查网络接口,您可以尝试手动运行 X 服务器以确保它不会崩溃。在下一个测试阶段,您可以使用旨在通过回归和性能测试验证内核功能的特殊程序。后者对于内核开发人员来说尤其重要,因为它们有助于识别由于更新引起的变化。
对于自动化内核测试,您可以使用 AutoTest 套件,其中包括许多测试应用程序和工具,并结合了简单的用户界面。上面看到的运行级别是一个典型的 UNIX 系统概念,代表机器的活动状态。每个运行级别由一个数字标识:
- 运行级别 0:停止系统。
- 运行级别 1(单用户模式):用于维护活动。
- 运行级别 2(多用户模式):启用网络但没有网络服务。
- 运行级别 3(多用户模式):启用所有网络功能,并激活所有相关服务。
- Runlevel 4:一般不使用;
- 运行级别 5:类似于运行级别 3 加上启用的图形服务器;
- 运行级别 6:用于系统重启。
文件系统
Linux 内核在系统引导期间所做的最后一件事是挂载根文件系统。Linux 内核没有规定文件系统结构,但用户空间应用程序希望在目录结构中找到具有特定名称的文件。
配置内核的下一步是创建根文件系统(图 6)。可以使用两种主要技术:initrd / initramfs 和使用 NFS 通过网络安装根预文件系统。Initrd(initial ramdisk),从内核 2.6 版开始在 Linux 中引入,是一个小型临时文件系统,在引导过程的初始阶段充当安装在内存中的根文件系统,可通过引导加载程序访问内核.
审核编辑:汤梓红
评论
查看更多