kconfig kbuild
阅读数:211 评论数:0
跳转到新版页面分类
Linux
正文
一、概述
自从Linux内核代码迁移到Git以来,Linux内核配置/构建系统(也称为Kconfig / kbuild)已存在很长时间了。
二、Kconfig (Kernel config)
menuconfig程序可以识别kconfig文件,然后从中提出有效的信息组成菜单项。
构建内核的第一步始终是配置。Kconfig有助于使Linux内核高度模块化和可定制。Kconfig为用户提供了许多配置目标:
配置 | 使用面向行的程序更新当前配置 |
---|---|
nconfig | 使用ncurses基于菜单的程序更新当前配置 |
menuconfig | 使用基于菜单的程序更新当前配置 |
xconfig的 | 使用基于Qt的前端更新当前配置 |
gconfig | 使用基于GTK +的前端更新当前配置 |
oldconfig | 使用提供的.config作为基础更新当前配置 |
localmodconfig | 更新当前配置禁用未加载的模块 |
localyesconfig | 更新将本地mod转换为核心的当前配置 |
defconfig | 默认来自Arch提供的defconfig的新配置 |
savedefconfig | 将当前配置保存为./defconfig(最小配置) |
allnoconfig | 新配置,其中所有选项均以“否”回答 |
allyesconfig | 使用“是”接受所有选项的新配置 |
allmodconfig | 尽可能新的配置选择模块 |
alldefconfig | 所有符号都设置为默认值的新配置 |
randconfig | 新配置,随机回答所有选项 |
listnewconfig | 列出新选项 |
olddefconfig | 与oldconfig相同,但在没有提示的情况下将新符号设置为其默认值 |
kvmconfig | 为KVM来宾内核支持启用其他选项 |
xenconfig | 为xen dom0和来宾内核支持启用其他选项 |
tinyconfig | 配置最小的内核 |
与Kconfig相关的工具和源代码主要位于内核源代码中的scripts / kconfig /下。
逻辑上讲,Kconfig的基础结构有两部分:一部分实现一种新语言来定义配置项(参见内核源代码下的Kconfig文件),另一部分解析Kconfig语言并处理配置操作。
大多数配置目标具有大致相同的内部过程:
0、所有配置项都具有默认值。
1、读取源根目录下的Kconfig文件,构建初始配置数据库。
.config
/ lib / modules / (shell,uname−r)/.config/etc/kernel−config/boot/config−(shell,uname -r)
ARCH_DEFCONFIG
arch / $(ARCH)/ defconfig
如果你通过menuconfig进行基于GUI的配置或通过oldconfig进行基于命令行的配置,则会根据您的自定义更新数据库。最后,配置数据库被转储到.config文件中。
但.config文件不是内核构建的最终目标 ; 这就是syncconfig目标存在的原因。
syncconfig将.config作为输入并输出许多其他文件,这些文件分为三类:
(1)auto.conf和tristate.conf
用于makefile文本处理。
(2)autoconf.h
用于C语言源文件
(3)include/config/*.h下的空头文件
用于kbuild期间的配置依赖性跟踪。
2、菜单创建
(1)内核源码顶层目录的kconfig
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.txt.
#
mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
config SRCARCH
string
option env="SRCARCH"
source "arch/$SRCARCH/Kconfig"
mainmenu: 主菜单
语法格式:mainmenu "主菜单的名字" 如下图红线部分
source :引入下一级菜单
语法格式: source "下一级菜单的Kconfig的路径" 打开 arch/arm64/目录下的Kconfig文件
(2)次一级目录的kconfig
config ARM64
def_bool y
select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
........
help
ARM 64-bit (AArch64) Linux support.
config 64BIT
def_bool y
......
config PGTABLE_LEVELS
int
default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
source "init/Kconfig"
........
menu "Bus support"
config PCI
bool "PCI support"
help
This feature enables support for PCI bus system. If you say Y
here, the kernel will include drivers and infrastructure code
to support PCI bus devices.
config PCI_DOMAINS
def_bool PCI
config PCI_DOMAINS_GENERIC
def_bool PCI
config PCI_SYSCALL
def_bool PCI
source "drivers/pci/Kconfig"
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/hotplug/Kconfig"
endmenu
menu "CPU Power Management"
source "drivers/cpuidle/Kconfig"
source "drivers/cpufreq/Kconfig"
endmenu
source "net/Kconfig"
source "drivers/Kconfig"
source "drivers/firmware/Kconfig"
source "drivers/acpi/Kconfig"
source "fs/Kconfig"
source "arch/arm64/kvm/Kconfig"
source "arch/arm64/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
if CRYPTO
source "arch/arm64/crypto/Kconfig"
endif
source "lib/Kconfig"
menu…endmenu : 菜单
格式:
menu “菜单的名字”
菜单选项
source “下一级的菜单”
endmenu
如:
menu "CPU Power Management"
source "drivers/cpuidle/Kconfig"
source "drivers/cpufreq/Kconfig"
endmenu
(3)config条目
每个菜单项都有一个关键字标识,最常见的就是config
config symbol
options
语法解释如下:
config 关键字 表示后面是菜单项
symbol 新的菜单项
options 菜单项下的属性和选项
每个config菜单项都要有类型定义:
(1)bool:该config宏只能选择y(编译内核)或者n(不编译),菜单顶前为圆括号
(2)tristate: 三态(y/m/n),表示模块
(3)string: 该config宏可以设为一串字符串,比如#define CONFIG_XXX “config test”
(4)hex: #define CONFIG_XXX 0x1234
(5)int: #define CONFIG_XXX 1234
依赖型定义depends on和select
(1)dependes on:比如depends on XXX 表示当前宏需要CONFIG_ XXX宏打开的前提下,才能设置它
(注意依赖项的config参数只有bool或tristate才有效)
(2)select:: 反依赖项,和depends on刚好相反
比如 selecton
XXX表示当前宏如果是y或者m,则会自动设置XXX=y或者m(注意参数只有bool或tristate才有效)
帮助性定义
只是增加帮助用关键字help或—help—
例如
config ARM64_ACPI_PARKING_PROTOCOL
bool "Enable support for the ARM64 ACPI parking protocol"
depends on ACPI
help
Enable support for the ARM64 ACPI parking protocol. If disabled
the kernel will not allow booting through the ARM64 ACPI parking
protocol even if the corresponding data is present in the ACPI
MADT table.
(4)menu条目
menu条目用于生成菜单,其格式如下:
menu "字符串"
..............
endmenu
(5)choice条目
会生成一个单选框,里面通过多选一方式选择config,需要注意choice中的config参数只能bool或tristate
choice条目将多个类似的配置选项组合在一起,供用户单选或多选
choices条目格式如下
"choice"
<choiceoptions>
<choiceblock>
"endchoice"
(6)comment条目
comment条目用于定义一些帮助信息,出现在界面的第一行
三、kbuild
组件式构建(称为递归make)是GNU make
管理大型项目的常用方法。Kbuild是递归make的一个很好的例子。通过将源文件划分为不同的模块/组件,每个组件都由其自己的makefile管理。当您开始构建时,顶级makefile以正确的顺序调用每个组件的makefile,构建组件,并将它们收集到最终的执行程序中。
Kbuild指的是不同类型的makefile:
1、源根目录的项级makefile
2、.config是内核配置文件
3、arch/$(ARCH)/Makefile
4、**script/Makefile,**描述了所有kbuild makefile的通用规则
5、最后,有很多kbuild makefile
在Documentation/kbuild/makefiles.txt中描述相关的makefile。
让我们看一下在x86-64上生成vmlinux
在x86-64中,vmlinux和bzImage的关系图
源根vmlinux被剥离,压缩,放入piggy.S,然后与其他对等对象链接到arch / x86 / boot / compressed / vmlinux。同时,在arch / x86 / boot下生成一个名为setup.bin的文件。可能有一个可选的第三个文件具有重定位信息,具体取决于CONFIG_X86_NEED_RELOCS的配置 。
由内核提供的称为build的宿主程序将这两个(或三个)部分构建到最终的bzImage文件中。
四、依赖性跟踪
kbuild跟踪三种依赖关系:
1、所有必备文件(.c和.h)
2、所有必备文件 中使用**CONFIG_**选项
3、用于编译目标的命令行依赖项
第一个很容易理解,但第二个和第三个呢?内核开发人员经常会看到如下代码:
#ifdef CONFIG_SMP __boot_cpu_id = cpu; #endif
当CONFIG_SMP更改时,应重新编译这段代码。编译源文件的命令行也很重要,因为不同的命令行可能会导致不同的目标文件。
当**.c文件通过#include**指令使用头文件时,您需要编写如下规则:
main.o: defs.h recipe...
管理大型项目时,需要大量的这些规则; 把它们全部写下来会很乏味和乏味。幸运的是,大多数现代C编译器都可以通过查看源文件中的**#include行来为您编写这些规则。对于GNU编译器集合(GCC),只需添加命令行参数:-MD depfile**