Kbuild.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),依赖关系,帮助信息和默认值。一配置选项可以用相同的名字定义多次,但每个定义只能有一个输入提示并且类型还不能冲突。
Config 后边的字符串作用?

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

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

bool
prompt "Networking support"
-输入提示: "prompt" <prompt> ["if" <expr>]
每个菜单选项最多只能有一个显示给用户的输入提示。可以用 "if"来表示该提示的依赖关系,当然这是可选的。
它会显示在make menuconfig中供选择,有什么作用?
-默认值:"default" <expr> ["if" <expr>]
一个配置选项可以有任意多个默认值。如果有多个默认值,那么只有第一个被定义的值是可用的。默认值并不是只限于应用在定义他们的菜单选项。这就意味着默认值可以定义在任何地方或被更早的定义覆盖。
如果用户没有设置(通过上面的输入提示),配置选项的值就是默认值。如果可以显示输入提示的话,就会把默认值显示给用户,并可以让用户进行修改。
默认值的依赖关系可以用 "if"添加。(可选项)
该模块编译的默认值
-依赖关系:"depends on"/"requires" <expr>
为一菜单选项定义依赖关系。如果定义了多个依赖关系,它们之间用 '&&'间隔。依赖关系也可以应用到该菜单中所有的其它选项(同样接受一if表达式),所以下面的两个例子是等价的:
干嘛的?
bool "foo" if BAR
default y if BAR
and
depends on BAR
bool "foo"
default y
-反向依赖关系:"select" <symbol> ["if" <expr>]
尽管普通的依赖关系可以降低一选项的上限,反向依赖能将这一限制降的更低。当前菜单选项的值是symbol
的最小值。如果symbol被选择了多次,上限就是其中的最大值。
反向依赖只能用在 boolean或 tristate选项上。

-数据范围:"range" <symbol> <symbol> ["if" <expr>]
为int和hex类型的选项设置可以接受输入值范围。用户只能输入大于等于第一个symbol,小于等于第二个
symbol的值。
-帮助信息: "help" or "---help---"
定义一帮助信息。帮助信息的结束就由缩进的水平决定的,这也就意味着信息是在第一个比帮助信息开始行
的缩进小的行结束。
"---help---"和 "help"在实现的作用上没有区别,"---help---"有助于将文件中的配置逻辑与
给开发人员的提示分开。


菜单依赖关系
依赖关系决定了菜单选项是否可见,也可以减少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赋给表达式。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" <symbol>
<config options>
定义了一配置选项 <symbol>并且可以接受任何前面介绍的属性。
menuconfig:
"menuconfig" <symbol>
<config options>
此关键字和前面的关键字很相似,但它在前面的基础上要求所有的子选项作为独立的行显示。(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"
<choice options>
<choice block>
"endchoice"

该关键字定义了一组选择项,并且选项可以是前面描述的任何属性。尽管boolean只允许选择一个配置选项,
tristate可以抒多个配置选项设为'm',但选项只能是boolean或tristate类型。这可以在一个硬件有多
个驱动的情况下使用,最终只有一个驱动被编译进/加载到内核,,但所有的驱动都可以编译成模块。
选项可以接受的另一个选项是"optional",这样选项就被设置为'n',没有被选中的。
comment:
"comment" <prompt>
<comment options>
这里定义了在配置过程中显示给用户的注释,该注释还将写进输出文件中。唯一可用的可选项是依赖关系。
menu:
"menu" <prompt>
<menu options>
<menu block>
"endmenu"

这里定义了一个菜单,详细信息请看前面的"菜单结构"。唯一可用的可选项是依赖关系。

if:
"if" <expr>
<if block>
"endif"
这里定义了if结构。依赖关系<expr>被加到所有在if ... endif中的菜单选项中


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

上面的内容说明了,Kconfig就是对应着内核的配置菜单。假如要想添加新的驱动到内核的源码中,能够修改Kconfig,这样就能够选择这个驱动,假如想使这个驱动被编译,要修改Makefile。所以,添加新的驱动时需要修改的文档有两种(注意不只是两个)
*Kconfig
*Makefile

---------------------------------------------------------------------------------------------
Kconfig
先了解一下Kconfig的语法:
一个典型的内核配置菜单如下:
menu "Network device support"
config NETDEVICES
        bool "Enable Net Devices"
        depends on NET
        default y
       help
               This is help desciption。
...
Endmenu
Menu后边的字符串会出现在make menuconfig中成为相应目录下的菜单
包含在menu/endmenu中的内容会成为Network device support的子菜单。每一个子菜单项都是由config来定义的。congfig下方的那些bool、depends on、default、help等为config的属性,用于定义该菜单项的类型、依赖项、默认值、帮助信息等。

2. 补充说明一下类型定义部分:
每个config菜单项都要有类型定义: bool布尔类型、 tristate三态(内建、模块、移除)、string字符串、 hex十六进制、 integer整型。
例如:
config HELLO_MODULE
bool "hello test module"
bool 类型的只能选中或不选中,显示为[ ]; tristate类型的菜单项多了编译成内核模块的选项,显示为< > , 假如选择编译成内核模块,则会在.config中生成一个 CONFIG_HELLO_MODULE=m的配置,假如选择内建,就是直接编译成内核影响,就会在.config中生成一个 CONFIG_HELLO_MODULE=y的配置. hex十六进制类型显示为( )。
3. 目录层次迭代
在Kconfig中有类似语句:source "drivers/usb/Kconfig"
用来包含(或嵌套)新的Kconfig文件,这样便可以使各个目录管理各自的配置内容,使不必把那些配置都写在同一个文件里,方便修改和管理。
----------------------------------------------------------------------------------------------
              

 

开发详解中有一个新增驱动代码目录和子目录的例子,很好的!P61

五、DIY:向内核添加自己的程序
A.在Linux内核中增加自己的程序步骤(注意这里只是程序文件):
1.将编写的源代码复制到Linux内核源代码的相应目录中。
2.在目录的Kconfig文件中增加新源代码对应项目的编译配置选项
3.在目录的Makefile文件中增加对新源代码的编译条目。
B.在Linux内核drivers/目录中增加目录和子目录步骤:
1.所加目录为daiq,文件如下:
[daiq@localhost daiq]$ tree
.
|-- Kconfig
|-- Makefile
|-- led
|   |-- Kconfig
|   |-- Makefile
|   `-- led.c
`-- test.c

#注意此时各个目录中的Makefile和Kconfig文件是空的
2.在新增的相应目录添加Kconfig和Makefile文件,上面的目录中已经添加。
3.修改新增目录的父目录的Kconfig和Makefile文件,以便新增的Kconfig和
Makefile能被引用。向父目录中的Makefile添加:
 obj-y                           += daiq/
表示在编译过程中包含子目录daiq目录。然后修改Kconfig文件,添加:
source “drivers/daiq/Kconfig”
表示在配置时引用子目录daiq中的配置文件Kconfig。
4.实际上,要让drivers/daiq/Kconfig有效,要在arch/arm/Kconfig文件中添加:
source “drivers/daiq/Kconfig”
父目录drivers/Kconfig的修改可以不要。

5.经过上面一步,内核就可以找到所加的目录daiq了,然后就是编辑各个目录中的Makefile和Kconfig文件,在你添加的目录daiq中的Makefile加入:
  obj-$(CONFIG_TEST) += test.o #因为在daiq目录中要编译test.c文件
     #所以会根据CONFIG_TEST来决定编译选项
    obj-y += led/#编译daiq目录中的子目录led
 然后Kconfig文件是:

menu "DaiQ device support"   #在make menuconfig时要显示的菜单入口                                       
config DAIQ_TEST
 bool "Test"
 help
   DaiQ device support
source "drivers/daiq/led/Kconfig"
endmenu

注意:menu和endmenu的前后要加回车,不然make menuconfig的时候会出错。

再看led目录下的Makefile和Kconfig:
Makefile为文件:
obj-$(CONFIG_LED)+=led.o
Kconfig文件:
 config LED
      tristate “led support”

5.现在可以make menuconfig来配置添加自己目录daiq的驱动了!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值