0%

linux kernel kconfig

0x00 前言

在编译linux kernel遇到诸多不如意,比如,我想研究这个模块,想单独编译,但是,改了那个模块的makefile也没有起作用;我想内核帮我编译某一个模块,改完 .config之后的他也没有编译,这就很郁闷了。那么如何顺心如意的控制的kernel的编译选项的呢。这里以编译vivid驱动为例深入理解kernel的编译选项。

0x01 kconfig

参考:

简单来说就是make menuconfig 之后产生的界面就是各级kconfig文件产生的,具体的介绍参考 linux源码 Documentation/kbuild/kconfig-language.txt

0x00 实例分析kconfig的语法

我们先来看一下kernel的顶级kconfig

1
2
3
4
5
6
7
8
9
10
11
12
# SPDX-License-Identifier: GPL-2.0
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.rst.
#
mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration"

comment "Compiler: $(CC_VERSION_TEXT)"

source "scripts/Kconfig.include"
以下省略
......

根据显示的效果可以推测 mainmenu是标识主菜单后面是字符串是显示的文字,commit是提示信息,也是把后面的字符串输出,source就是引入次级目录的kconfig文件

下面我们看driver的下面的kconfig文件

1
2
3
4
5
6
7
8
9
10
11
12
# SPDX-License-Identifier: GPL-2.0
menu "Device Drivers"

# Keep I/O buses first

source "drivers/amba/Kconfig"

....

source "drivers/counter/Kconfig"

endmenu

menu就是次级菜单,名字是 Device Drivers

这样的话,我们设置一个驱动的编译选项就更好定位了,由于我们的vivid的驱动在media目录下,所以,看media目录的kconfig目录

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
config CEC_CORE
tristate

config CEC_NOTIFIER
bool

config CEC_PIN
bool

source "drivers/media/rc/Kconfig"

menuconfig MEDIA_SUPPORT
tristate "Multimedia support"
depends on HAS_IOMEM
help
If you want to use Webcams, Video grabber devices and/or TV devices
enable this option and other options below.
Additional info and docs are available on the web at
<https://linuxtv.org>

if MEDIA_SUPPORT

comment "Multimedia core support"

......

config MEDIA_CAMERA_SUPPORT
bool "Cameras/video grabbers support"
help
Enable support for webcams and video grabbers.

Say Y when you have a webcam or a video capture grabber board.

这里config就是具体一条config选项了,然后他有五种类型

  • bool

  • tristate

  • string

  • hex

  • int

    tristate是有三个值一般标识模块 [*] 内建 [M] 模块 [ ]移除 然后depends on就是依赖选项,

    之后在看platform下的kconfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    menuconfig V4L_TEST_DRIVERS
    bool "Media test drivers"
    depends on MEDIA_CAMERA_SUPPORT

    if V4L_TEST_DRIVERS

    source "drivers/media/platform/vimc/Kconfig"

    source "drivers/media/platform/vivid/Kconfig"

    config VIDEO_VIM2M
    tristate "Virtual Memory-to-Memory Driver"
    depends on VIDEO_DEV && VIDEO_V4L2
    select VIDEOBUF2_VMALLOC
    select V4L2_MEM2MEM_DEV
    help
    This is a virtual test device for the memory-to-memory driver
    framework.

    source "drivers/media/platform/vicodec/Kconfig"

    endif #V4L_TEST_DRIVERS

我们要设置vivid下的kconfig的话,依赖于media目录下的MEDIA_CAMERA_SUPPORT选项,所以,选中就可以了,之后就看vivid下的kconfig

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
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_VIVID
tristate "Virtual Video Test Driver"
depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB
depends on HAS_DMA
select FONT_SUPPORT
select FONT_8x16
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
select VIDEO_V4L2_TPG
help
Enables a virtual video driver. This driver emulates a webcam,
TV, S-Video and HDMI capture hardware, including VBI support for
the SDTV inputs. Also video output, VBI output, radio receivers,
transmitters and software defined radio capture is emulated.

It is highly configurable and is ideal for testing applications.
Error injection is supported to test rare errors that are hard
to reproduce in real hardware.

Say Y here if you want to test video apps or debug V4L devices.
When in doubt, say N.

config VIDEO_VIVID_CEC
bool "Enable CEC emulation support"
depends on VIDEO_VIVID
select CEC_CORE
help
When selected the vivid module will emulate the optional
HDMI CEC feature.

config VIDEO_VIVID_MAX_DEVS
int "Maximum number of devices"
depends on VIDEO_VIVID
default "64"
help
This allows you to specify the maximum number of devices supported
by the vivid driver.

依赖很多,之后在看vivid的makefile

1
2
3
4
5
6
7
8
9
10
11
# SPDX-License-Identifier: GPL-2.0
vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \
vivid-osd.o
ifeq ($(CONFIG_VIDEO_VIVID_CEC),y)
vivid-objs += vivid-cec.o
endif

obj-$(CONFIG_VIDEO_VIVID) += vivid.o

我们看可以看到最后一句

1
obj-$(CONFIG_VIDEO_VIVID) += vivid.o

我们都知道obj-m是编译模块,所以,我们需要逐级设置config才是正道,如果你只是改.config的文件

1
CONFIG_VIDEO_VIVID=m

是没有任何效果,因为上级依赖没有设置,所以这个选项就会被忽略。

0x02 总结

了解kconfig文件之后,就可以解释之前好多kernel编译的玄学问题,这个故事告诉我们,知道原理才能前行,那么问题来了,你怎么知道要了解的是什么原理,这是一个值得探究的问题,这个问题解决的话,学习效率就会高的超乎想象。