原作者:Greg Kroah-Hartman
翻译整理:土豆丝624
原文链接:www.linuxjournal.com/article/656…
说明:文章版权归原作者所有
预警:文中有些知识陈旧了,但大体的原则还在,可作为入门学习阅读。转载说明出处,谢谢。
Linux内核构建的过程分为两部分:配置内核选项和根据这些选项编译源代码。在内核2.5版本之前,在每一个子文件都有一个Config.in文件来决定配置,还有一个帮助文档,放在Documentation/Configure.help。描述构建过程的语言类似于shell脚本,它来控制向当前用户显示哪些配置选项。
本来这一切都很合理,但是慢慢的内核中各种不同的配置以及超出了这门语言能够合理处理的范围,所以在内核2.5.45版本中,Roman Zippel重写了配置语言。配置语言放在了内核的主线分支上。新的配置语言更灵活更强大,为单个驱动打补丁包更容易,而不用担心和Configue.help有冲突.
并且,在2.5系列的版本中,Kai Germaschewski和其他的Kbuild开发人员重写了内核中makefile的逻辑,使得基于选项编译内核更加容易。这篇文章描述了makefile的格式和2.5内核的配置文件,以及如何在构建过程中添加新的驱动。
配置内核
为了配置不同的内核选项,可以运行命令行或基于图形界面的配置工具。可以使用Make Config来运行命令行的配置工具,它会按照顺序提示用户应该选择哪些配置选项(见图1)。更为流行的方式是使用Make menuconfig的方式(见图2)。第三种方式是使用Make xconfig运行图形界面的配置工具。该配置工具是基于Qt开发的。
图表 1make config
图表 2 Make menuconfig
图表 3 Make xconfig
当内核配置工具运行时,在i386平台上它会读取位于arch/i386/Kconfig目录下的主要配置文件。其他的架构在它们的主要目录下也有配置文件。主配置文件也包含在kernel目录下子目录中的其他配置文件。这些配置文件也包含其他需要的配置文件。比如,arch/i386/Kconfig包含下面
source "sound/Kconfig"
用来从这个文件中读取信息。然后Sound/Kconfig包含很多其他的文件。
source "sound/core/Kconfig"
source "sound/drivers/Kconfig"
source "sound/isa/Kconfig"
source "sound/pci/Kconfig"
source "sound/ppc/Kconfig"
source "sound/arm/Kconfig"
source "sound/usb/Kconfig"
sound/usb/Kconfig这个文件描述了ALSA USB驱动的所有信息
# ALSA USB drivers
menu "ALSA USB devices"
depends on SND!=n && USB!=n
config SND_USB_AUDIO
tristate "USB Audio/MIDI driver"
depends on SND && USB
help
Say 'Y' or 'M' to include support for
USB audio and USB MIDI devices.
Endmenu
字符#表示文件的注释。在这个字符后面的文字是不会被配置工具读取的,它用来描述这个文件的目的和应该怎么做。Menu[wt1] 和 endmenu命令告诉配置工具这是一个新的菜单级别或者在某些配置编程中这是新的一屏。在menu那一行,菜单的名字应该写在双引号里面。以这个文件为例,这个菜单的名字叫做“ALSA USB”。
可以控制菜单或配置选线是否显示。在本例中,USB配置菜单只有在同时选择了CONFIG_SND和CONFIG_USB才会显示,这些是由depends on SND!=n && USB!=n来控制的。为了减少打字的数量,所有的配置选项都自动以CONFIG开头,而这个在配置语言里是没有的。合法的配置选项如下:
- y—打开这个选项
- n—关闭这个选项
- m—编译成一个模块
如果CONFIG_SND和CONFIG_USB都设置成n(意思是他们会被编译进内核或编译成一个模块),就是显示CONFIG_SND_USB_AUDIO这个选项。这个选项用”tristate”表示它可以设置三个值中的其中一个。显示给用户的文本就是“USB Audio/MIDI driver”。
tristate "USB Audio/MIDI driver"
描述一个配置变量的合法值如下
- bool—该变量可以设置为y或n
- tristate—该变量可以设置为y,n,m.
- int—该变量可以设置为任何数字
这个配置选项和菜单选项遵循相同的逻辑。CONFIG_SND_USB_AUDIO依赖于CONFIG_SND和CONFIG_USB这两个选项,意味着如果这些选项中的其中一个设置成一个模块,那么CONFIG_SND_USB_AUDIO也应该设置为一个模块。如果这两个配置选项都关闭(意思是这两个选项都设置为n),那么这个选项就不会显示。如果这两个选项都设置为y,那么该选项可以选择y,n,m。所有的这些用一行命令就可以简单定义
depends on SND && USB
在内核代码中,可以看见配置变量(比如上面提到的CONFIG_SND_USB_AUDIO),所以代码就可以测试它或任何其他内核配置选项的存在。但是在a.c文件中使用#ifdef是违反内核编程指南的,关于这个在另一篇文章中提到过(www.linuxjournal.com/article/578…)。因此在头文件中不要使用#ifdef,保证c文件干净且易于阅读。
之前,所有的帮助说明都在一个大的Configuration.help文件中。现在帮助说明放在了Kconfig文件中依赖行的后面。另起一行,以help或---help---开头,紧跟着的是多行帮助文本,它们从帮助行缩进了两个空格。
新增配置选项
新增配置选项,只要在已存在的Kconfig文件中新增一行,或者在相关配置项的相同为止。举个例子,如果新增一个为ALSA声音系统新写的USB声音驱动,会先进入sound/usb 目录,新增sound/usb/Kconfig文件。新的设备驱动控制FooBar USB音响驱动。除了CONFIG_SND_USB_AUDIO配置项,它还依赖于CONFIG_SND和CONFIG_USB这两个选项是否打开,因为新的驱动要是用那个驱动的一些功能。新的配置项应在放在SND_USB_AUDIO后面,但是要在endmenu命令之前。如下所示
config SND_USB_FOOBAR
tristate "USB FooBar speaker device driver"
depends SND_USB_AUDIO
help
Say Y here if you want to use FooBar USB
speaker device.
This code is also available as a module
(= code which can be inserted in and
removed from the running kernel whenever
you want). The module will be called
usbfoobar.o.
当选择了SND_USB_AUDIO的时候,这个配置项就会显示
图表 4新增设备驱动
编译内核
编译内核的时候,所有单个的makefile会链接到一起形成一个大的makefile来编译内核。单个的makefile不像标准的makefile,它遵循内核构建过程中需要的唯一的特定的格式,无法单独运行。Makefile根据打开的配置项,仅构建必须的文件。举个例子,内核2.5.5中drivers/usb/misc/Makefile长这个样子
#
# Makefile for the rest of the USB drivers
# (the ones that don't fit into any other
# categories)
#
obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
obj-$(CONFIG_USB_BRLVGER) += brlvger.o
obj-$(CONFIG_USB_EMI26) += emi26.o
obj-$(CONFIG_USB_LCD) += usblcd.o
obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o
obj-$(CONFIG_USB_TEST) += usbtest.o
obj-$(CONFIG_USB_TIGL) += tiglusb.o
obj-$(CONFIG_USB_USS720) += uss720.o
speedtch-objs := speedtouch.o atmsar.o
这行
obj-$(CONFIG_USB_LCD) += usblcd.o
和这行
speedtch-objs := speedtouch.o atmsar.o
第一行控制是否构建speedtch模块。如果需要构建,这行表示它是否被编译进内核或编译成一个标准的模块。第二行解释了speedtouch.c和atmsar.c文件会被编译成.o文件然后一起链接到speedtouch.o模块
在老的内核中,如果一个文件导出符号,需要在内核的makefile中显示说明。在2.5和之后的内核版本中,已经不必要提了。
在构建过程中增加新的驱动
在内核构建过程中,如果驱动包含在单个文件中,需要单独新增一行。用之前的FooBar USB音响驱动距离,新增行如下:
obj-$(CONFIG_SND_USB_FOOBAR) += usbfoobar.o
这行会增加到sound/usb/Makefile中
如果驱动包含在两个文件中,比如foobar1.c和foobar2.c,需要在新增额外的一行,如下:
usbfoobar-objs := foobar1.o foobar2.o
结论
在内核2.5版本中内核的配置和构建过程比之前的版本要更简单灵活。感谢Roman Zippel和Kai Germaschewski做出的贡献让内核开发者能够更专注于写代码,而不用担心内核构建过程的复杂性。
了解更多关于Kconfig语言的知识,指路www.kernel.org/doc/html/la…