2011年(4)
分类: LINUX
2011-02-26 12:46:27
要想学习Linux内核,特别是要想通过去hacking内核代码来找到您手头问题的答案,那你通常就需要先有一些基础知识,包括操作系统的原理、实际hacking所需要的工具使用、Linux内核构建系统的基本构成与基本运作原理等等。而Linux内核构建系统就是前述第三类知识中比较基础的部分。在整个Linux的开发生态中,处于不同位置的人要求掌握内核构建系统的程度也不同。作为驱动程序开发人员来讲,只要求会写自己驱动程序的Kbuild/Makefile文件即可,但是正所谓“技多不压身”,更何况了解构建系统能让你更熟悉整个内核的工作原理,这反过来会促进你驱动开发能力的提升。
我认为你应当自己动手去hacking内核构建系统,但是,假如你想节省一点时间,那本文应该就是你需要的材料。由于本文主题比较大,所以我在这里做一连载,发表在我的blog上。当然,如果你更喜欢看pdf格式的文档,那这里就可以下载到包含所有内容的pdf文档。
这一系列的文章总共有十篇,这是它们的链接: 一 二 三 四 五 六 七 八 九 十
概论
在xNIX世界中,您若要想使用任何一款软件,通常来说都必须先从官方站点上获取源代码、继而编译安装、最后才是动手使用。概括起来,整个其过程一般可分成以下几个步骤:
a) 获取该软件的源代码;
源代码通常是以压缩包的形式由官方所发布出来的,所以到手后您必须解压。需要注意的是,如果官方代码中藏有bugs,而正好有热心人修正了这些bugs,并且发布出来一些补丁程序。那么您为了在后续使用时避免出现问题,您通常也需要下载这些补丁包,并进行patch操作。
b) 进入到源代码目录中进行配置;
对大型的软件项目来说,配置必不可少。该步骤的目的之一是为了确定编译阶段需要使用到的各种工具和编译过程所面对的系统架构。比如编译器在哪里?连接器又使用哪一个?搞清楚在什么机器架构上进行编译,编译出来的程序又运行在什么架构上?其目的之二,您通常需要在配置过程中指定哪些功能特征是您所需要的。要知道,一个较大型的软件项目,其中的功能可为多种多样,而您,通常只需要其中的一小部分,所以您需要在下面编译之前指定出来。
c) 编译该软件;
使用配置过程中所确定出来的工具,对实现您所指定那部分功能的代码模块进行编译,并经过连接,最后形成所需要的可执行程序或可执行映像。
d) 安装部署所编译出来的结果;
可执行程序的安装,就是要把他们放在PATH环境变量所指定的目录中去,通常是 /bin, /usr/bin, /sbin, /usr/sbin 之类的目录。那么可执行映像呢,这通常和嵌入式应用相关,您需要将这些映像下载到非易失性存贮器中,比如 EEPROM 或者 FLASH 中去。
当然,上面这个过程只是一般的过程。但是,像Windows平台那样,现在有很多软件也都发布了针对不同架构编译好的可执行应用程序包,为用户省却了烦琐的配置和编译,这种情况我们不去考虑。Linux内核作为一个大型的软件项目,其使用也遵循上面这样一个一般的过程。
针对Linux内核而言,上面的步骤b被称为kconfig,而步骤c即为kbuild。
kconfig时,我们要使用类似 "make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig" 的命令来选择我们所要的功能。这个命令结束时,我们所选择的结果会被记录到一个叫 ".config" 的隐藏文件中。注意,其中ARCH=arm规定了我们要为arm架构编译内核,而CROSS_COMPILE=arm-linux-规定了编译内核时需要使用arm-linux-打头的交叉工具链。
.config文件生成后,我们就可以使用 "make ARCH=arm CROSS_COMPILE=arm-linux-" 之类的命令来做编译,即kbuild了。需要注意的是,对Linux内核做编译,其产生的可执行代码分布在两个部分中间:一个基本内核映像和数个可独立加载的模块。在使用Linux内核时,前者作为Linux操作系统的主体而常驻内存;而后者可按需要动态的加载到内存中或自内存中卸载,用以动态的修改内核所具有的功能。这种安排是作为整块式操作系统结构的Linux内核向微内核操作系统结构学习的结果。既然编译的出来的可执行代码可以以两种方式存在,那么我们就必须预先告诉kbuild系统,哪部分放在基本内核里,哪部分又以模块的形式存在。所以显然,我们在配置过程中产生".config"文件的时候,除了需要记录我们所需要的功能外,还要记录这些功能都需要放在哪里。
Linux内核编译完成后,接下来要做的同样也是安装。对于x86等架构的桌面机来说,我们需要将基本内核映像放到文件系统中,通常是/boot目录下;对于嵌入式系统,我们要烧写进FLASH中。对于各种模块,我们也要装到文件系统的指定目录下面。另外值得一提的是为了让应用程序能正常使用C库,Linux内核还要向C库提供一套头文件,所以我们也需要将内核提供的头文件安装到文件系统相应的目录下面。安装可以手动进行,也可以自动的用类似 "make modinstd"、"make install"、"make headerinst"之类的命令。
[ 注意, 您可至此完整的查看该系列文章: http://yihect.juliantec.info/julblog//post/4/17
]