您好,欢迎来到爱站旅游。
搜索
您的当前位置:首页嵌入式Linux内核的配置与编译系统研究

嵌入式Linux内核的配置与编译系统研究

来源:爱站旅游
维普资讯 http://www.cqvip.com

嵌入式 1=j 接的醚与编译系统研究 赵国义 摘要 以ARM处理器平台为例,详细分析了嵌入式Linux内核的配置与编译系统,并给 出了生成Linux内核映像的配置与编译方法,最后通过一个例子讲述了如何将用 户开发的源代码加入到Linux内核中,并增加相应的可供选择的配置菜单选项, 可根据用户选择情况决定是否被编译进Linux的内核映像文件vmlinux中。 关键词Linux,Makefile,配置,依赖关系,编译规则,内核映像 一、引言 Linux是一种实用性很强的现代操作系统,它可以稳定地 具体的配置选项这里就不进行一一介绍了,根据提供的帮 助信息很容易理解。这里需要说明的是:如果某选项在配置菜 单中是可选择的,这并不意味着目标系统就支持该功能,当然 大部分可供选择的选项是目标系统支持的;同样,配置菜单中 没有的选项并不一定就表示目标系统不支持该功能,原因可能 是该功能还未在目标系统上测试过,或者是维护人员未将该功 能选项加入到各级系统配置文件的eonfig.in中。所有这些可访 问上面给出的下载补丁网站来确定。 2.配置方法 运行在X86、PowerPC、ARM、MIPS等多种平台上,是目前支 持硬件平台最多的操作系统。Linux最大的特点在于它是开放 源码的,任何人只要遵循GPL,就可以对内核进行修改并发布 给他人使用。所有这些特点成为了嵌入式系统开发员首选的操 作系统,开发者可以根据自己特殊的硬件系统及应用需求对 Linux内核进行配置,并将自己开发的源代码加入到Linux内 核,从而满足不同的嵌入式系统的应用需求。本文以ARM开 发平台为例,深入分析Linux内核的配置与编译系统。 make eonfig:通过提示,依次设定每个选项为Y、m或n。 make oldconifg:也是通过提示的方式,它要求手动设定在 .二、选择 为了得到适合目标系统的内核,先从http:// www.kerne1.org上下载合适的内核,假设选择下载了Linux一 2.4.18版本,再从http://www.arm.1inux.org.uk/developer eonfig中没有设定的选项,而make config则不管在,config中 是否设定过都要求用户重新设定。 make menuconifg:显示以eurses为基础的、终端式的配置 菜单。如果.eonfig文件存在,则会根据该文件来设定默认 值。一般情况下我们会选择该方法进行配置。 make xconfig:显示以Tk为基础的X Window配置菜单。 同样,如果.eonfig文件存在,则会根据该文件来设定默认 值。 上下载相应的补丁2.4.18一rmk5,打上补丁后就得到了所需 的支持ARM处理器的内核Linux一2.4.18一rmk5。当然如果想 得到真正能够运行在自己特定的嵌入式系统板上的内核,还需 要在此基础上做许多的移植工作 不管选择哪种方法,在对Linux内核配置选项进行选择设 三、配置 1.配置选项 定后,都会在内核顶层目录下生成一个隐藏的. ̄onfig文件, 它包含了所有配置选项的用户选择信息。当下一次make menuconfig时,会生成一个新的.eonfig文件,原来的文件被更 名为.eonfig.old。 3.配置文件 配置选项是在输入配置命令后根据自己的系统需求进行选 择的,选择Y表示要将该功能编译进Linux内核中,选择m表 示要编译成内核模块,选择n表示不将该功能编译进内核。 (1)eonfig文件 该文件被顶层Makefile包含,Rules.make及子目录中的 维普资讯 http://www.cqvip.com

………………………………………… ……………}t 实用第一 智慧密集 __t--_。-Et__ ---- -g-_--。-_l-t- l-・* Ej-- 目t L目- jt El-_- E E。 ・|_。t Makefile并未包含这个文件,它是通过在顶层Makefile中设置 件生成目标文件的规则等。各级子目录下的Makefile通过语句 include¥(TOPDIR)/Rules.make将其包含,用以识别各Make— ifle中所定义的一些变量,比如.config文件中有CON— FIGARCH_并出口(export)变量MAKEFILES来向下传递的,比如MAKE FILES=¥(TOPDIR)/.config。 (2)arc/arm/config.in文件 _S3C2410=Y, 则在Makeifle中obj— CON— 该文件提供了总体的内核配置菜单选项,具体的子配置菜 单选项需在其他各级子目录下的config,in中描述。当用户开发 FIGARCH__S3C2410就成为obj—Y变量。 下面分析一下Rules.make中的变量所代表的意义: (1)obj—Y,obj—m,bj—n,obj一 了新功能程序并需将其相关的配置选项加入到Linux的配置菜 单中,以供用户需要此功能时进行选择,这时要在各级目录下 变量obj—Y表示需编译到IAnux内核中的目标文件名集 的config.in文件中用配置语言来编写相应的配置脚本。具体 的配置语言的语法可参考Documentation/kbuild/config—lan- guage.t)【t文件。 (3) include/linux/autoconf.h 同.config一样,该文件也是在make menuconfig后产生, 它是根据内核配置情况由一些预处理语句组成。 几乎所有的源文件都会通过#include<linux/config.h>来 嵌入autoconf.h文件。当配置选项发生变化时,会更新auto— conf.h,如果按照通常方法,使用make dep在每个子目录下生 成依赖文件.depend,将造成所有源代码的重新编绎。为了优 化make过程,减少不必要的重新编绎,Linux开发了专用的 mkdep及split—include工具。在scripts目录下有工具mkdep及 split—include的源代码,编译后生成相应的工具。mkdep用来 取代make dep来生成.depend文件,它在处理源文件时,将 忽略linux/config.h头文件,直接查找源文件中具有 “CONFIG ’特征的宏定义。例如,如果有“#删ef CON— FIG_PCI”这样的行,它就会在.depend文件中输出¥(wildcard /opt/linux/include/config/pci.h),split—include工具以auto一 、conf.h为输入文件,利用autoconf.h中的“CONFIG"’标记, 生成与mkdep相对应的文件。例如,如果autoconf.h中有#un— def CONFIG_PCI这样的行,它就会生成include/config/pci.h 文件,其内容只有一行:#undef CONFIG_PCI,表示不支持PCI 设备。include/config/下的文件名只在.depend文件中出现, 内核源文件是不会嵌入它们的。这样的话,每重新配置一次内 核,就会运行工具split—include一次,来检查旧的子文件的内 容,以确定是否需要更新它们。这样,不管autoconf.h修改日 期如何,只要其配置不变,make就不会重新编绎内核。 四、编译 这是本文讲述的重点。Linux内核的编译系统比较复杂, 主要从下面几个方面进行分析阐述。 1.Rules.make文件 Rules.make文件中包含了各级目录下的Makefile共同遵循 的编译规则,比如将C文件编绎成目标文件的规则、将汇编文 合,obj—m表示需要编译成模块的目标文件名集合,obj—n表 示不需要编译的文件,obj一表示为空。 (2)O TARGET,L_TARGET 每个Makefile中都有一个O TARGET或L_TARGET变量, O_TARGET或L TARGET的生成规则在Rules.make中规定。目 标文件O_TARGET表示由obj—Y链接(1d)而成,后缀为.O, 静态库文件L_TARGET是由obj—Y打包(ar)而成,后缀为 .a。 2.Makefile分析 Makeifle根据配置文件.config构造出需要进入的子目录及 其下需要编译的源文件列表,然后对该源文件列表分别进行编 译,并把目标代码链接到一起,最终形成Linux内核二进制 文件。各级子目录下都有Makefile文件,分别控制其所在目录 下的源代码编译。 (1)顶层Makeifle分析 该Makeifle为内核编译的总体控制文件,它的主要任务是 生成内核二进制文件vmlinux和内核模块module。以内核文件 vmlinux的生成规则为例,分析一下顶层Makefile如何进入子目 录并调用其下的各Makefile。 在顶层Makeifle中vmlinux的生成规则设定如下: vmlinux:incIude/Iinux/version.h¥(CONFIGURATION) init/main.o init/version.o linuxsubdirs ¥(LD)¥(LINKFLAGS)¥(HEAD)inIt/main.o init/version. o i 一一start—group I ¥(CORE_FILES)\ ¥(DRIVERS)、 ¥(NEn/\/ORKS)\ ¥(LIBS)\ 一一end—group t —.o vmlinux 从上面可以看出内核vmlinux是由HEAD、main.o ver- sion.O、CORE_FIELS、DRIVERS、NETWORKS、LIBS组成。其 中CORE_FIELS、DRIVERS、NETWORKS、LIBS在顶层Make— ifle中定义,例如在该Makefile中DRIVERS的定义如下: 维普资讯 http://www.cqvip.com

DRIVERS-y+=drivers/serial/seria1.odrivers/char/char.o DRIVERS一¥(CONFIG-PCI)+=drivers/pci/driver.o... DRIVERS:=¥(DRIVERS—Y) HEAD在arch/arm/Makefile中定义,该MakefiIe是针对特 定平台ARM的,它包含了与平台相关的一些信息. HEAD:=arch/arm/kernel/head一¥(PROCESSOR).o\ arch/arm/kernel/init_task.o 从内核vmlinux的产生过程所依赖的目标文件及变量可以 看出,欲生成vmlinux,顶层Makeifle会根据.conifg文件中的 配置,分别进入drivers/serial/、drivers/char/及arch/arm/ 等各个子目录并调用其中的Makefile,从而生成seira1.0、 char.0、init_task.O等。如果这时我们选择了系统支持PCI设 备,那么DRIVERS一¥(CONFIG_PCI)=DRIVERS—Y,make就 会进入drivesr/pci/目录并根据该目录下的Makeifle来生成 driver.0。所有的这些目标文件构成了DRIVERS和HEAD,从 而构成内核vmlinux中的DRIVERS和HEAD。其它的变量 NETWORKS、L1BS等的产生过程类似。 通过上例总结一下Makeifle之间的调用关系:在顶层 Makeifle中定义了变量SUBDIRS,在编译内核或模块时,顶层 Makeifle根据SUBDIRS的值来决定进入哪些子目录。SUB— DIRS的值取决于内核的配置,在顶层Makeifle中将SUB— DIRS赋值为:SUBDIRS=kemel drivesr mm fs net ipc lib,根 据内核的配置情况,在arch/arm/Makefile中对变量SUBDIRS 的值进行了扩充。假设现在进入了drivers/目录,在该目录下 的Makefile会根据其中的变量subdir—Y的值来决定进入 drivers/下的哪个子目录进行编译,subdir—Y的定义如下: subdir—Y:=parport serila char block net sound misc media cdrom hotplug。这是默认需要进入的子目录,根据需要可以对 其进行扩充。比如我们在make menuconfig的配置菜单中选择 了系统支持PCI设备,在.config中¥(CONFIG_PCI)的值就为 Y,因此在该Makeifle中可以通过subdir一¥(CONFIGPCI)+: pci语句对subdir—Y进行扩充。也就是还需要进入drivers/ pci/子目录下进行make。然后在drivers/pci/Makefile中根据 变量obj—Y来定义drivers/pci/下需要编译的C源文件:obj一 ¥(CONFIG_PCI)+=pci.O quirks.O compat.O names.O bridge.0 也就是需要编译pci.C、bridge.C源文件等。当然根据配置也可 以对需要编译的C源文件进行扩充,比如我们选择了系统支持 proc文件系统,通过下面语句则还需要对drivers/pci/proc.C 文件进行编译:obj一¥(CONFIGPROC_FS)+=proc.O。 另外,顶层Makeifle中定义并出口了许多环境变量,子目 录中的Makeifle可以使用这些变量。前面已经提到了一些,比 如HEAD、COREFILES、DRIVERS等。这里需要补充一点: 当进行交叉编译时,需在顶层Makeifle中修改变量 CROSS_COMPILE的值,将其改为用户自己的交叉编译器所在 的目录,比如 CROSS COMPILE =/usr/local/arm/2.95.3/bin/ lfl-m—lintLx—o (2)子Makefile分析 子Makefile比较简单,它负责控制该Makeifle所在目录下 的子目录及其源文件的编译。 五、配置、编译Linux内核的步骤 1.make mrproper:如果内核已经过多次编译,该命令可将 内核源代码恢复到“干净”的初始状态。 2.make menuconifg:配置内核。 在顶层Makefile中有对应的执行语句: menuconfig:include/linux/version.h symlinks ¥(MAKE)一C sc ripts/IxdiaIOg al l¥(CONFIG_SHELL)scripts/Menuconfig arch/¥(ARCH)/ config.in 也就是当执行该命令时,顶层Makeifle会调用该目录下的 scripts/Menuconfig脚本程序来解释arch/arm/config.in文件, 执行完后产生配置文件.config,它保存了配置变量。 对于特定的嵌入式Linux应用系统,并不会用到所提供的 Linux内核的所有部分,这就需要对内核进行裁减。所谓裁减 就是只将应用系统需要用到的部分功能保留,将其它不需要的 功能去掉,这样会节省系统资源,并减少系统出错的机率。所 有这些都需要在make menuconfig所弹出的菜单选项中进行取 舍,选择方法很简单,就是将光标移到每个选项上,通过空格 键进行选择切换,当出现[ 】时,表示系统需要此功能,当出 现[m】时,表示系统需要此功能并把它作为模块进行编译,当 出现【】时,表示系统不需要此功能,在编译时并不会将该功 能编译进内核。 3.make dep:建立依赖关系。 内核源码树中大多数文件都会与一些头文件有依存关系。 要建立内核,各个Makefile必须知道这些依存关系。执行该命 令后会在内核源码树中每个子目录里产生一个隐藏的.depend 文件,此文件中含有子目录下各文件所依存的头文件清单。 4.make zImage或make bzImage:编译内核。 不管用哪个命令,在顶层目录下都会生成vmlinux文件, vmlinux为未经压缩的内核映像,vm代表vitrual memo ̄, 即 表示它支持虚拟内存。使用make zImage或make bzlmage都会 在arch/amr/boot/下产生内核映像名为zlmage的文件,它是 经过gzip压缩的内核映像,不同之处在于:前者生成的内核为 不超过512KB的小内核映像;后者bzlmage是big zImage的简 维普资讯 http://www.cqvip.com

………………………………………………………… 实用第一 智慧密集 …。 …# …t … ii…‘ i …_ i… j ・ Et・ I E b・ …_} 写,它不受大小限制,生成的内核映像可以比前者更大一些。 5.如果需要编译内核模块,则用命令make modules。 上面的步骤在生成Linux内核映像的过程中不一定全部使 用,根据经验一般只需make menuconfig、make bzlmage两步 即可,然后将arch/arm/boot/下生成的内核映像zImage文件 烧写到嵌入式应用系统的板子上。 六、实例 经过上面的分析,应该对嵌入式“nux内核的配置与编译 系统有了比较深入的认识。下面通过一个简单的例子说明如何 将开发者自己开发的内核代码加入到Linux内核中,并且增加 相应的可供用户选择的配置选项,一旦用户选择了这些选项就 可以将相应的代码编译进最终生成的内核映像vmlinux中去。 这个例子中用到了配置语言及其编程,以及Makefile的编写, 在例子中都做了相应的解释。 这里使用的内核是杭州立宇泰电子有限公司提供的与开发 板配套的基于¥3C2410的源码包(内核版本为2.4.18,其它 公司提供的源码包和下面的操作过程类似)ker- nel_armsys_050929.tgz,将其拷贝到/opt目录下,然后解压: tar zxvf kernel_armsys_050929.tgz,在当前目录下会生成解压后 的kernel源码目录,以下的操作都是在/opt/kernel/目录下进 行。 1.确定源代码的放置位置 本例是向Linux内核中增加一个新的驱动程序newclriver, 因此应该将该驱动所包含的代码加入到.drivers/目录下,下 面是其代码目录树: ¥cd drivers/newdriver Stfee l一一Config.in I一一Makefile I一一dir I I一一Makefile l、一一program1.C l一一newdriver.C l一一program2.C 2.配置文件arch/arm/config.in 通过在该配置文件的最后加入一行source drivers/test/ Conifg.in,将子功能newdriver的配置菜单及其选项加入到 Linux内核的配置菜单系统中。因为arch/arm/config.in是总 的配置菜单,所有在make menuconfig之后出现的菜单及其选 项均在该文件中设置。 3.配置文件drivers/newdriver/contlg.in # 与 #newdriver driver configuration # mainmenu_option next_comment comment Newdriver Driver bool Newdriver support CONFIG_NEWDRIVER IfI ¥CONFIG_NEWDRIVER - Y l:then dep_tristate user interface CONFIG_NEWDRIVER -PROGRAM2\¥CONFIG_NEWDRIVER if【 CONFIG.NEWDRIVER._PROGRAM2 != n l:then dep—tristate Increase dir function CONFIG_NEWDRIVER— DIR\¥CONFIGJ、JEWDRIVER—PROGRAM2¥CONFIGJ2C fi fi endmenu 因为newdriver是内核驱动中的一项新功能,因此创建了 一个相应的菜单Newdriver Driver,接着会显示Newdriver sup. port选项选择,当选择了该选项(CONFIG._NEWDRIVER=Y)时, 会出现user interface选项供用户选择。同理,当选择了user interface及I2C suppofl(配置菜单中已存在)选项后,会出现In. crease dir function选项供用户选择。关键字bool类型只接受 Y、n,并将其值赋给后面的变量CONFIG NEWDRIVER,关键 字tirstate可接受Y、m、n,dep_tfstate表示CON. FIG_NEWDRIVER_DIR的值依赖于CONFIG_I2C及CON. FIG._NEWDRIVER._PROGRAM2二者的值,只要二者中有一个为 n,则其值亦为n。 4.drivers/newdriver/Makeftle内容 # #Makefile for the newdriver # SUB DIRS:= MOD UB—pIRS:=¥《SUB_DIRS) ALL SUB IRS:=¥《SUB_DIRS)dir L-TARGET:=newdriver.a export—objs:=program2.O obi一¥《CONFIG EWDRIVER)+=newdriver.O obi一¥ 《CONFIG_NEWDRIVER_PROGRAM2)+=program2.O SUbdir一¥《CONFIG_NEWDRIVER_DIR)+=dir include¥《TOPDIR)/Rules.make clean: for dirname in¥《ALL_SUB_DIRS):do make—C¥¥dirname clean;done rm—f¥.Ioa1.}.flags , /drivers/newdriver目录下最终生成的文件为newdriver.a. 将prgoram2.O放在export-objs列表中.是因为program.C 中使用了EXPORT_SYMBOL输出符号《可以是变量或者是函 数).以供其它内核模块调用.根据用户的选择构建obj—Y、 维普资讯 http://www.cqvip.com

……_翻_BEDDED SY弧啊PROG咖啊iNG…………………………………………………………………………… obj—m列表.然后将该列表中的目标文件连接成newdriv- er.a.同时根据选择确定是否进入 目录进行make,sub- DRIVERS::¥(DRIVERS—Y) c¨r—Y表示需要进入该列表中的目录进行编译. 5,/drivers/newdriver/dir/Makefile内容如下: # 在该目录下加入上面所示两条语句。 如果用户在配置菜单中选择了选项Newdriver support与 # # Makefile for the dir Increase dir function(选该选项的前提是user interface和I2C support选项都被选择上),那么CONFIG.NEWDRIVER和 _SUBDIRS :: CONFIG_NEWDRIVER_DIR的值都为Y,newdriver.a和pro— MOD-sUB IRS::¥(SUB_DIRS) ALLSUB IRS::¥(SUB_DIRS) _graml,a就都位于DRIVERS—Y列表中,然后又被包括在 DRIVERS列表中(通过语句DRIVERS::¥(DRIVERS—Y))。 前面已经讲过,Linux内核映像文件vmlinux中包括 LJARGET::program1,a obj一¥(CONFIG_NEWDRIVER—DIR)+:pmgram1.o include¥lTOPDIR)/Rules.make clean: ‘ DRIVERS,所以newdriver.a和pm ̄am1.a最终就可以被链接 到vmlinux中。 rm—f}.【oa】.},flags 同理,在/drivers/newdriver/dir/下生成文件program1,a。 6.drivers/Makelile # 七、结语 本文深入分析了嵌入式Linux内核的配置与编译系统,基 于此分析,开发者可以根据自己的硬件对Linux内核进行不同 的配置,也可以根据需要将自己开发的源代码加入到Linux内 #Makefile for the Linux kernel device drivers. # 核中,并增加相应的可供选择的配置选项,使其成为Linux内 核的一部分。通过了解Linux内核的配置与编译系统,还有助 于分析内核编译时的出错信息,从而做出相应的处理。 subdir一¥(CONFIG—NEWDRIVER)+:newdriver include¥(TOPDIR)/Rules.make 在该Makefile中加入subdir一¥(CONFIG_NEWDRIVER) +:newdriver语句,这样在内核编译时才能够进入newdriver 目录进行编译。 7,顶层Makefile 参考文献 1,倪继利,Linux内核分析及编程,电子工业出版社, 2005 2.Karim Yagbmour.Building Embedded Linux Systems.O’ Reilly Media,Inc,2003 DRIVERS一¥(CONFIG—NEWDRIVER)+:drivers/new- driver/newdriver.a 3.陈渝等.源码开放的嵌入式系统软件分析与实践.北 京航空航天大学出版社,2004 (收稿日期:2006年9月26日) DRIVERS一¥ (CONFIG EWDRIVER_DIR)+:/drivers/ newdriver/dir/program1.a (上接第64页) 四、结语 本文采用VRML语言编程实现了三维汽车造型的设计,该 汽车具有较强的交互功能和真实感。引入虚拟现实技术,可以 把许多物品以三维形式在网上在线展示,使用户感觉身临其 境。随着互联网的普及和VRML技术的发展,虚拟现实的应用 前景也会越来越广泛,必将对网络应用产生深远的影响。 (收稿日期:2006年10月9日) 图4汽车造型的效果图 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- azee.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务