linux内核配置Word格式.docx
- 文档编号:22174766
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:15
- 大小:25KB
linux内核配置Word格式.docx
《linux内核配置Word格式.docx》由会员分享,可在线阅读,更多相关《linux内核配置Word格式.docx(15页珍藏版)》请在冰豆网上搜索。
顶层Makefile,是整个内核配置、编译的总体控制文件。
2..config:
内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果(如makeconfig)。
3.arch/*/Makefile:
位于各种CPU体系目录下的Makefile,如arch/arm/Makefile,是针对特定平台的Makefile。
4.各个子目录下的Makefile:
比如drivers/Makefile,负责所在子目录下源代码的管理。
5.Rules.make:
规则文件,被所有的Makefile使用。
用户通过makeconfig配置后,产生了.config。
顶层Makefile读入.config中的配置选择。
顶层Makefile有两个主要的任务:
产生vmlinux文件和内核模块(module)。
为了达到此目的,顶层Makefile递归的进入到内核的各个子目录中,分别调用位于这些子目录中的Makefile。
至于到底进入哪些子目录,取决于内核的配置。
在顶层Makefile中,有一句:
includearch/$(ARCH)/Makefile,包含了特定CPU体系结构下的Makefile,这个Makefile中包含了平台相关的信息。
位于各个子目录下的Makefile同样也根据.config给出的配置信息,构造出当前配置下需要的源文件列表,并在文件的最后有include$(TOPDIR)/Rules.make。
Rules.make文件起着非常重要的作用,它定义了所有Makefile共用的编译规则。
比如,如果需要将本目录下所有的c程序编译成汇编代码,需要在Makefile中有以下的编译规则:
%.s:
%.c
$(CC)$(CFLAGS)-S$<
-o$@
有很多子目录下都有同样的要求,就需要在各自的Makefile中包含此编译规则,这会比较麻烦。
而Linux内核中则把此类的编译规则统一放置到Rules.make中,并在各自的Makefile中包含进了Rules.make(includeRules.make),这样就避免了在多个Makefile中重复同样的规则。
对于上面的例子,在Rules.make中对应的规则为:
$(CC)$(CFLAGS)$(EXTRA_CFLAGS)$(CFLAGS_$(*F))$(CFLAGS_$@)-S$<
2.2Makefile中的变量
顶层Makefile定义并向环境中输出了许多变量,为各个子目录下的Makefile传递一些信息。
有些变量,比如SUBDIRS,不仅在顶层Makefile中定义并且赋初值,而且在arch/*/Makefile还作了扩充。
常用的变量有以下几类:
1)版本信息
版本信息有:
VERSION,PATCHLEVEL,SUBLEVEL,EXTRAVERSION,KERNELRELEASE。
版本信息定义了当前内核的版本,比如VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它们共同构成内核的发行版本KERNELRELEASE:
2.4.18-rmk7
2)CPU体系结构:
ARCH
在顶层Makefile的开头,用ARCH定义目标CPU的体系结构,比如ARCH:
=arm等。
许多子目录的Makefile中,要根据ARCH的定义选择编译源文件的列表。
3)路径信息:
TOPDIR,SUBDIRS
TOPDIR定义了Linux内核源代码所在的根目录。
例如,各个子目录下的Makefile通过$(TOPDIR)/Rules.make就可以找到Rules.make的位置。
SUBDIRS定义了一个目录列表,在编译内核或模块时,顶层Makefile就是根据SUBDIRS来决定进入哪些子目录。
SUBDIRS的值取决于内核的配置,在顶层Makefile中SUBDIRS赋值为kerneldriversmmfsnetipclib;
根据内核的配置情况,在arch/*/Makefile中扩充了SUBDIRS的值,参见4)中的例子。
4)内核组成信息:
HEAD,CORE_FILES,NETWORKS,DRIVERS,LIBS
Linux内核文件vmlinux是由以下规则产生的:
vmlinux:
$(CONFIGURATION)init/main.oinit/version.olinuxsubdirs
$(LD)$(LINKFLAGS)$(HEAD)init/main.oinit/version.o\
--start-group\
$(CORE_FILES)\
$(DRIVERS)\
$(NETWORKS)\
$(LIBS)\
--end-group\
-ovmlinux
可以看出,vmlinux是由HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS和LIBS组成的。
这些变量(如HEAD)都是用来定义连接生成vmlinux的目标文件和库文件列表。
其中,HEAD在arch/*/Makefile中定义,用来确定被最先链接进vmlinux的文件列表。
比如,对于ARM系列的CPU,HEAD定义为:
HEAD:
=arch/arm/kernel/head-$(PROCESSOR).o\
arch/arm/kernel/init_task.o
表明head-$(PROCESSOR).o和init_task.o需要最先被链接到vmlinux中。
PROCESSOR为armv或armo,取决于目标CPU。
CORE_FILES,NETWORK,DRIVERS和LIBS在顶层Makefile中定义,并且由arch/*/Makefile根据需要进行扩充。
CORE_FILES对应着内核的核心文件,有kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,这些是组成内核最为重要的文件。
同时,arch/arm/Makefile对CORE_FILES进行了扩充:
#arch/arm/Makefile
#Ifwehaveamachine-specificdirectory,thenincludeitinthebuild.
MACHDIR:
=arch/arm/mach-$(MACHINE)
ifeq($(MACHDIR),$(wildcard$(MACHDIR)))
SUBDIRS+=$(MACHDIR)
CORE_FILES:
=$(MACHDIR)/$(MACHINE).o$(CORE_FILES)
endif
SUBDIRS+=arch/arm/kernelarch/arm/mmarch/arm/libarch/arm/nwfpe
=arch/arm/kernel/kernel.oarch/arm/mm/mm.o$(CORE_FILES)
LIBS:
=arch/arm/lib/lib.a$(LIBS)
5)编译信息:
CPP,CC,AS,LD,AR,CFLAGS,LINKFLAGS
在Rules.make中定义的是编译的通用规则,具体到特定的场合,需要明确给出编译环境,编译环境就是在以上的变量中定义的。
针对交叉编译的要求,定义了CROSS_COMPILE。
比如:
CROSS_COMPILE=arm-linux-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
......
CROSS_COMPILE定义了交叉编译器前缀arm-linux-,表明所有的交叉编译工具都是以arm-linux-开头的,所以在各个交叉编译器工具之前,都加入了$(CROSS_COMPILE),以组成一个完整的交叉编译工具文件名,比如arm-linux-gcc。
CFLAGS定义了传递给C编译器的参数。
LINKFLAGS是链接生成vmlinux时,由链接器使用的参数。
LINKFLAGS在arm/*/Makefile中定义,比如:
LINKFLAGS:
=-p-X-Tarch/arm/vmlinux.lds
6)配置变量CONFIG_*
.config文件中有许多的配置变量等式,用来说明用户配置的结果。
例如CONFIG_MODULES=y表明用户选择了Linux内核的模块功能。
.config被顶层Makefile包含后,就形成许多的配置变量,每个配置变量具有确定的值:
y表示本编译选项对应的内核代码被静态编译进Linux内核;
m表示本编译选项对应的内核代码被编译成模块;
n表示不选择此编译选项;
如果根本就没有选择,那么配置变量的值为空。
2.3Rules.make变量
前面讲过,Rules.make是编译规则文件,所有的Makefile中都会包括Rules.make。
Rules.make文件定义了许多变量,最为重要是那些编译、链接列表变量。
O_OBJS,L_OBJS,OX_OBJS,LX_OBJS:
本目录下需要编译进Linux内核vmlinux的目标文件列表,其中OX_OBJS和LX_OBJS中的"
X"
表明目标文件使用了EXPORT_SYMBOL输出符号。
M_OBJS,MX_OBJS:
本目录下需要被编译成可装载模块的目标文件列表。
同样,MX_OBJS中的"
O_TARGET,L_TARGET:
每个子目录下都有一个O_TARGET或L_TARGET,Rules.make首先从源代码编译生成O_OBJS和OX_OBJS中所有的目标文件,然后使用$(LD)-r把它们链接成一个O_TARGET或L_TARGET。
O_TARGET以.o结尾,而L_TARGET以.a结尾。
2.4子目录Makefile
子目录Makefile用来控制本级目录以下源代码的编译规则。
我们通过一个例子来讲解子目录Makefile的组成:
#
#Makefileforthelinuxkernel.
#Allofthe(potential)objectsthatexportsymbols.
#Thislistcomesfrom'
grep-lEXPORT_SYMBOL*.[hc]'
.
export-objs:
=tc.o
#Objectfilelists.
obj-y:
=
obj-m:
obj-n:
obj-:
obj-$(CONFIG_TC)+=tc.o
obj-$(CONFIG_ZS)+=zs.o
obj-$(CONFIG_VT)+=lk201.olk201-map.olk201-remap.o
#Filesthatarebothresidentandmodular:
removefrommodular.
=$(filter-out$(obj-y),$(obj-m))
#TranslatetoRules.makelists.
L_TARGET:
=tc.a
L_OBJS:
=$(sort$(filter-out$(export-objs),$(obj-y)))
LX_OBJS:
=$(sort$(filter$(export-objs),$(obj-y)))
M_OBJS:
=$(sort$(filter-out$(export-objs),$(obj-m)))
MX_OBJS:
=$(sort$(filter$(export-objs),$(obj-m)))
include$(TOPDIR)/Rules.make
a)注释
对Makefile的说明和解释,由#开始。
b)编译目标定义
类似于obj-$(CONFIG_TC)+=tc.o的语句是用来定义编译的目标,是子目录Makefile中最重要的部分。
编译目标定义那些在本子目录下,需要编译到Linux内核中的目标文件列表。
为了只在用户选择了此功能后才编译,所有的目标定义都融合了对配置变量的判断。
前面说过,每个配置变量取值范围是:
y,n,m和空,obj-$(CONFIG_TC)分别对应着obj-y,obj-n,obj-m,obj-。
如果CONFIG_TC配置为y,那么tc.o就进入了obj-y列表。
obj-y为包含到Linux内核vmlinux中的目标文件列表;
obj-m为编译成模块的目标文件列表;
obj-n和obj-中的文件列表被忽略。
配置系统就根据这些列表的属性进行编译和链接。
export-objs中的目标文件都使用了EXPORT_SYMBOL()定义了公共的符号,以便可装载模块使用。
在tc.c文件的最后部分,有"
EXPORT_SYMBOL(search_tc_card);
"
,表明tc.o有符号输出。
这里需要指出的是,对于编译目标的定义,存在着两种格式,分别是老式定义和新式定义。
老式定义就是前面Rules.make使用的那些变量,新式定义就是obj-y,obj-m,obj-n和obj-。
Linux内核推荐使用新式定义,不过由于Rules.make不理解新式定义,需要在Makefile中的适配段将其转换成老式定义。
c)适配段
适配段的作用是将新式定义转换成老式定义。
在上面的例子中,适配段就是将obj-y和obj-m转换成Rules.make能够理解的L_TARGET,L_OBJS,LX_OBJS,M_OBJS,MX_OBJS。
=$(sort$(filter-out$(export-objs),$(obj-y)))定义了L_OBJS的生成方式:
在obj-y的列表中过滤掉export-objs(tc.o),然后排序并去除重复的文件名。
这里使用到了GNUMake的一些特殊功能,具体的含义可参考Make的文档(infomake)。
d)include$(TOPDIR)/Rules.make
3.配置文件
3.1配置功能概述
除了Makefile的编写,另外一个重要的工作就是把新功能加入到Linux的配置选项中,提供此项功能的说明,让用户有机会选择此项功能。
所有的这些都需要在config.in文件中用配置语言来编写配置脚本,
在Linux内核中,配置命令有多种方式:
配置命令
解释脚本
Makeconfig,makeoldconfig
scripts/Configure
Makemenuconfig
scripts/Menuconfig
Makexconfig
scripts/tkparse
以字符界面配置(makeconfig)为例,顶层Makefile调用scripts/Configure,按照arch/arm/config.in来进行配置。
命令执行完后产生文件.config,其中保存着配置信息。
下一次再做makeconfig将产生新的.config文件,原.config被改名为.config.old
3.2配置语言
1)顶层菜单
mainmenu_name/prompt//prompt/是用'
或"
包围的字符串,'
与"
的区别是'
…'
中可使用$引用变量的值。
mainmenu_name设置最高层菜单的名字,它只在makexconfig时才会显示。
2)询问语句
bool/prompt//symbol/
hex/prompt//symbol//word/
int/prompt//symbol//word/
string/prompt//symbol//word/
tristate/prompt//symbol/
询问语句首先显示一串提示符/prompt/,等待用户输入,并把输入的结果赋给/symbol/所代表的配置变量。
不同的询问语句的区别在于它们接受的输入数据类型不同,比如bool接受布尔类型(y或n),hex接受16进制数据。
有些询问语句还有第三个参数/word/,用来给出缺省值。
3)定义语句
define_bool/symbol//word/
define_hex/symbol//word/
define_int/symbol//word/
define_string/symbol//word/
define_tristate/symbol//word/
不同于询问语句等待用户输入,定义语句显式的给配置变量/symbol/赋值/word/。
4)依赖语句
dep_bool/prompt//symbol//dep/...
dep_mbool/prompt//symbol//dep/...
dep_hex/prompt//symbol//word//dep/...
dep_int/prompt//symbol//word//dep/...
dep_string/prompt//symbol//word//dep/...
dep_tristate/prompt//symbol//dep/...
与询问语句类似,依赖语句也是定义新的配置变量。
不同的是,配置变量/symbol/的取值范围将依赖于配置变量列表/dep/…。
这就意味着:
被定义的配置变量所对应功能的取舍取决于依赖列表所对应功能的选择。
以dep_bool为例,如果/dep/…列表的所有配置变量都取值y,则显示/prompt/,用户可输入任意的值给配置变量/symbol/,但是只要有一个配置变量的取值为n,则/symbol/被强制成n。
不同依赖语句的区别在于它们由依赖条件所产生的取值范围不同。
5)选择语句
choice/prompt//word//word/
choice语句首先给出一串选择列表,供用户选择其中一种。
比如LinuxforARM支持多种基于ARMcore的CPU,Linux使用choice语句提供一个CPU列表,供用户选择:
choice'
ARMsystemtype'
\
"
AnakinCONFIG_ARCH_ANAKIN\
Archimedes/A5000CONFIG_ARCH_ARCA5K\
Cirrus-CL-PS7500FECONFIG_ARCH_CLPS7500\
……
SA1100-basedCONFIG_ARCH_SA1100\
SharkCONFIG_ARCH_SHARK"
RiscPC
Choice首先显示/prompt/,然后将/word/分解成前后两个部分,前部分为对应选择的提示符,后部分是对应选择的配置变量。
用户选择的配置变量为y,其余的都为n。
6)if语句
if[/expr/];
then
/statement/
...
fi
if[/expr/];
/statement/
else
if
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 内核 配置
![提示](https://static.bdocx.com/images/bang_tan.gif)