Coder
分类: 嵌入式
2010-04-12 13:10:23
Linux 2.6内核的配置系统
Linux 2.6内核的配置系统由以下三个部分组成:
Makefile:分布在Linux内核源代码中的Makefile,定义Linux内核的编译规则。
配置文件(Kconfig):给用户提供配置选择的功能。
配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供字符界面和图形界面)。这些配置工具都是用脚本语言编写的,如Tcl/TK、Perl等。
使用make config、make
menuconfig等命令后,会生成一个.config配置文件(隐含在顶层Makefile中),记录那些部分被编译入内核,那些部分被编译为内核模块。
运行make menuconfig后,配置工具会首先分析与体系结构对应的arch/xxx/Kocnfig文件(xxx即为传入的ARCH参数),arch/xxx/Kconfig文件中除本身包含一些与体系结构相关的配置项和配置菜单意外,还通过source语句引入了一系列Kconfig文件,而这些Kconfig文件有可能再次通过source引入下一层的Kconfig,配置工具依据这些Kconfig包含的菜单和项目即可描绘出一个分层结构。
用户运行make zImage、make
bzImage等生成映像的命令时,先检索顶层Makefile(在arch/xxx目录下的Makefile为顶层Makefile补充体系结构相关的信息),顶层Makefile完成两个主要的任务:产生内核映像文件和内核模块,为了达到刺目的,顶层Makefile会递归地进入内核的各个子目录中,分别调用位于这些子目录中的Makefile(子目录中的Makefile属于kbuild类型的Makefile,记录编译目标)。进入那些子目录则取决于内核的配置(.config)。
Kconfig和Makefile
在Linux内核中增加程序需要完成以下3个工作:
将编写的源代码复制到Linux源代码的相应目录中。
在目录的Kconfig文件中增加新源代码对应项目的编译配置选项。
在目录的Makefile文件中增加对新项目的编译项目。
如S
1、在linux-
2、在同一目录下的Kconfig文件中包含RTC_DRV_S
config RTC_DRV_S
tristate "Samsung S
depends on ARCH_S
help
RTC (Realtime Clock) driver for the clock inbuilt into the
Samsung S
interrupt rates from 1Hz to 64Hz for user programs, and
wakeup from Alarm.
The driver currently supports the common features on all the
S
and S
This driver can also be build as a module. If so, the module
will
be called rtc-s
3、在同目录下的Makefile中关于RTC_DRV_S
obj-$(CONFIG_RTC_DRV_S
Makfile
Kbuild Makefile的语法包括如下几个方面(在内核目录Documentation\kbuild下的makefiles.txt文件中有相当详细清晰地信息。)
(1)、目标定义
用来定义哪些文件将被编译,一些特殊的编译选项,和任何需要递归进入的子目录。
Example:
obj-y
+= foo.o
This tells kbuild
that there is one object in that directory, named foo.o. foo.o will be built
from foo.c or foo.S. If foo.o shall
be built as a module, the variable obj-m is used.
Therefore the
following pattern is often used:
Example:
obj-$(CONFIG_FOO)
+= foo.o
$(CONFIG_FOO)
evaluates to either y (for built-in) or m (for module).If CONFIG_FOO is neither
y nor m, then the file will not be compiled nor
linked.
除了obj-形式的目标外,还有lib-y
library库、hostprogs-y主机程序等目标,但是基本都应用在特定的目录和场合下。
(2)、如果一个模块有多个文件组成,这时候应采用模块名加-objs后缀或者-y后缀的形式来定义模块的组成文件。
Example:
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
注:该Kbuild Makefile所在的目录中不能再包含和模块名相同的源文件如ext2.c/ext2.S。
或者写成-objs的形式
obj-$(CONFIG_ISDN)
+= isdn.o
isdn-objs
:= isdn_net_lib.o isdn_v110.o isdn_common.o
(3)、目录层次的迭代
Example:
obj-$(CONFIG_EXT2_FS)
+= ext2/
当CONFIG_EXT2_FS的值为y或m是,kbuild将会把ext2目录列入向下迭代的目标中,具体ext2目录下的文件是要作为模块编译还是连接入内核则有ext2目录下的Makefile文件的内容决定。
Kconfig
内核配置脚本本件的语法(在内核目录Documentation\kbuild下的kconfig-language.txt文件中有相当详细清晰地信息。)
(1)、菜单入口
大多数的入口定义一个配置选项。如:
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”开始一个新的配置入口,接下来的几行定义这个配置选项的属性。属性可能是配置选项的类型、输入提示、依赖、帮助文本和默认值。一个配置选项可以用同一个名字多次定义,但是每一个定义只能仅有一个输入提示,而且类型一定不能冲突。
每一个配置选项都必须指定一个类型,类项包括"bool"/"tristate"/"string"/"hex"/"int",其中有两个基本类型:tristate and string,其他的类型都基于这两种基本类型。在类型定义后可以进这输入提示,也可以使用prompt,所以下面两个例子是等价的:
bool
"Networking support"
和
bool
prompt
"Networking support"
输入提示的格式: "prompt"
其中可选的if用来表示提示的依赖关系
默认值的格式: "default"
一个配置选项可以有任意多个默认值,在这种情况下,只有第一个定义的值是有效地。如果用户不设置对应的选项,配置选项的值就是默认值。
依赖的格式: "depends on"
如果定义了多个依赖,他们之间用“&&”间隔,依赖关系也可以应用到所有的其他选项中(这些选项同样可接受if表达式),如洗面两个例子等价:
bool
"foo" if BAR
default y
if BAR
and
depends on
BAR
bool
"foo"
default y
反向依赖关系格式: "select"
Depends能限定一个symbol的上限,而select能限定一个symbol的下限,如果symbol反向依赖于多个对象,则它的下限是这些对象的最大值。
数值范围格式: "range"
数值范围允许用整型或十六进制值来限制可能的输入值的范围。用户只能输入大于第一个symbol而小于第二个symbol的指。
help 文本: "help" or "---help---"
定义一个help 文本,help文本的结束用缩进来决定。Help文本在第一个和help文本第一个文本行具有相似缩进的行上结束。
"---help---"和 "help" 在行为上没有区别,
"---help---"用来把配置逻辑与给开发人员的提示分开。
依赖表达式有如下的语法:
'('
'!'
Expressions are
listed in decreasing order of precedence.
(1) Convert the
symbol into an expression. Boolean and tristate symbols
are simply converted into the respective
expression values. All
other symbol types result in 'n'.
(2) If the values
of both symbols are equal, it returns 'y',
otherwise 'n'.
(3) If the values
of both symbols are equal, it returns 'n',
otherwise 'y'.
(4) Returns the
value of the expression. Used to override precedence.
(5) Returns the
result of (2-/expr/).
(6) Returns the
result of min(/expr/, /expr/).
(7) Returns the
result of max(/expr/, /expr/).
Menuconfig关键字的作用与config类似,但它在config的基础上要求所有的子选项作为独立的行显示。
(2)菜单结构
菜单入口在菜单树结构中的位置可有两种方法决定。首先可以显示的指定:
menu "Network device support"
depends on
NET
config NETDEVICES
...
endmenu
所有处于“menu”和“endmenu”之间的菜单入口都会成为“Network device support”的子菜单,而且所有子菜单都会继承父菜单的依赖关系。比如,这意味着依赖“NET”会被添加到配置选项NETDEVICES的依赖列表中。
另外一种方式是通过分析依赖关系从而生成菜单结构。如果菜单选项在一定程度上依赖于前面的选项,那么它就能成为该选项的子菜单。如果父选项为“N”,则子选项不可见;如果复选项为“Y”或“M”,则子选项可见。如:
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’的时候它才可见。
除此之外,Kconfig中还可能使用“choice…endchoice”、“comment”、“if…endif”这样的语法结构。其中“choice…endchoice”的结构如下所示:
"choice"
"endchoice"
它定义一个选择群,其接受的选项(choice option)可以是前面描述的任何属性。选择群还可以接受的另一个选项“optional”,这样菜单入口就被设置为“N”,没有被选中。
最后补充说明一点
关于内核的配置和构建,在内核源代码目录Documentation\kbuild下有几个文件来对这个系统进行说明,总共为6个文件:
00-INDEX
-info on the kernel build process
kbuild.txt
- developer information on kbuild
kconfig.txt
- usage help for make *config
kconfig-language.txt
- specification of Config Language, the
language in Kconfig files
makefiles.txt
- developer information for linux kernel
makefiles
modules.txt
-
how to
build modules and to install them
其实这些文件对这整个系统的说明相当的简洁清晰明了。所以也难怪,尽管这个系统相当有意思,但实际上介绍这个系统的文章却并不多。因为内核的文档对这一部分真的是说的相当明白了。不仅有说明,而且有大量的例子来解释。