kconfig 和 config.in 语法 翻译

内核源码树的目录下都有两个文件Kconfig2.4版本是Config.in)和Makefile。分布到各目录的 Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(xconfig)时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文件中。在内核编译时,主 Makefile调用这个.config,就知道了用户的选择。

上面的内容说明了,Kconfig就是对应着内核的配置菜单。如果要想添加新的驱动到内核的源码中,可以修改Kconfig,这样就可以选择这个驱动,如果想使这个驱动被编译,要修改Makefile

对于kconfig的语法在https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt中做了详细的说明,在这里给出kconfig-language.txt的中文版。

在配置数据库的配置选项是以树的形式组织的:

   +- Code maturity level options

   |  +- Prompt for development and/or incomplete code/drivers

   +- General setup

   |  +- Networking support

   |  +- System V IPC

   |  +- BSD Process Accounting

   |  +- Sysctl support

   +- Loadable module support

   |  +- Enable loadable module support

   |      +- Set version information on all module symbols

   |      +- Kernel module loader

   +- ...

+- 代码成熟级别选项

|  +- 对于开发和/或不完整的代码/驱动 的提示

+-通用配置

|  +- 网络支持

|  +- System V 进程通信机制

|  +- BSD 程序计数器

|  +- Sysctl支持

+-可装载模块支持

|  +- 使能可装载模块支持

|     +- 在所有模块标记上设置版本信息

|     +- 内核模块装载

+-...

每个选项都有其自己的依赖关系。这些依赖关系决定了选项是否是可见的。父选项可见,子选项才能可见。

 

1. Menu entries

大多数的entry都定义了一个config选项,其它entry帮助组织它们。一个配置选项定义可以是下面的形式:

config MODVERSIONS

   bool "Set version information on all module symbols"

   depends MODULES

   help

      Usually, modules have to be recompiled whenever you switch to a new

      kernel. ...

每行都是以关键字开始,并可以接多个参数。"config" 为定义了一新的配置entry。下面的几行定义了该entity选项的属性。属性可以是该配置选项的类型,输入提示(input prompt),依赖关系,帮助信息和默认值。一配置选项可以用相同的名字定义多次,但每个定义只能有一个输入提示并且类型还不能冲突。

 

2. Menu attributes

一菜单选项可以有多个属性。并不要求这些属性可以用在任何地方(见语法)

类型定义:"bool"/"tristate"/"string"/"hex"/"int"

每个配置选项都必须指定类型。有两个基本类型:tristate 和 string,其他类型都是基于这两个基本类型。类型定义可以用输入提示,所以下面的两个例子是等价的:

(1)bool "Networking support"

(2)bool

     prompt "Networking support"

输入提示: "prompt" <prompt> ["if" <expr>]

每个菜单入口最多只能有一个展示给用户看的输入提示,可以使用“if”来表示输入提示的依赖性,这个依赖性是可选的。

 

- 默认值:"default" <expr> ["if" <expr>]

一个配置选项可以有任意多个默认值。如果存在多个默认值,只有第一个定义的默认值才是有效的。默认值可以定义在菜单入口的任何位置。这就意味着默认值可以在配置选项的其它地方再定义或者被之前的默认值定义给覆盖。

如果用户没有设置(通过上面的输入提示),配置选项的值就是默认值。如果可以显示输入提示的话,就会把默认值显示给用户,并可以让用户进行修改。

与输入提示一样,可以使用“if”来表示默认值的依赖性,这个依赖性是可选的。

 

- type definition + default value: "def_bool"/"def_tristate" <expr> ["if" <expr>]

这是一个类型定义加上一个默认值的速记符号。

如果使用依赖性,可以使用“if”来表示

 

- dependencies: “depends on” <expr>

为菜单选项定义一个依赖关系。如果有多个依赖关系,可使用&&隔开。依赖关系也可以应用到该菜单中所有的其它选项(同样接受if表达式),所以下面的两个例子是等价的:

bool "foo" if BAR

default y if BAR

and

depends on BAR

bool "foo"

default y

 

- reverse dependencies: “select <symbol>” [“if” <expr>]

一个正常的依赖项可以降低symbol的上限值,而反向依赖项则用来给一个symbol限定一个下限值。当前菜单symbol的值是当前可以设定的<symbol>最小值。如果<symbol>被选择了多次,那么它的值限定为最大的那一个。

只有booleantristate类型的symbol可以使用反向依赖。

注:应该非常小心使用反向依赖。反向依赖会给symbol强制赋一个值而不受正常依赖项的限制。滥用反向依赖会导致一个symbolF00被选择,即使F00的依赖项BAR没有被设置。一般情况下只有不可见的symbol和没有正向依赖项的symbol才使用反向依赖项。虽然这样限制了反向依赖的用途,但是从另一方面来说,这样阻止了大量的非法配置。

 

- limiting menu display: “visible if” <expr>

该属性只用在menu block中,如果条件为falsemenu block不显示给用户(尽管这样,其中包含的symbol仍可被其他symbol选择)。它类似与单个菜单entry的条件提示属性。默认visibletrue

 

- numerical ranges: “range” <symbol> <symbol> [“if” <expr>]

inthex类型的选项设置可能的输入值范围。用户只能输入大于等于第一个symbol,小于等于第二个symbol的值。

 

- help text: “help” or “---help---”

这个属性定义了一个帮助文本。帮助文本的结尾是根据缩进级别来决定的,这就意味着如果帮助文本中某一行相对于第一行有更小的缩进,那么这一行就是帮助文档的最后一行。

"---help---" 和 "help" 在实现的作用上没有区别,"---help---" 有助于将文件中的配置逻辑与给开发人员的提示分开。

 

- misc options: “option” <symbol>[=<value>]

各种不常见的选项的通过这个选项来定义,比如修改菜单入口的行为和配置symbol。下面这些配置当前是允许的:

 

-"defconfig_list"

这个选项定义了一系列默认入口,当使用默认配置时可以从这里寻找(当主.config文件不存在时会使用)

 

- “modules”

定义该symbolMODULES symbol,开启了所有配置symbol的第三种模块化状态。最多只有一个symbol可能设置“modules”选项。

 

- “env”=<value>

这个选项导入了一个环境变量到Kconfig中。环境变量就像是Kconfig中的一个默认值,但是它是从外部环境中导入的。正因为它从外部环境导入,所以赋值的这个时候它相对于正常的默认值来说是没有定义的。这个symbol当前没有导出到构建环境中(如果想要这样的话,可以通过另一个symbol导出)

 

- “allnoconfig_y”

当使用“allnoconfig”是,该symbol的值应该为y。用于隐藏其他symbolsymbol

 

3. Menu dependencies

依赖关系决定了菜单选项是否可见,也可以减少tristate的输入范围。tristate逻辑比boolean逻辑在表达式中用更多的状态(state)来表示模块的状态。依赖关系表达式的语法如下:

<expr> ::= <symbol>                             (1)

           <symbol> '=' <symbol>                (2)

           <symbol> '!=' <symbol>               (3)

           '(' <expr> ')'                       (4)

           '!' <expr>                           (5)

           <expr> '&&' <expr>                   (6)

           <expr> '||' <expr>                   (7)

 

表达式是以优先级的降序列出的。

(1)将一个symbol转换成表达式。Booleantristate symbol简单地转换成相应的表达式值。其它类型的symbol赋值‘n’。

(2)如果两个symbol的值相等,返回y,否则返回n

(3)如果两个symbol的值相等,返回n,否则返回y

(4)返回表达式的值,用于覆盖优先级。

(5)返回 (2-/expr/) 的结果。

(6)返回 min(/expr/,/expr/) 的结果。

(7)返回 max(/expr/,/expr/) 的结果。

一个表达式的值可以是'n''m''y'(或者是计算的结果 0,1,2)。当表达式的值为'm''y'的时候,菜单项才是可见的。

symbol有两种类型:不可变的和可变的。不可变的symbol是最普通的,由'config'语句定义。可变symbol由字母和下划线组成。

不可变的symbol只是表达式的一部分。经常用单引号或双引号括起来。在引号中,可以使用任何字符,使用引号要用转义字符'\'

 

4. Menu structure

菜单entry的位置在结构树中的定义有两种方式。第一种方式是明确地进行指定:

menu "Network device support"

depends on NET

 

config NETDEVICES

...

 

endmenu

“menu”“endmenu”块中的所有entry都是"Network device support"的子菜单。所有的子菜单选项都继承了父菜单的依赖关系,比如,"NET"的依赖关系就被加到了配置选项NETDEVICES的依赖列表中。

另一种就是通过分析依赖关系生成菜单的结构。如果菜单entry在一定程度上依赖于前面的entry,它就能成为该entry的子菜单。首先,前面的()symbol必须是依赖列表中的一部分并且它们中必须满足下面两个条件之一:

如果父选项为'n',子选项必须不可见。

如果父选项可见,子选项才能可见。

 

config MODULES

bool "Enable loadable module support"

 

config MODVERSIONS

bool "Set version information on all module symbols"

depends on MODULES

 

comment "module support disabled"

depends on !MODULES

 

MODVERSIONS 直接依赖于 MODULES,这意味着它只有当MODULES的值不是’n’的时候才是可见的。如果MODULES是可见的,那么comment也是可见的(MODULES的依赖关系也是comment依赖项的一部分)。

 

5. Kconfig syntax

这个配置文件描述了一系列的菜单entry,文件中的每一行都以一个关键字开头(除了帮助文本)。下面的关键字用来结束一个菜单entry

- config

- menuconfig

- choice/endchoice

- comment

- menu/endmenu

- if/endif

- source

前面5个也用来开始一个菜单entry的定义。

 

config:

       "config" <symbol>

       <config options>

定义一个配置symbol<symbol>,并且接受上面所说的任何属性作为选项。

 

menuconfig:

"menuconfig" <symbol>

<config options>

这个类似于上面所说的简单config entry,但是它给了前端一个提示:所有的子选项都应该作为一个单独的选项列表显示出来。

 

choices:

“choice” [symbol]

<choice options>

<choice block>

“endchoice”

该关键字定义了一组选择项,并且选项可以是前面描述的任何属性。选择只能是bool类型或tristate类型,并且布尔选择只允许一个单一的配置项被选中,三态选择还允许任何配置项被设置为“M”。这可以用在下面的情况:如果一个硬件存在多个驱动程序,并且只有一个驱动程序可以编译/加载到内核中,但所有的驱动程序可以编译成模块。

一个choice接受另外一个选项“optional”,允许将值设为’n’,并且不需要选择entry

如果一个choice没有关联的symbol,你就不能对该choice进行多重定义。如果一个symbolchoice关联,那么你可以在其他地方定义相同的choice

 

comment

“comment” <prompt>

<comment options>

这定义了一条在用户配置过程中显示的注释,同时会写入导出文件。它的选项options只能是依赖项。

 

 

menu:

"menu" <prompt>

<menu options>

<menu block>

"endmenu"

 

这定义了一个菜单块,具体情况请查看之前的“Menu structure”。它的选项options只能是依赖项并有“visible”属性。

 

if:

"if" <expr>

<if block>

"endif"

这定义了一个if块。依赖表达式<expr>将会追加到所有if ... endif 中的菜单选项中

 

source:

"source" <prompt>

这个选项读取特定配置文件,配置文件经常会被解析。

 

mainmenu:

"mainmenu" <prompt>

如果配置程序选择使用该项,那么它将会设置配置程序的标题栏。它应该放在配置的最顶端。

 

6. Kconfig hints

这是一个Kconfig提示的集合,大部分在初次看时都不是很明显,但确实很多Kconfig文件中的常用提示。

 

Adding common features and make the usage configurable

它是一个常见用法开实现和一些架构相关的功能。

推荐做法是:使用一个名字为HAVE_*的配置变量,该变量定义在一些常见的Kconfig文件中,并且被相关的架构选择。

一个典型的例子是通用IOMAP功能的实现:

我们将会在lib/Kconfig文件中看到:

# Generic IOMAP is used to ...

config HAVE_GENERIC_IOMAP

 

config GENERIC_IOMAP

depends on HAVE_GENERIC_IOMAP && FOO

 

lib/Makefile中,我们将看到:

obj-$(CONFIG_GENERIC_IOMAP) += iomap.o

 

对于每个使用通用IOMAP功能的架构,我们将看到:

config X86

select ...

select HAVE_GENERIC_IOMAP

select ...

 

注:我们使用已经存在的配置选项并且避免创建一个新的配置变量来选择HAVE_GENERIC_IOMAP

注:内部配置变量HAVE_GENERIC_IOMAP的使用是用来克服选择的限制的,选择限制将不管依赖关系强制配置选项值为y

依赖关系移动到symbol GENERIC_IOMAP,我们避免配置选项被强制赋给’y’值

 

Build as module only

为了限制一个组件只生成模块,限定它的配置选项为"depends on m".比如:

config FOO

depends on BAR && m

限制FOO生成一个模块 (=m) 或者关闭 (=n)

 

Kconfig recursive dependency limitations

如果你遇到了Kconfig error“recursive dependency detected” 检测到依赖关系递归,即循环依赖。Kconfig工具需要确保kconfig文件符合特定的配置要求。Kconfig必须要确定所有kconfig symbol的可能值,如果在两个或多个kconfig symbol间有循环依赖关系的话,这是不可能实现的。更多细节可参考下面的“Simple Kconfig recursive issue”小节。Kconfig没有递归依赖分辨性,这对写kconfig的人有一些启示。我们先解释一下问题存在的原因,然后提供一个Kconfig开发者带来的技术限制例子。希望尝试解决该限制的开发者,需要阅读下一个小节。

Simple Kconfig recursive issue

Read: Documentation/kbuild/Kconfig.recursion-issue-01

 

Test with:

make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig

 

Cumulative Kconfig recursive issue

Read: Documentation/kbuild/Kconfig.recursion-issue-02

 

Test with:

make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig

 

Practical solutions to kconfig recursive issue

遇到kconfig recursive issue的开发者有三个处理方式:

(1)移除任何不必要的“select FOO”或者“depends on FOO”

(2)匹配依赖关系语义:

i. 交换所有“select foo”“depends on foo”

ii. 交换所有“depends on foo”“select foo”

 

Future kconfig work

Kconfig的工作在澄清语义和评估使用a full SAT solver这两个区域很受欢迎。在开启更复杂的依赖关系映射或查询上a full SAT solver是可取的,同时可能解决recursive dependency issues

 

Semantics of Kconfig

Kconfig用途很广,Linux只是其中之一。研究表明kconfig12个项目中使用到。

在工具在实际评估依赖关系时,良好定义的语义是非常有帮助的。

 

[0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf

[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf

[2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf

[3] http://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf

 

Full SAT solver for Kconfig

感兴趣的开发者可访问: http://kernelnewbies.org/KernelProjects/kconfig-sat

 

[0] http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf

[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf

[2] https://cados.cs.fau.de

[3] https://vamos.cs.fau.de

[4] https://undertaker.cs.fau.de

[5] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf

 

 

 

 

 

 

 

linux2.6.x的配置文件kconfig语法linux在2.6版本以后将配置文件由原来的config.in 改为kconfig,对于kconfig语法在/Documentation/kbuild/kconfig-language.txt中做了详细的说 明,在这里给出kconfig-language.txt的中文版。 介绍 ---- 在配置数据库的配置选项是以树的形式组织的: +- Code maturity level options | +- Prompt for development and/or incomplete code/drivers +- General setup | +- Networking support | +- System V IPC | +- BSD Process Accounting | +- Sysctl support +- Loadable module support | +- Enable loadable module support | +- Set version information on all module symbols | +- Kernel module loader +- ... 每个选项都有其自己的依赖关系。这些依赖关系决定了选项是否是可见的。父选项可见,子选项才能可见。 菜单选项 -------- 大多数的选项都定义了一个配置选项,其它选项则有助于对它们进行组织。(原文:Most entries define a config option, all other entries help to organize them.)一个配置选项定义可以是下面 的形式: config MODVERSIONS bool "Set version information on all module symbols" depends MODULES help Usually, modules have to be recompiled whenever you switch to a new kernel. ... 每行都是以关键字开始,并可以接多个参数。"config" 为定义了一新的配置选项。下面的几行定义了该配置 选项的属性。属性可以是该配置选项的类型,输入提示(input prompt),依赖关系,帮助信息和默认值。一 配置选项可以用相同的名字定义多次,但每个定义只能有一个输入提示并且类型还不能冲突。 菜单属性 -------- 一菜单选项可以有多个属性。并不要求这些属性可以用在任何地方(见语法)。 - 类型定义:"bool"/"tristate"/"string"/"hex"/"int" 每个配置选项都必须指定类型。有两个基本类型:tristate 和 string,其他类型都是基于这两个基本 类型。类型定义可以用输入提示,所以下面的两个例子是等价的: bool "Networking support" 和 bool prompt "Networking support" - 输入提示: "prompt" ["if" ] 每个菜单选项最多只能有一个显示给用户的输入提示。可以用 "if" 来表示该提示的依赖关系,当然这是 可选的。 - 默认值:"default" ["if" ] 一个配置选项可以有任意多个默认值。如果有多个默认值,那么只有第一个被定义的值是可用的。默认值并 不是只限于应用在定义他们的菜单选项。这就意味着默认值可以定义在任何地方或被更早的定义覆盖。 如果用户没有设置(通过上面的输入提示),配置选项的值就是默认值。如果可以显示输入提示的话,就会把 默认值显示给用户,并可以让用户进行修改。 默认值的依赖关系可以用 "if" 添加。(可选项) - 依赖关系:"depends on"/"requires" 为一菜单选项定义依赖关系。如果定义了多个依赖关系,它们之间用 '&&' 间隔。依赖关系也可以应用到 该菜单中所有的其它选项(同样接受一if表达式),所以下面的两个例子是等价的: bool "foo" if BAR default y if BAR and depends on BAR bool "foo" default y - 反向依赖关系:"select" ["if" ] 尽管普通的依赖关系可以降低一选项的上限,反向依赖能将这一限制降的更低。当前菜单选项的值是symbol 的最小值。如果symbol被选择了多次,上限就是其中的最大值。 反向依赖只能用在 boolean 或 tristate 选项上。 - 数据范围:"range" ["if" ] 为int和hex类型的选项设置可以接受输入值范围。用户只能输入大于等于第一个symbol,小于等于第二个 symbol的值。 - 帮助信息: "help" or "---help---" 定义一帮助信息。帮助信息的结束就由缩进的水平决定的,这也就意味着信息是在第一个比帮助信息开始行 的缩进小的行结束。 "---help---" 和 "help" 在实现的作用上没有区别,"---help---" 有助于将文件中的配置逻辑与 给开发人员的提示分开。 菜单依赖关系 ------------ 依赖关系决定了菜单选项是否可见,也可以减少tristate的输入范围。tristate逻辑比boolean逻辑在表 达式中用更多的状态(state)来表示模块的状态。依赖关系表达式的语法如下: ::= (1) '=' (2) '!=' (3) '(' ')' (4) '!' (5) '&&' (6) '||' (7) 表达式是以优先级的降序列出的。 (1) 将symbol赋给表达式。boolean和tristate类型的symbol直接赋给表达式。所有其它类型的symbol 都赋 'n'。 (2) 如果两个symbol相等,返回'y',否则为'n'。 (3) 如果两个symbol相等,返回'n',否则为'y'。 (4) 返回表达式的值。用于改变优先级。 (5) 返回 (2-/expr/) 的结果。 (6) 返回 min(/expr/,/expr/) 的结果。 (7) 返回 max(/expr/,/expr/) 的结果。 一个表达式的值可以是'n','m'或'y'(或者是计算的结果 0,1,2)。当表达式的值为'm'或'y'的时候,菜 单项才是可见的。 symbol有两种类型:不可变的和可变的。不可变的symbol是最普通的,由'config'语句定义,完全由数字 、字母和下划线组成(alphanumeric characters or underscores)。 不可变的symbol只是表达式的一部分。经常用单引号或双引号括起来。在引号中,可以使用任何字符,使用引 号要用转义字符'\'。 菜单结构 -------- 菜单在树中的位置可由两种方法决定。第一种可以是这样: menu "Network device support" depends NET config NETDEVICES ... endmenu 所有的在"menu" ... "endmenu" 之间都是"Network device support"的子菜单。所有的子菜单选项 都继承了父菜单的依赖关系,比如,"NET"的依赖关系就被加到了配置选项NETDEVICES的依赖列表中。 还有就是通过分析依赖关系生成菜单的结构。如果菜单选项在一定程度上依赖于前面的选项,它就能成为该选 项的子菜单。首先,前面的(父)选项必须是依赖列表中的一部分并且它们中必须有满足下面两个条件的选项: - 如果父选项为'n',子选项必须不可见。 - 如果父选项可见,子选项才能可见。 config MODULES bool "Enable loadable module support" config MODVERSIONS bool "Set version information on all module symbols" depends MODULES comment "module support disabled" depends !MODULES MODVERSIONS 直接依赖 MODULES,这就意味着如果MODULES不为'n',该选项才可见。换句话说,当 MODULES可见时,选项才可见(MODULES的(空)依赖关系也是选项依赖关系的一部分)。 Kconfig 语法 ------------ 配置文件描述了菜单选项,每行都是以一关键字开头(除了帮助信息)。下面的关键字结束一菜单选项: - config - menuconfig - choice/endchoice - comment - menu/endmenu - if/endif - source 前5个同样可以用在菜单选项定义的开始。 config: "config" 定义了一配置选项 并且可以接受任何前面介绍的属性。 menuconfig: "menuconfig" 此关键字和前面的关键字很相似,但它在前面的基础上要求所有的子选项作为独立的行显示。(This is similar to the simple config entry above, but it also gives a hint to front ends, that all suboptions should be displayed as a separate list of options.) choices: "choice" "endchoice" 该关键字定义了一组选择项,并且选项可以是前面描述的任何属性。尽管boolean只允许选择一个配置选项, tristate可以抒多个配置选项设为'm',但选项只能是boolean或tristate类型。这可以在一个硬件有多 个驱动的情况下使用,最终只有一个驱动被编译进/加载到内核,,但所有的驱动都可以编译成模块。 选项可以接受的另一个选项是"optional",这样选项就被设置为'n',没有被选中的。 comment: "comment" 这里定义了在配置过程中显示给用户的注释,该注释还将写进输出文件中。唯一可用的可选项是依赖关系。 menu: "menu" "endmenu" 这里定义了一个菜单,详细信息请看前面的"菜单结构"。唯一可用的可选项是依赖关系。 if: "if" "endif" 这里定义了if结构。依赖关系被加到所有在if ... endif 中的菜单选项中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值