本章重点
² 了解Linux内核源代码的目录结构及各目录的相关内容
² 了解Linux内核各配置选项内容和作用
² 掌握Linux内核配置文件的作用
² 掌握Linux内核的编译过程
² 掌握将新增内核代码加入到Linux内核结构中的方法
本章导读
在计算机科学中,内核是操作系统最基本的部分。它是为众多应用程序提供对计算机硬体的安全访问的一部分软件,这种访问是有限的,并且内核决定一个程序在什么时候对某部分硬体操作多长时间。直接对硬体操作是非常覆杂的,所以内核通常提供一种硬体抽象的方法来完成这些操作。硬件抽象隐藏了复杂性,为应用软件和硬件提供了一套简洁,统一的接口,使程序设计更为简单。
3.1、内核源代码目录介绍
Linux内核源代码可以从网上下载,一般主机平台的Linux (如红旗Linux)源代码在根目录下的/usr/src/linux目录下。内核源代码的文件按树形结构进行组织的,在源代码树最上层的主要可以看到如下的一些目录: (1)、arch:arch子目录包括所有与体系结构相关的内核代码。arch的每一个子目录都代表一个Linux所支持的体系结构。 (2)、include:include子目录包括编译内核所需要的头文件。与ARM相关的头文件在include/asm-arm子目录下。 (3)、init:这个目录包含内核的初始化代码,但不是系统的引导代码,其中所包含main.c和Version.c文件是研究Linux内核的起点。 (4)、mm:该目录包含所有独立于CPU体系结构的内存管理代码,如页式存储管理内存的分配和释放等。与ARM体系结构相关的代码在arch/arm/mm中。 (5)、Kernel:这里包括主要的内核代码,此目录下的文件实现大多数Linux的内核函数,其中最重要的文件是sched.c。与Xscale体系结构相关的代码在arch/arm-pxa/kernel目录中。 (6)、Drives:此目录存放系统所有的设备驱动程序,每种驱动程序各占一个子目录。 (a)、/block:块设备驱动程序。块设备包括IDE和scsi设备。 (b)、/char:字符设备驱动程序。如串口、鼠标等。 (c)、/cdrom:包含Linux所有的CD-ROM代码。 (d)、/pci:PCI卡驱动程序代码,包含PCI子系统映射和初始化代码等。 (e)、/scsi:包含所有的SCSI代码以及Linux所支持的所有的SCSI设备驱动程序代码。 (f)、/net:网络设备驱动程序。 (g)、/sound:声卡设备驱动程序。 (7)、lib目录放置内核的库代码; (8)、net目录包含内核与网络的相关的代码; (9)、ipc目录包含内核进程通信的代码; (10)、fs目录是所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统,如JFFS2; (11)、scripts目录包含用于配置内核的脚本文件等。每个目录下一般都有depend文件和一个makefile文件,他们是编译时使用的辅助文件,仔细阅读这两个文件对弄清各个文件之间的相互依托关系很有帮助。
3.2、内核的配置的基本结构
Linux内核的配置系统由四个部分组成 (1)、Makefile:分布在Linux内核源码中的Makefile,定义Linux内核的编译规则;顶层Makefile是整个内核配置、编译的总体控制文件; (2)、配置文件(config.in):给用户提供配置选择的功能;config:内核配置文件,包括由用户选择的配置选项,用来存放内核配置后的结果; (3)、配置工具:包括对配置脚本中使用的配置命令进行解释的配置命令解释器和配置用户界面(基于字符界面:make config;基于Ncurses图形界面:make menuconfig;基于xWindows图形界面:make xconfig) (4)、Rules.make:规则文件,被所有的Makefile使用。 3.2.1编译规则Makefile 利用 make menuconfig(或make config、make xconfig)对Linux内核进行配置后,系统将产生配置文件(.config)。在编译时,顶层 Makefile 将读取 .config 中的配置选择。 顶层 Makefile完成产生核心文件(vmlinux )和内核模块(module)两个任务,为了达到此目的,顶层 Makefile 递归进入到内核的各个子目录中,分别调用位于这些子目录中的 Makefile,然后进行编译。至于到底进入哪些子目录,取决于内核的配置。顶层Makefile中的include arch/$(ARCH)/Makefile指定特定 CPU 体系结构下的 Makefile,这个Makefile包含了特定平台相关的信息。 各个子目录下的 Makefile 同样也根据 配置文件(.config)给出的配置信息,构造出当前配置下需要的源文件列表,并在文件最后有 include $(TOPDIR)/Rules.make。 顶层 Makefile 定义并向环境中输出了许多变量,为各个子目录下的 Makefile 传递一些变量信息。有些变量,比如 SUBDIRS,不仅在顶层 Makefile 中定义并且赋初值,而且在 arch/*/Makefile 还作了扩充。 3.3、编译内核的常用命令 精简Linux内核常用命令包括:Make Config,dep,clean,mrproper,zImage,bzImage,Modules,Modules_Install
(1)、Make config:内核配置,调用./scripts/Configure按照arch/i386/config.in来进行配置。命令执行后产生文件.config,其中保存着配置信息。下次在做make config时将产生新的.config文件,原文件config更名为config.old (2)、 make dep:寻找依存关系。产生两个文件. depend和.hdepend,其中.hdepend表示每个.h文件都包含其他哪些嵌入文件。而.depend文件有多个,在每个会产生目标文件(.o)文件的目录下均有,它表示每个目标文件都依赖于哪些嵌入文件(.h) (3) 、make clean:清除以前构核所产生的所有的目标文件,模块文件,核心以及一些临时文件等,不产生任何文件
(4)、 make rmproper:删除所有以前在构核过程所产生的所有文件,及除了做make clean 外,还要删除.config,.depend等文件,把核心源码恢复到最原始的状态。下次构核时必须进行重新配置;
(5)、make,make zImage, make bzImage:
(a)、make:构核。通过各目录的Makefile文件进行,会在各个目录下产生一大堆目标文件,如核心代码没有错误,将产生文件vmlinux,这就是所构的核心。并产生映像文件system.map通过各目录的makefile文件进行。.version文件中的数加1,表示版本号的变化。
(b)、make zImage:在make的基础上产生压缩的核心映像文件./arch/$(ARCH)/boot/zImage以及./arch/$(ARCH)/boot/compressed目录下产生一些临时文件。
(c)、make bzImage:在make的基础上产生压缩比例更大的的核心映像文件./arch/$(ARCH)/boot/bzImage以及./arch/$(ARCH)/boot/compressed目录下产生一些临时文件。在核心太大时进行
3.4、内核编译过程,以实例介绍 3.4.1内核移植的准备 内核包:linux-2.6.22.5.tar.gz 官方下载:
http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.22.5.tar.bz2 BusyBox 是标准 Linux 工具的一个单个可执行实现。BusyBox 包含了一些简单的工具,例如 cat 和 echo,还包含了一些更大、更复杂的工具,例如 grep、find、mount 以及 telnet。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令。
busybox包:busybox-1.1.0.tar.bz2 官方下载:
http://www.busybox.net/downloads/busybox-1.1.0.tar.bz2
注意:若未安装交叉编译器,则还需先安装交叉编译器。下面所采用的交叉编译器是handhelds.org制作的arm-linux-gcc-3.4.1。
下载地址:ftp://ftp.handhelds.org/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2 安装方法:tar xjvf arm-linux-gcc-3.4.1.tar.bz2 -C /
安装后的路径:/usr/local/arm/3.4.1/
测试硬件:
上海锐极电子科技有限公司提供的ARM9开发板。
3.4.2 内核移植的基本过程 (1) 下载内核,解压到相应的目录;
(2) 修改Makefile文件,设置架构类型及使用的编译器;
(3) 配置内核,通常是尽量裁减内核;
(4) 生成新内核。
移植流程:
下载并解压缩内核
准备工作
配置内核
生成内核文件
测试新内核
修改Makefile文件
图3-1 内核移植流程图
3.4.3 内核移植的具体操作 内核移植步骤:
步骤1:拷贝linux-2.6.22.5内核压缩包到embedded目录中,并解压缩
[root@localhost embedded]# tar xjvf linux-2.6.22.5.tar.bz2
步骤2:进入linux-2.6.22.5目录中
[root@localhost embedded]# cd linux-2.6.22.5/
步骤3:修改Makefile文件
[root@localhost linux-2.6.22.5]# vi Makefile #ARCH
?= $(SUBARCH) #注释该行
#CROSS_COMPILE ?= #注释该行
ARCH ?= arm #添加该行
CROSS_COMPILE ?= /usr/local/arm/3.4.1/bin/arm-linux- #添加该行
步骤4:执行 make menuconfig 配置内核
[root@localhost linux-2.6.22.5]# make menuconfig
注意:可以尝试使用命令make xconfig ,配置会更方便,通常有4种主要的内核配置方法。
1.make config
命令行方式,配置相对繁琐。
2.make oldconfig 使用一个已有的.config配置文件,提示行会提示之前没有配置过的选项,相对较简单。
3.make menuconfig 基于文本图形化终端配置菜单,是目前最广泛使用的配置内核方法。
4.make xconfig 基于X窗口的配置菜单,用户可以通过图形界面和鼠标进行配置。
修改如下相关内容,要注意选的是 还是 [M] 之类
General setup --->
Initial RAM filesystem and RAM disk (initramfs/initrd) support
System Type --->
ARM system type (ARM Ltd. Versatile family) --->
(X) ARM Ltd. Versatile family 改成(X) Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443 再在ARM system type (Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443) --->
[ ] S3C2410 DMA support (NEW) 改成 S3C2410 DMA support
S3C2410 Machines --->
[ ] SMDK2410/A9M2410 (NEW) 改成 SMDK2410/A9M2410
Boot options --->
() Default kernel command string 改成(console=ttySAC0 root=/dev/ram init=/linuxrc) Default kernel command string
Device Drivers --->
Character devices --->
Serial drivers --->
< > Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support (NEW) 改成<*> Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support
Support for console on S3C2410 serial port
LED devices --->
[ ] LED Support (NEW) 改成 LED Support
<M> LED Class Support
< > LED Support for Samsung S3C24XX GPIO LEDs (NEW) 改成<M> LED Support for Samsung S3C24XX GPIO LEDs
[ ] LED Trigger support (NEW) 改成 LED Trigger support
<M> LED Timer Trigger
<M> LED Heartbeat Trigger
Multimedia devices --->
<M> Video For Linux 改成< > Video For Linux
DAB adapters (NEW) 改成[ ] DAB adapters
Graphics support --->
< > S3C2410 LCD framebuffer support (NEW) 改成<M> S3C2410 LCD framebuffer support
Console display driver support --->
VGA text console (NEW) 改成[ ] VGA text console
< > Framebuffer Console support (NEW) 改成<M> Framebuffer Console support
Framebuffer Console Rotation
Select compiled-in fonts
VGA 8x16 font
Mini 4x6 font
[ ] Bootup ** (NEW) ---> 改成 Bootup ** --->
上述的修改是必须的,下面的修改是根据需要进行的。
Code maturity level options --->
Prompt for development and/or incomplete code/drivers 改成[ ] Prompt for development and/or incomplete code/drivers Floating point emulation --->
[ ] NWFPE math emulation (NEW) 改成 NWFPE math emulation
Support extended precision Device Drivers --->
< > Memory Technology Device (MTD) support ---> 改成<M> Memory Technology Device (MTD) support --->
[ ] MTD partitioning support (NEW) 改成
MTD partitioning support
RAM/ROM/Flash chip drivers --->
< > Detect flash chips by Common Flash Interface (CFI) probe (NEW) 改成<M> Detect flash chips by Common Flash Interface (CFI) probe
< > Support for Intel/Sharp flash chips (NEW) 改成<M> Support for Intel/Sharp flash chips
< > Support for RAM chips in bus mapping (NEW) 改成<M> Support for RAM chips in bus mapping
< > Support for ROM chips in bus mapping (NEW) 改成<M> Support for ROM chips in bus mapping
Mapping drivers for chip access --->
< > Map driver for platform device RAM (mtd-ram) (NEW) 改成<M> Map driver for platform device RAM (mtd-ram)
Self-contained MTD device drivers --->
< > Physical system RAM (NEW) 改成<M> Physical system RAM
< > MTD using block device (NEW) 改成<M> MTD using block device
Parallel port support --->
<M> Parallel port support 改成< > Parallel port support
SCSI device support --->
<M> SCSI device support 改成< > SCSI device support
Multi-device support (RAID and LVM) --->
Multiple devices driver support (RAID and LVM) 改成[ ] Multiple devices driver support (RAID and LVM)
ISDN subsystem --->
<M> ISDN support 改成< > ISDN support
Input device support --->
<M> Joystick interface 改成< > Joystick interface
< > Touchscreen interface (NEW) 改成<M> Touchscreen interface
(320) Horizontal screen resolution
(240) Vertical screen resolution
[ ] Touchscreens (NEW) ---> 改成[ ] Touchscreens --->
< > Philips UCB1400 touchscreen (NEW) 改成<M> Philips UCB1400 touchscreen File systems --->
Miscellaneous filesystems --->
< > Journalling Flash File System v2 (JFFS2) support (NEW) 改成<M> Journalling Flash File System v2 (JFFS2) support
Advanced compression options for JFFS2
内核移植关键的步骤就在于配置哪些选项是必须选择,哪些选项是不用选的。实际上在配置时,大部分选项可以使用其默认值,只有少部分需要根据用户不同的需要选择。选择的原则,是将与内核其它部分关系较远且不经常使用的部分功能代码编译成可加载模块,有利于减小内核的大小,减小内核消耗的内存,简化该功能相应的环境改变时对内核的影响。不需要的功能就不选,与内核关系紧密而且经常使用的部分功能代码直接编译到内核中。
步骤5:执行make dep检查依赖关系
[root@localhost kernel]# make dep
步骤6:生成zImage内核镜像文件
[root@localhost kernel]# make zImage
注意:
1.make dep应用在内核2.4或之前,在2.6内核中已取消该命令。
2.make clean删除前面留下的中间文件,该命令不会删除.config等配置文件。
3.make zImage 编译生成gzip压缩形成的image文件。
4.make bzImage编译生成较大一点的内核文件。
5.生成的zImage文件在arch/arm/boot/ 目录中。
步骤7:复制zImage zImage文件复制到/tftpboot目录中
[root@localhost kernel]# cp arch/arm/boot/zImage /tftpboot/
步骤8:测试生成的新内核能否启动
在另一终端中打开minicom,复位开发板,进入PPCBoot的命令行界面,执行下面两行语句
SMDK2410 #setenv bootargs console=ttySAC0 initrd=0x30800000,0x00440000 root=/dev/ram init=/linuxrc SMDK2410 #tftp 0x30008000 zImage; go 0x30008000
注意:
上述两行语句中的ttySAC0、0x00440000部分,跟第一部分内核移植是不同的。
这里测试没有使用ramdisk文件系统,原因是前面移植的文件系统不能在这个内核下使用,需要移植更高版本的busybox才能使用。
出现如下信息,就表明内核能够运行在开发板上了。
Uncompressing Linux..................................................................... done, booting t.Linux version 2.6.22.5 (root@localhost.localdomain) (arm-linux-gcc version 3.4.1) #7 Sun Sep 2 14:24:43 CST 2007 CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177 Machine: SMDK2410 ATAG_INITRD is deprecated; please update your bootloader. Memory policy: ECC disabled, Data cache writeback CPU S3C2410 (id 0x32410000) S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz S3C24XX Clocks, (c) 2004 Simtec Electronics
当然,对于实际的应用当中的内核移植,需要根据实际需要,对某些选项进行裁剪,以使生成的内核文件尽可能小。当裁剪好的内核满足应用需要后,就可以烧写到目标板上了。
思考题
1、简述Linux源代码各目录中的内容, 2、分析make config、make menuconfig、make xconfig三个linux内核配置界面的区别 3、指出linux内核编译命令make,make zImage, ma bz俄Image的区别
4、下载一个Linux 2.6内核,查看它们的内核各项配置项的内容。 5、请针对内核的目录绘制一个树形结构图?请分析Linux内核面临许多新的变化是怎么将内核组织的很简洁和具有很好的扩展性。 6、简述将新增设备驱动源代码添加到linux内核中的步骤 |