• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    dinner.c

    // dinner.c
    #include 
    
    void dinner(void)
    {
        printf("eat dinner\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    dinner.h

    // dinner.h
    void dinner(void);
    
    • 1
    • 2

    eat.c

    // eat.c
    #include 
    #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
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    conf 和 mconf 是从 kernel 源码目录 scripts/kconfig 中拷贝过来的
    include、config、generated 目录要事先创建好

    方式一

    make menuconfig
    
    • 1

    在这里插入图片描述
    保存后生成 .config

    #
    # Automatically generated file; DO NOT EDIT.
    # Kbuild Test Configuration
    #
    
    #
    # EAT_WHATE
    #
    CONFIG_BREAKFAST=y
    CONFIG_LUNCH=y
    # CONFIG_DINNER is not set
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    然后再执行 make

    $ make
    gcc -I./include/generated -o eat eat.c
    
    • 1
    • 2

    运行

    $ ./eat 
    have breakfast
    have a good lunch
    
    • 1
    • 2
    • 3

    方式二

    除了可以使用 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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    生成 .config

    #
    # Automatically generated file; DO NOT EDIT.
    # Kbuild Test Configuration
    #
    
    #
    # EAT_WHATE
    #
    CONFIG_BREAKFAST=y
    CONFIG_LUNCH=y
    CONFIG_DINNER=y
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    编译

    $ make
    gcc -I./include/generated -o eat eat.c dinner.c
    
    • 1
    • 2

    运行

    $ ./eat 
    have breakfast
    have a good lunch
    eat dinner
    
    • 1
    • 2
    • 3
    • 4

    方式三

    make allyesconfig && make
    
    • 1

    方式四

    make allnoconfig && make
    
    • 1

    方式五

    make alldefconfig && make
    
    • 1
  • 相关阅读:
    八大排序总结篇
    svo2.0 svo pro 编译运行
    1447_TC275 DataSheet阅读笔记8_电气特性
    数据分析案例-基于随机森林模型探究电商网站推销商品的影响因素
    查阅相关文献描述CN,SMC,EMCI,LMCI,AD五类疾病的早期干预和诊断标准|2022数维杯国赛C题
    感知SOTA模型
    蛋白结构合理性评估软件-PROCHECK的安装与使用
    动态规划常见实例详解
    TikTok生态圈【6.27跨境日报】TikTok夏季大甩卖利用现场活动中的游戏化
    区间重叠问题
  • 原文地址:https://blog.csdn.net/lyndon_li/article/details/126455766