Kbuild1

Kbuild: the Linux Kernel Build System
Linux 内核采用统一的代码基础,却可以在大到服务器,小到微型的嵌入式设备上使用,其高度可裁剪、可定制化的构建在业界都是一流的。Linux 在 2.6 版本之后采取了 Kbuild 系统进行系统的配置和构建。在新的构建系统下,首先编译系统会读取 Linux 内核顶层的 Makefile,然后根据读到的内容第二次读取 Kbuild Makefile 来编译内核。

从配置和编译 Linux Kernel 所使用的命令来看,Linux Kernel 的配置和编译体系总体上还是基于 GNU Make 的,没有另外使用其他的编译工具(比如 Scons、CMake等)。但 Linux Kernel 实现了 KconfigKbuild,用于辅助内核的配置和编译。Kconfig,顾名思义就是 Linux内核的配置(Kernel config),Kbuild 系统需要与 Kconfig 配合使用。

长篇的描述网上已经很多了,这里描述一下如何搭建和使用一个简要的 Kbuild 系统。

搭建Kbuild2

The Linux Kernel Build System has four main components:

Config symbols: compilation options that can be used to compile code conditionally
in source files and to decide which objects to include in a kernel image or its modules.

Kconfig files: define each config symbol and its attributes, such as its type, description and dependencies.
Programs that generate an option menu tree (for example, make menuconfig) read the menu entries from these files.

.config file: stores each config symbol's selected value. You can edit this file manually or use one of the many
make configuration targets, such as menuconfig and xconfig, that call specialized programs to build a tree-like
menu and automatically update (and create) the .config file for you.

Makefiles: normal GNU makefiles that describe the relationship between source files and the commands
needed to generate each make target, such as kernel images and modules.

我们先不管抽象的定义,搭建的时候会有相应的文件对应到上面四个 components。

目录结构

创建一个目录,结构如下,里面有两个文件夹,其中 include下有 configgenerated 两个文件夹,这几个文件夹 (include config generated) 都是自动生成的,其中的文件也都是自动生成的。实际发现必须建立 include config generated 目录才能生成成功,否则会报 *** Error during update of the configuration. 的错误。scripts 文件夹下的两个可执行文件拷贝自 Linux 源码目录下的./scripts/kconfig/,比较新版本的 Linux 可能 confmconf 在构建过程才会生成,因此需要先构建一下 Linux 才行。
在这里插入图片描述
剩余需要手动添加的文件为 hello.c, Kconifg, Makefile, myprint.c, myprint.h

示例源码

// hello.c
#include <stdio.h>
#include "autoconf.h"
#include "myprint.h"

void main()
{
#ifdef CONFIG_ARM
	printf("ARM PLAT!\n");
#endif

#ifdef CONFIG_x86
	printf("x86 PLAT!\n");
#endif

#ifdef CONFIG_MYPRINT
	myprint();
#endif
}

// myprint.c
#include <stdio.h>

void myprint(void)
{
	printf("This is mytest!\n");
}

// myprint.h
void myprint(void);

通过源码中的条件编译选项,我们可以控制哪些代码逻辑生效,Kbuild 系统可以自动生成上述条件编译宏,这些宏默认位于 autoconf.h 里。

Kconfig文件

使用 Kbuild 通常是这个过程。

1. make *config,比如 menuconfig, defconfig
2. make 程序会读取目录树下的 Kconfig 文件,以 GUI 或者命令行的方式获得用户的配置,这一步会生成一个 .config 文件。
3. 运行 Kbuild 提供的 conf 程序,生成 config 和 generated 目录下的各个文件。
4. 用户使用的时候包含其中的 autoconf.h 即可。

Kconfig 的语法可以参考 linux 目录下 Documentation/kbuild/kconfig-language.txt

mainmenu "Kbuild Test Configuration"

menu "TEST_KBUILD"
	config ARM
	tristate "enable gcc arm"
	
	config x86
	bool "enable gcc x86"
	
	config MYPRINT
	bool "enable myprint.c"
help
	this is a test
endmenu

Makefile

Makefile 里可以使用宏 CONFIG_XXX 来控制是否包含相应的目标。这些宏包含在 auto.conf 里,由 Kbuild 系统自动生成,可以在 Makefile 里包含这个头文件。

TARGET=hello

# 这一句在 make defconfig / menuconfig 生成相应的文件后再添加
# 添加在这里只是为了展示 Makefile 可以通过 CONFIG_MYPRINT 来控制文件编译与否
include ./include/config/auto.conf

LDFLAGS= -I./include/generated

obj-y := hello.c
obj-$(CONFIG_MYPRINT) += myprint.c

all: $(TARGET)
$(TARGET): $(obj-y) FORCE
	gcc $(LDFLAGS) -o $@ $(obj-y)
	echo $@
	echo $(obj-y)
defconfig:
	./scripts/conf Kconfig
	./scripts/conf -s --syncconfig Kconfig
menuconfig:
	./scripts/mconf Kconfig
	./scripts/conf -s --syncconfig Kconfig
clean:
	rm $(TARGET)

PHONY +=FORCE
FORCE:

.PHONY: $(PHONY)

运行 make defconfig

在这里插入图片描述
配置写到了 .config 文件中,内容如下。

#
# Automatically generated file; DO NOT EDIT.
# Kbuild Test Configuration
#

#
# TEST_KBUILD
#
CONFIG_ARM=y
CONFIG_x86=y
# CONFIG_MYPRINT is not set

include/config/auto.conf 文件内容和 .config 内容并无二致。把不是 y 的以及冗余的信息删除了而已。

#
# Automatically generated file; DO NOT EDIT.
# Kbuild Test Configuration
#
CONFIG_x86=y
CONFIG_ARM=y

include/generated/autoconf.h 文件内容如下。这个文件实际上是 ./conf --syncconfig Kconfig 生成的,并且名字和存放的位置可以通过环境变量 KCONFIG_AUTOHEADER 来指定。默认是在当前目录下的 include/generated/autoconf.h。如可以通过这个命令指定生成的文件为 kconfig.hKCONFIG_AUTOHEADER=kconfig.h ./conf --syncconfig Kconfig,如此一来 include 目录下将没有 generated 目录。

/*
 *
 * Automatically generated file; DO NOT EDIT.
 * Kbuild Test Configuration
 *
 */
#define CONFIG_x86 1
#define CONFIG_ARM 1

conf 其他命令选项

./conf: Kconfig file missing
Usage: ./conf [-s] [option] <kconfig-file>
[option] is _one_ of the following:
  --listnewconfig         List new options
  --helpnewconfig         List new options and help text
  --oldaskconfig          Start a new configuration using a line-oriented program
  --oldconfig             Update a configuration using a provided .config as base
  --syncconfig            Similar to oldconfig but generates configuration in
                          include/{generated/,config/}
  --olddefconfig          Same as oldconfig but sets new symbols to their default value
  --defconfig <file>      New config with default defined in <file>
  --savedefconfig <file>  Save the minimal current configuration to <file>
  --allnoconfig           New config where all options are answered with no
  --allyesconfig          New config where all options are answered with yes
  --allmodconfig          New config where all options are answered with mod
  --alldefconfig          New config with all symbols set to default
  --randconfig            New config with random answer to all options
  --yes2modconfig         Change answers from yes to mod if possible
  --mod2yesconfig         Change answers from mod to yes if possible

总结

总结一下 Kbuild 系统包含的四个 components。

  • Config symbols: CONFIG_XXX,由 Kconfig 文件描述。最后生成源码可用的 autoconf.h
  • Kconfig files: Kconfig 文件,描述了有哪些选项及其依赖等。
  • .config file: .config,由 make menuconfig 等生成的文件,里面列出了各选项的取值。
  • Makefiles: Makefile,描述待构建目标及其依赖、命令等。

  1. https://blog.csdn.net/wxywxywxy110/article/details/78049798 ↩︎

  2. https://www.linuxjournal.com/content/kbuild-linux-kernel-build-system ↩︎

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐