Kconfig 和 Kbuild
Posted Li-Yongjun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kconfig 和 Kbuild相关的知识,希望对你有一定的参考价值。
文章目录
Kconfig、Makefile、.config 关系
Linux kernel 的目录结构下一般都会存在 Kconfig 和 Makefile 两个文件,分布在各级目录中的 Kconfig 构成了一个分布式的内核配置数据库。每个 Kconfig 分别描述了所属目录源文件相关的内核配置菜单。
在执行 make menuconfig 时,从 Kconfig 中读出内核配置菜单,用户配置完后保存为 .config。
内核在编译时,主 Makefile 调用 .config,就知道用户对内核做了哪些配置。
简单来说:
Kconfig 是饭店菜单,Makefile 是菜谱,.config 是用户在菜单上的勾选。
make 这个自动炒菜机,挑选 .config 中勾选的菜,根据 Makefile 菜谱进行炒菜,一切顺利的话,一道道菜肴就做好了。
Kconfig
构建内核的第一步始终是配置。Kconfig 有助于内核高度模块化和定制化。Kconfig 为用户提供了许多配置目标:
其中,menuconfig 是这些目标中最受欢迎的一个。一些目标有 GUI (为了方便用户),而大多数没有。与 Kconfig 相关的工具和源代码主要位于 scripts/kconfig/ 下。这里有几个主程序,包括 conf
、mconf
和 nconf
。除了 conf
之外,每个都负责一个基于 GUI 的配置目标,因此,conf
处理大多数目标。
从逻辑上讲,Kconfig 的基础结构有两部分:一部分实现一种新语言来定义配置项(参见内核源代码下的 Kconfig 文件),另一部分解析 Kconfig 语言并处理配置操作。
大多数配置目标具有大致相同的内部过程(如下所示):
请注意,所有配置项都具有默认值。
第一步读取源代码根目录下的 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
文件中。
Kbuild
组件式构建,称为递归 make,是 make 管理大型项目的常用方法。Kbuild 是递归 make 的一个很好的例子。
通过将源文件划分为不同的模块/组件,每个组件都由其自己的 makefile 管理。当开始构建时,顶级 makefile 以正确的顺序调用每个组件的 makefile,构建组件,并将它们收集到最终的执行程序中。
.config.old
.config.old 为上一次的 .config 的内容
示例
$ tree
.
├── dinner.c
├── dinner.h
├── eat.c
├── include
│ ├── config
│ └── generated
├── Kconfig
├── Makefile
└── scripts
├── conf
└── mconf
Kconfig
mainmenu "Kbuild Test Configuration"
menu "EAT_WHATE"
config BREAKFAST
default y
tristate "have breakfast"
config LUNCH
default y
bool "have a good lunch"
config DINNER
bool "eat dinner"
help
this is a test
endmenu
Makefile
TARGET=eat
-include ./include/config/auto.conf
LDFLAGS= -I./include/generated
obj-y := eat.c
obj-$(CONFIG_DINNER) += dinner.c
all: $(TARGET)
$(TARGET): $(obj-y) FORCE
gcc $(LDFLAGS) -o $@ $(obj-y)
defconfig:
./scripts/conf Kconfig
./scripts/conf -s --silentoldconfig Kconfig
allyesconfig:
./scripts/conf -s --allyesconfig Kconfig
./scripts/conf -s --silentoldconfig Kconfig
allnoconfig:
./scripts/conf -s --allnoconfig Kconfig
./scripts/conf -s --silentoldconfig Kconfig
alldefconfig:
./scripts/conf -s --alldefconfig Kconfig
./scripts/conf -s --silentoldconfig Kconfig
menuconfig:
./scripts/mconf Kconfig
./scripts/conf -s --silentoldconfig Kconfig
clean:
-rm $(TARGET)
-rm ./include/config/* ./include/generated/*
-rm .config .config.old
PHONY +=FORCE
FORCE:
.PHONY: $(PHONY)
dinner.c
// dinner.c
#include <stdio.h>
void dinner(void)
printf("eat dinner\\n");
dinner.h
// dinner.h
void dinner(void);
eat.c
// eat.c
#include <stdio.h>
#include "autoconf.h"
#include "dinner.h"
void main()
#ifdef CONFIG_BREAKFAST
printf("have breakfast\\n");
#endif
#ifdef CONFIG_LUNCH
printf("have a good lunch\\n");
#endif
#ifdef CONFIG_DINNER
dinner();
#endif
conf 和 mconf 是从 kernel 源码目录 scripts/kconfig 中拷贝过来的
include、config、generated 目录要事先创建好
方式一
make menuconfig
保存后生成 .config
#
# Automatically generated file; DO NOT EDIT.
# Kbuild Test Configuration
#
#
# EAT_WHATE
#
CONFIG_BREAKFAST=y
CONFIG_LUNCH=y
# CONFIG_DINNER is not set
然后再执行 make
$ make
gcc -I./include/generated -o eat eat.c
运行
$ ./eat
have breakfast
have a good lunch
方式二
除了可以使用 make menuconfig 进行图形化界面配置,还可以使用 make defconfig 进行命令行界面配置
$ make defconfig
./scripts/conf Kconfig
*
* Kbuild Test Configuration
*
*
* EAT_WHATE
*
have breakfast (BREAKFAST) [Y/n] Y
have a good lunch (LUNCH) [Y/n] Y
eat dinner (DINNER) [N/y/?] Y
#
# configuration written to .config
#
./scripts/conf -s --silentoldconfig Kconfig
生成 .config
#
# Automatically generated file; DO NOT EDIT.
# Kbuild Test Configuration
#
#
# EAT_WHATE
#
CONFIG_BREAKFAST=y
CONFIG_LUNCH=y
CONFIG_DINNER=y
编译
$ make
gcc -I./include/generated -o eat eat.c dinner.c
运行
$ ./eat
have breakfast
have a good lunch
eat dinner
方式三
make allyesconfig && make
方式四
make allnoconfig && make
方式五
make alldefconfig && make
以上是关于Kconfig 和 Kbuild的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核Linux 内核源码根目录下的文件 ( .clang-format | COPYING | CREDITS | Kbuild | Kconfig | MAINTAINERS )