1、 Linux内核移植 所谓 Linux内核移植就是把 Linux操作系统针对具体的目标机做必要裁剪之后,安装到目标机使其正确的运行起来。 这个概念目前在嵌入式开发领域流传比较广泛。嵌入式 Linux移植是指对 Linux经过小型化裁剪后,能够固化在容量只有几 K字节或几十 K字节的存储器芯片或单片机中,应用于特定嵌入式场合的专用 Linux操作系统。 选择 Linux内核 内核( kernel)是所有 Linux 系统的主要软件组件。内核既是操作系统的心脏,也是它的大脑,因为内核控制着基本的硬件。内核是操作系统的核心,具 有很多最基本功能,如虚拟内存、多任务和 TCP/IP 网络等功能。 Li
2、nux 内核本身并不是操作系统,它是一个完整操作系统的组成部分。 Red Hat、 Novell、 Debian和 Gentoo等 Linux发行商都采用 Linux内核,然后加入更多的工具、库和应用程序来构建一个完整的操作系统。 Linux内核移植前准备 对于嵌入式 Linux 系统来说,有各种体系结构的处理器和硬件平台,并且用户需要根据需求自己定制硬件板。只要是硬件平台 发生 变化,即使非常小,可能也需要做一些移植工作。内核移植是嵌入式 Linux 系 统中最常见的一项工作。 当然,移植嵌入式 Linux系统并不意味着该内核使用了任何特定的链接库或用户工具,建立嵌入式系统并不需要特别的内核
3、。嵌入式系统中使用的内核与工作站或服务器上使用的内核主要的不同在于内核的配置方面。 Linux内核移植是在 Linux 原 内核 基础上,通过对平台的选择设计来实现针对特定系统的内核版本。 Linux 内核的移植包含启动代码的修改、内核的链接及装入、参数传递、内核引导几个部分 。其基本过程如下: ( 1)首先,获取某一版本的 Linux内核源码,根据具体目标平台对源码进行必要的改写(主要是修 改体系结构相关部分); ( 2)然后添加一些外设的驱动 (如网卡驱动, USB驱动) ,打造一款适合于目标平台(可以是嵌入式便携设备也可以是其它体系结构的 PC机)的新操作系统,也就是常说的内核配置或内核
4、定制; ( 3)对该系统进行针对目标平台的交叉编译,生成一个内核映象文件 (如zImage, uImage, bzImage) ; ( 4)最后通过一些手段 (如 TFTP) 把该映象文件烧写到目标平台中。 Linux内核源码 Linux内核移植工作主要是修改跟硬件平台相关的代码,一般不涉及 Linux 内核通用的程序 , 移植的难度也 取决于两种硬件平台的差异 。 通常对 Linux 源码的改写工作难度较大,它要求你不仅对 Linux内核结构要非常熟悉,还要求你对目标平台的硬件结构非常熟悉。同时还要求你对相关版本的汇编语言较熟悉因为与体系结构相关的部分源码往往是用汇编写的。 ( 1) BSP
5、包开发 Linux对于特定的硬件平台的软件就叫作 BSP( Board Support Package) 。 基于上面描述的困难,这部分工作一般由目标平台提供商来完成。比如说针对目前嵌入式系统中最流行的 ARM平台,它的这部分工作就是由英国 ARM公司的工程师完成的,我们 所要做的就是从其网站上下载相关版本 Linux内核的补丁( Patch)。把它打到我们的 Linux内核上,再进行后续操作就行。针对某些特定的硬件平台可能并没有平台开发商提供的 BSP,这就需要我们自己参考类似的BSP来开发程序。 所幸的是, Linux 内核已经支持了各种体系结构的很多种目标板,我们很容易从中找到跟自己硬件
6、类似的目标板。参考内核已经支持的目标板来移植 BSP,就如同使用模板开发程序 一样 。 当然,我们选择的参考板不能仅凭兴趣或爱好来选取, 选择参考板 也有一定的 原则 。具体的原则如下: 参考板与开发板具有相同 的处理器,至少类似的处理器; 参考板和开发板具有相同的外围接口电路,至少基本接口相同; Linux 内核已经支持参考板,至少有非官方的补丁或者 BSP; 参考板 Linux 设备驱动工作正常,至少已经驱动基本接口。 找到了参考板后, 还要仔细分析内核代码 以及参考板的 BSP, 分析平台相关的部分代码实现;分析内核编译组织方式;分析内核启动的初始化程序 ; 分析驱动程序的实现 ; 弄清
7、楚哪些设备有驱动程序,哪些还没有 等等。然后才能开始动手修改内核源代码。 ( 2)内核源码分析 我们需要进行 Linux内核移植,那么 首先 , 我们 得下载一个干净的内核源码树,解压后,先来看看 Linux内核源代码目录树结构。 arch:存放各种与硬件体系结构相关的代码,每种体系结构一个相应的目录,每个目录下都包括了该体系结构相关的代码,包括内存管理,启动代码,浮点数仿真等等。 block:部分块设备驱动程序。 crypto:常用加密和散列算法(如 AES、 SHA等),还有一些压缩和 CRC 校验算法 。 Documentation:关于内核各部分的通用解释和注释。 drivers:设备
8、驱动程序,每个不同的驱动占用一个子目录。 fs:提供对各种文件系统的支持 。 include:内核相关的头文件。以及与各体系结构相关的头文件也都放在这个目录下的各个体系结构目录中。 init:内核初始化代码。包括 main函数也是在这个目录下实现的。 ipc:进程间通信的代 码。 kernel:内核的最核心部分,包括进程调度、定时器等,和平台相关的一部分代码放在 arch/*/kernel 目录下。 lib: 各种 库文件代码 。 mm:内存管理代码,和平台相关的一部分代码放在 arch/*/mm目录下。 net:网络相关代码,实现了各种常见的网络协议。 scripts:用于配置内核文件的脚本
9、文 件。 security:主要是一个 SELinux的模块。 sound:常用音频设备的驱动程序等。 usr: 用户的代码 。 在 以上布局 中, linux 内核 主要分为特定于体系结构的部分和与体系结构无关的部分。 在 Linux启动的第一阶段,内核与体系结构相关部分( arch目录下)首先执行, 在这部分它要做的工作有 : 内核解压缩 、 解压缩内核重定位 ; 内存硬件初始化检测 ; 参数表的分析 ; 初始化页表目录的制作等工作, 然后把控制权转给内核中与系统结构无关部分。 所以 操作系统内核移植 中要改动的代码主要集中在与体系结构相关的 启动初始化 部分。 从上面的 目录结构 介绍
10、可知,如果要添加新的开发板或者寻找体系结构相关的文件首先就是 到 arch目录下去寻找。 在 arch目录中我们可以看到有许多子目录,它们往往是用芯片命名的,表示是针对该芯片体系结构的代码。为 ARM系列芯片编译内核,就应修改 ARM目录下的相关文件。 内核配置 及 方法 Linux 内核源代码支持二十多种体系结构的处理器 ,还有各种各样的驱动程序等选项。因此,在编译之前必须根据特定平台配置内核源代码。 Linux内核有上千个配置选项,配置相当复杂,所以, Linux内核源代码组织了一个配置系 统。 配置系统主要包含 Makefile、 Kconfig和配置工具。它可以生成内核配置菜单,方便内
11、核配置。配置界面是通过工具来生成的,工具通过 Makefile 编译执行,选项则是通过各级目录的 Kconfig文件定义。顶层目录的 Makefile 是整个内核配置编译的核心文件,整体管理 Linux内核的配置编译,负责组织目录树中子目录的编译管理,其定义了配置和编译的规则,还可以设置体系结构和版本号等。 Kconfig文件是 Linux2.6内核引入的配置文件,是内核配置选项的源文件。内核源码中的 Documentation/kbuild/kconfig-language.txt 文档有详细说明。对 内核进行 配置的方法有好几种,而且配置时 需要对 许多选项 进行 选择。不管用哪种方法来配
12、置,或者选择哪些配置选项,在配置好之后,内核都会产生 .config文件,这个文件包含了所有设定选项的全部细节。 常用的 内核配置 主要 有以下四种方法: ( 1) make config 通过命令界面,依次要求设定每个选项,并会根据 .config 配置文件设定各选项的预设值。 ( 2) make oldconfig 通过命令界面,自动载入 .config 配置文件。当遇到 先前没有设定过的选项时,才会要求你手动设定(而 make config 却会要求你手动设定所有的选项)。 ( 3) make menuconfig 显示配置菜单的形式。同 make config一样,会根据 .confi
13、g文件来设定预设值。 在 2.4.X 以及以前版本中 xconfig菜单是基于 TCL/TK的图形库的。 ( 4) make xconfig 显示 X Window配置菜单。它同样会根据 .config文件来设定预设值。 以上四种方法当中,只有少数开发者会使用 make config 来设定内核配置。多数开发者会使用 make menuconfig来建立初始的配置或调整已有的配置。接下来将介绍 make menuconfig进行内核配置的 选项和使用 方法。 图形化 内核配置选项 在 Linux源码的顶层目录运行 make menuconfig,便会出现如下图所示的图形化配置菜单: 图 6-2
14、-1 内核配置选项主菜单 上图显示的是一个主菜单,主菜单中还包含了很多子菜单,通过敲键盘的 、 键可以选择不同的子菜单,再敲回车键,进入这些子菜单,可以看到该子菜单下的一些功能选项,如我们进入 System Type这个子菜单,便可以看到如 图 6-2-2所示的 界面: 图 6-2-2 内核配置选项子菜单 在对各个选项进行配置时,有三种方式,它们分别代表的含义如下: Y:将该功能编译进内核; N:不将该功能编译进内核; M:将该功能编译成可以在需要时动态插入到内核中的模块 。 至于某个选项具体配置成哪一种方式,可以通过空格键进行选取。所有选项前都有一个括号,有的是中括号,有的是尖括号,还有圆括
15、号。用空格键选择时可以发现,中括号里要么是空,要么是 “*“,而尖括号里可以是空, “*“和 “M“这表示前者对应的项要么不要,要么编译到内核里;后者则多一样选择 ,可以编译成模块。而圆括号的内容是要你在所提供的几个选项中选择一项。 内核配置好后, 读者 可以通过 Esc键或是 Exit选项离开内核配置菜单。内核配置系统将会提示是否要储存新的配置。选择 Yes,离开内核配置系统的时候,会将新的配置储存到新的 .config 文件。这除了会建立 .config 文件,也会建立一些的头文件和符号链接。选择 No,离开内核配置系统的时候,并不会储存任何变更。 除了主要的配置选项,内核所支持的架构通常
16、会包含特定开发板的标准样版配置。比如 ARM 开发板,以 s3c2410 为例,在 arch/arm/configs 目录下便有一个 s3c2410_defconfig的配置文件,运行 make s3c2410_defconfig命令,内核配置系统将自动调用该配置文件,并且将该文件中各选项的配置存储到 .config文件中去,下次执行 make menuconfig时就会载入这些配置。 构建内核映像 内核编译基本命令 make mrproper: 清理全部文件,包括 .config和一些备份文件。 make clean:清理生成文件,但会保留 .config和一些模块文件。 make defc
17、onfig:生成包含默认选 项的 .config文件。 make oldconfig:在旧的 .config基础上生成新的 .config。如果只想在原来内核配置的基础上修改一些小地方,会省去不少麻烦。 make config: 基于文本的最为传统的配置界面,不推荐使用。 make menuconfig:基于文本选单的配置界面,字符终端下推荐使用。 make xconfig:基于图形窗口模式的配置界面, Xwindow下推荐使用。目的都是生成一个 .config文件 ,这三个命令中, make xconfig的界面最为友好,如果你可以使用 Xwindow,你就用这个好了,这个比较方便,也好设置
18、。如果你不能使用 Xwindow,那么就使用 make menuconfig。界面虽然比上面一个差点,总比 make config的要好多了。 make: 默认编译。 make bzImage:编译生成压缩的内核二进制文件,也会用 make zImage替代。 make distclean: 在进行安装之前要特别注意,如果你需要清理 内核 的 源码 ,让它回复到 配置 设定、依存关系建立或编译之前的初始状态, 就 使用 make distclean命令 , 但务必在执行此命令之前,将 内核 的 配 置文件 备份起来,因为 make distclean 会清除前面这几个阶段所产生的 文件 ,包括 .config 文件 、所有的 目标文件 以及 内核 映像。