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**

 




相关推荐

一、概述 makefile文件包含一些规则,告诉make工具编译哪些文件以及怎样编译这些文件。 配置文件.config 是在进行内核配置后生成的中间产物。 是通过make menuconfi

mainline 、longterm、stable、linux-next、snapshot这些名词,都是linux kernel sou

__CONCAT,连接两个参数,##用于粘贴两个参数,#用于替换参数 #define __CONCAT(a, b) a ##

这个宏定义,可以在内核源码的script目录查看Makefile.lib文件。 # These flags are

<img src="http://123.56.17.129:2177/images/linux_kernel.png" alt="" /

在编程中,一个符号symbol是一个程序的创建块,它是一个变量名或一个函数名。 内核符号表(Kernel Symbol Table) 内核并不使用符号名。它是通过

在Kernel_path/Makefile中可以查看到 # SPDX-License-Identifier: GPL

一、概述 在 Linux 内核中,printk 是一个类似于用户空间 C 语言中的 printf 函数的内核级日志记录功能。它用于内核代码中输出调试信息到控制台或系统日志。printk 可以在几乎任何

一、概述  在日常工作中,经常会需要对内核进行Debug、或者进行优化工作。一些简单的问题,可以通过dmesg/printk查看,优化借助一些工具进行。 但是当问题逻辑复杂,优化面宽泛的时候,往往无从

一、概述 在 Linux 内核编程中,asmlinkage 是一个关键字,用于告诉编译器该函数将通过堆栈而不是寄存器接收所有的参数。这个宏主要用于那些需要从用户空间通过系统调用接口调用的函数。在系统调