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/ 下。这里有几个主程序,包括 confmconfnconf。除了 conf 之外,每个都负责一个基于 GUI 的配置目标,因此,conf 处理大多数目标。
从逻辑上讲,Kconfig 的基础结构有两部分:一部分实现一种新语言来定义配置项(参见内核源代码下的 Kconfig 文件),另一部分解析 Kconfig 语言并处理配置操作。
大多数配置目标具有大致相同的内部过程(如下所示):

请注意,所有配置项都具有默认值。
第一步读取源代码根目录下的 Kconfig 文件,构建初始配置数据库;然后它根据如下优先级读取现有配置文件来更新初始数据库:

  1. .config
  2. /lib/modules/$(shell,uname -r)/.config
  3. /etc/kernel-config
  4. /boot/config-$(shell,uname -r)
  5. ARCH_DEFCONFIG
  6. 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的主要内容,如果未能解决你的问题,请参考以下文章

Kconfig 和 Kbuild

Linux 内核Linux 内核源码根目录下的文件 ( .clang-format | COPYING | CREDITS | Kbuild | Kconfig | MAINTAINERS )

如何从Kbuild Kconfig文件中的另一个选项中选择字符串选项的值?

kconfig反向依赖

kernel Makefile Kconfig说明

Kconfig SourceCode GDB调试 *****