嵌入式Linux——Linux 内核配置三剑客:一篇搞懂 Kconfig, .config 和 defconfig
Kconfig:配置选项的“蓝图”
-
当你用
make menuconfig时看到的那个文本界面的来源,即由Kconfig定义。 -
作用:
-
定义配置选项: 它使用一种特定的语言来定义每一个内核配置选项(在内部称为“符号”,Symbol),例如 CONFIG_USB_STORAGE。
-
描述选项类型: 定义该选项是布尔型(bool,是/否)、三态(tristate,是/否/模块)还是字符串(string)、整数(int)等。
-
建立依赖关系: 这是 Kconfig 最强大的功能。它可以定义一个选项依赖于另一个选项(depends on)或者选择另一个选项(select)。例如,某个特定的 USB WiFi 驱动程序会 depends on CONFIG_USB 和 CONFIG_WLAN。如果您没有启用 USB 和无线网络支持,配置系统甚至不会向您显示这个驱动选项。
-
组织菜单结构: Kconfig 文件通过 menu 和 endmenu 来组织配置菜单的层级结构。
-
-
如何工作:
- 当您运行任何配置命令(如 make menuconfig)时,系统会解析遍布内核源码树的所有 Kconfig 文件,在内存中建立一个完整的配置选项树及其依赖关系,然后将其呈现给你。
.config:最终的“编译指令单”
-
它是配置过程的最终产物,也是编译过程的直接输入。(它是
make menuconfig保存过后的结果) -
作用:
-
记录最终选择: 它是一个纯文本文件,记录了您对所有 Kconfig 中定义的选项所做的最终选择。
-
指导编译: make 编译系统(称为 kbuild)会读取此文件来决定编译行为。
-
CONFIG_FOO=y:表示该功能(FOO)将被静态编译到内核主文件(如 vmlinux 或 bzImage)中。
CONFIG_FOO=m:表示该功能将被编译为一个可加载的内核模块(.ko 文件)。
CONFIG_FOO is not set:表示该功能未被选中,相关代码不会被编译。
-
生成C头文件: 配置系统还会根据 .config 文件自动生成一个C语言头文件(位于 include/generated/autoconf.h),C 源代码(.c 文件)会包含这个头文件,以便在代码中使用 #ifdef CONFIG_FOO 这样的宏来条件性地编译代码块。
-
-
如何生成:
- 你不应该手动编辑 .config 文件,因为它的选项之间存在复杂的依赖关系。您应该始终使用配置工具来生成它,例如:
- make menuconfig:启动一个基于 ncurses 的文本菜单界面(最常用)。
- make xconfig:启动一个基于 Qt 的图形界面。
- make gconfig:启动一个基于 GTK 的图形界面。
- 当您在这些工具中保存配置时,它们会自动生成或更新 .config 文件。
- 你不应该手动编辑 .config 文件,因为它的选项之间存在复杂的依赖关系。您应该始终使用配置工具来生成它,例如:
defconfig:推荐的“默认套餐”
-
defconfig 文件(“default configuration”的缩写)是一个最小化的 .config 文件,它只包含那些与默认值不同的配置选项。
-
作用:
-
提供基础配置: 内核支持成千上万种硬件平台。为每一种平台(如树莓派、某个特定的 ARM 开发板或标准的 x86 PC)提供一个完整功能的 .config 文件是不现实的。相反,维护者只提供一个 defconfig 文件,它包含了启动该平台所需的最小且最关键的配置。
-
作为配置的起点: 当你为某个新平台编译内核时,你的第一步通常不是从零开始配置,而是加载一个官方提供的 defconfig。
-
-
如何使用:
- defconfig 文件通常存储在 arch/<架构名>/configs/ 目录下。例如,x86_64 架构的通用默认配置可能是
arch/x86/configs/x86_64_defconfig。你可以通过运行以下命令来使用它:make x86_64_defconfig - 这个命令会:
-
找到对应您架构的 defconfig 文件(如 arch/x86/configs/x86_64_defconfig)将其作为输入。
-
遍历所有 Kconfig 文件,为 defconfig 中未提及的所有其他选项应用它们的默认值。
-
最终生成一个完整的 .config 文件。
-
在此之后,您可以再运行 make menuconfig 来在这个默认配置的基础上进行您自己的修改。
-
- defconfig 文件通常存储在 arch/<架构名>/configs/ 目录下。例如,x86_64 架构的通用默认配置可能是
总结
-
假设Linux内核就是一份你要点的“豪华套餐”,这份套餐功能超级多,但你不需要全部,你只想点你爱吃的(你需要的硬件驱动和功能)。
-
你要编译内核(点菜):
-
厨房(内核开发者)已经准备好了总菜单 Kconfig(规定了所有功能和依赖规则)。
-
你为了省事,先喊了一声:“来一份店家推荐套餐 defconfig!”
-
服务员(make menuconfig)帮你点好了套餐,并让你加加减减,最后生成了一张最终订单小票 .config。
-
后厨的厨师(编译器)拿走这张小票(.config),然后严格按照小票上的每一项(=y 的做进主菜里,=m 的单独打包,is not set 的就不做了),为你做出了独一无二的“豪华套餐”(你的内核)。
-
更多推荐
所有评论(0)