Linux 驱动开发 六十五:《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
	+- ...

每个条目都有自己的依赖项。这些依赖项用于确定条目的可见性。任何子条目只有在其父条目可见的情况下才可见

二、菜单项

大多数条目定义了一个配置选项;所有其他条目都有助于组织它们。单个配置选项定义如下:

config MODVERSIONS
	bool "Set version information on all module symbols"
	depends on MODULES
	help
	  Usually, modules have to be recompiled whenever you switch to a new
	  kernel.  ...

每一行都以一个关键字开头,后跟多个参数“config” 启动一个配置条目。以下行定义此配置选项的属性。属性可以是配置选项的类型输入提示依赖项帮助文本默认值。配置选项可以使用相同的名称多次定义,但每个定义只能有一个输入提示,并且类型不得冲突

三、菜单属性

一个菜单项可以有许多属性。并不是所有的规则都适用于任何地方(参见语法)。

1、类型属性

  • type definition: "bool"/"tristate"/"string"/"hex"/"int"

选项都必须有一个类型。只有两种基本类型tristate(三态)和 string(字符串);其他类型是基于这两种。类型定义可选地接受输入提示符,因此这两个示例是等价的:

	bool "Networking support"
	and
	bool
	prompt "Networking support"

2、输入提示

  • input prompt: "prompt" <prompt> ["if" <expr>]

每个菜单项最多只能有一个提示符,用于显示给用户。可以使用 if 添加仅针对此提示的依赖项。

3、默认值

  • default value: "default" <expr> ["if" <expr>]

配置选项可以有任意数量默认值。如果有多个默认值可见,则只有第一个定义默认值活动的。默认值不局限于定义它们的菜单项。这意味着默认值可以在其他地方定义,也可以被早期的定义覆盖。

如果用户没有设置其他值(通过上面的输入提示),则默认值只分配给配置符号。如果可以看到输入提示,则默认值将显示给用户,用户可以覆盖该值。

可选地,可以使用 if 只添加此默认值的依赖项。

4、类型定义+默认值

  • "def_bool"/"def_tristate" <expr> ["if" <expr>]

这是类型定义加值的速记符号。可以使用 if 为这个默认值添加可选的依赖性。

5、依赖

  • dependencies: "depends on" <expr>

这为这个菜单项定义了一个依赖项。如果定义了多个依赖项,则用 '&&' 连接它们。依赖项应用于该菜单项中的所有其他选项(也接受 if 表达式),因此这两个示例是等价的:

	bool "foo" if BAR
	default y if BAR
	and
	depends on BAR
	bool "foo"
	default y

6、反向依赖关系

  • reverse dependencies: "select" <symbol> ["if" <expr>]

正常依赖减少符号的上限(见下文),反向依赖可用于强制另一个符号的下限。当前菜单符号的值用作可设置的最小值符号。如果多次选择符号,则将限制设置为最大的选择。反向依赖关系只能与布尔或三态符号一起使用。

注:Select 应该小心使用。Select 将强制将符号转换为一个值,而不访问依赖项。通过滥用 select,您可以选择一个符号 FOO,即使 FOO 依赖于未设置的 BAR。一般情况下,只选择不可见的符号(任何地方都没有提示)和没有依赖关系的符号。这一方面限制了它的有效性,另一方面又避免了所有的非法配置。

7、限制菜单显示

  • limiting menu display: "visible if" <expr>

这个属性只适用于菜单块,如果条件为 false,菜单块就不会显示给用户(但是,包含在那里的符号仍然可以由其他符号选择)。它类似于单个菜单项的条件提示属性。默认值为 true

8、数值范围

  • numerical ranges: "range" <symbol> <symbol> ["if" <expr>]

这允许限制整数和十六进制符号可能输入值的范围。用户只能输入大于等于第一个符号且小于等于第二个符号的值。

9、帮助信息

  • help text: "help" or "---help---"

这将定义帮助文本。帮助文本的结尾由缩进级别决定,这意味着它以第一行结束,该行的缩进比帮助文本的第一行小。“---help---”“help” 在行为上没有区别,“---help---” 用于帮助在视觉上将配置逻辑与文档中的帮助分开,以帮助开发人员。

10、misc选项

可以通过这个选项语法定义各种不太常用的选项,它可以修改菜单项及其配置符号的行为。这些选择目前是可行的:

1、defconfig_list

这将声明一个默认条目列表,该列表可用于查找默认配置(当主 .config 尚不存在时使用)。

2、modules

这将声明该符号作为 MODULES 符号使用,从而为所有配置符号启用第三种模块化状态。最多一个符号可以有 modules 选项集。

3、env

这会将环境变量导入到 Kconfig 中。它的行为类似于默认值,除了值来自于环境之外,这也意味着此时将其与正常默认值混合时的行为是未定义的。该符号目前没有导出回构建环境(如果需要这样做,可以通过另一个符号完成)。

4、allnoconfig_y

这将声明该符号在使用 allnoconfig 时应该具有 y 值。用于隐藏其他符号的符号。

四、菜单依赖关系

依赖关系定义菜单项的可见性,还可以减少三态符号的输入范围。表达式中使用的三态逻辑使用比普通布尔逻辑多一种状态来表达模块状态。依赖项表达式具有以下语法:

<expr> ::= <symbol>                             (1)
           <symbol> '=' <symbol>                (2)
           <symbol> '!=' <symbol>               (3)
           '(' <expr> ')'                       (4)
           '!' <expr>                           (5)
           <expr> '&&' <expr>                   (6)
           <expr> '||' <expr>                   (7)

表达式按优先级递减顺序列出。

1、将符号转换为表达式。布尔和三态符号被简单地转换为各自的表达式值。所有其他符号类型的结果都是 'n'

2、如果两个符号的值相等,则返回 “y”,否则返回 “n”

3、如果两个符号的值相等,则返回 'n',否则返回 'y'

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

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

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

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

表达式的值可以是 'n''m' 或’y’(计算时分别为 012)。当一个菜单项的表达式计算为 'm''y' 时,它就会变得可见。

有两种类型的符号:常量和非恒定符号。非常量符号是最常见的符号,并使用 “config” 语句定义。非常量符号完全由字母数字字符或下划线组成。

常量符号只是表达式的一部分。常量符号始终用单引号或双引号括起来。在引号中,允许任何其他字符,并且可以使用 “\” 对引号进行转义。

五、菜单结构

菜单项在树中的位置以两种方式确定。首先,可以显式指定它:

menu "Network device support"
	depends on NET

config NETDEVICES
	...

endmenu

"menu" ... "endmenu" 块中的所有条目成为网络设备支持的子菜单。所有子项都继承了菜单项的依赖项,例如,这意味着依赖项 NET 被添加到配置选项 NETDEVICES 的依赖项列表中。

生成菜单结构的另一种方法是通过分析依赖项来完成。如果菜单项以某种方式依赖于前一个条目,则可以将其作为其子菜单。首先,上一个(父)符号必须是依赖项列表的一部分,然后必须满足以下两个条件之一:

  • 如果父条目设置为 '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

MODVERSION 直接依赖于 MODULES,这意味着只有当 MODULES'n' 不同时,它才可见。另一方面,当 MODULES 可见时,注释始终可见(MODULES 的(空)依赖项也是注释依赖项的一部分)。

六、Kconfig语法

配置文件描述了一系列菜单项,其中每一行都以一个关键字开始(帮助文本除外)。以下关键字结束菜单项:

  • config
  • menuconfig
  • choice/endchoice
  • comment
  • menu/endmenu
  • if/endif
  • source

前五个也开始定义菜单项。

config:

	"config" <symbol>
	<config options>

这定义了一个配置符号符号,并接受上述任何属性作为选项。

menuconfig:
	"menuconfig" <symbol>
	<config options>

这类似于上面的简单配置条目,但它也给前端一个提示,所有子选项都应该显示为单独的选项列表。

choices:

	"choice" [symbol]
	<choice options>
	<choice block>
	"endchoice"

这将定义一个选项组,并接受上述任何属性作为选项。选项只能是布尔或三态类型,而布尔选择只允许选择单个配置条目,三态选择还允许将任意数量的配置条目设置为 “m”。如果存在单个硬件的多个驱动进程,并且只能将单个驱动进程编译/加载到内核中,但所有驱动进程都可以编译为模块,则可以使用此方法。

一个选项接受另一个可选选项,它允许将选项设置为 'n',并且不需要选择任何条目。

如果没有 [符号] 与选项相关联,则不能对该选项有多个定义。如果 [符号] 与选项相关联,则可以在另一个位置定义相同的选项(即具有相同的条目)。

comment:

	"comment" <prompt>
	<comment options>

这将定义一个注释,该注释在配置过程中显示给用户,并且还将返回到输出文件中。唯一可能的选择是依赖关系。

menu:

	"menu" <prompt>
	<menu options>
	<menu block>
	"endmenu"

这定义了一个菜单块,参见上面的菜单结构了解更多信息。唯一可能的选项是依赖项和可见属性。

if:

	"if" <expr>
	<if block>
	"endif"

这定义了一个 if 块。依赖关系表达式将追加到所有包含的菜单项。

source:

	"source" <prompt>

它读取指定的配置文件。这个文件总是被解析。

mainmenu:

	"mainmenu" <prompt>

如果配置程序选择使用它,这将设置配置程序的标题栏。它应该放在配置的顶部,在任何其他语句之前。

七、Kconfig 提示

这是 Kconfig 提示的集合,其中大部分乍一看并不明显,其中大部分已成为几个 Kconfig 文档中的习语。

1、添加常用功能并使用法可配置。

实现与某些体系结构(但不是全部)相关的特性/功能是一种常见的习惯用法。建议的方法是使用名为 HAVE_* 的配置变量,该变量在通用 Kconfig 文档中定义并由相关体系结构选择。

一个例子是通用的 IOMAP 功能。

我们会在 lib/Kconfig 中看到:

# Generic IOMAP is used to ...
config HAVE_GENERIC_IOMAP

config GENERIC_IOMAP
	depends on HAVE_GENERIC_IOMAP && FOO

And in lib/Makefile we would see:
obj-$(CONFIG_GENERIC_IOMAP) += iomap.o

For each architecture using the generic IOMAP functionality we would see:

config X86
	select ...
	select HAVE_GENERIC_IOMAP
	select ...

注意:我们使用现有的配置选项,避免创建新的配置变量来选择 HAVE_GENERIC_IOMAP

注意:使用内部配置变量 HAVE_GENERIC_IOMAP,引入它是为了克服选择的限制,无论依赖关系如何,都会强制配置选项为 “y”

依赖项被移动到符号 GENERIC_IOMAP,我们避免了选择强制符号等于 “y” 的情况。

2、仅作为模块构建

要将组件构建限制为仅模块,请使用“依赖于 m”限定其配置符号。 例如:

config FOO
	depends on BAR && m

FOO 限制为模块 (=m) 或禁用 (=n)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值