最新实验四Linux内核编译阅读Linux内核b源码b.docx
《最新实验四Linux内核编译阅读Linux内核b源码b.docx》由会员分享,可在线阅读,更多相关《最新实验四Linux内核编译阅读Linux内核b源码b.docx(12页珍藏版)》请在冰豆网上搜索。
最新实验四Linux内核编译阅读Linux内核b源码b
实验四Linux内核编译阅读Linux内核b源码b
实验四Linux内核编译、阅读Linux内核源码
一.实验目的
1.了解Linux内核的版本和组成
2.掌握Linux系统内核的编译操作方法
3.了解Linux系统内核的配置方法
4.通过阅读Linux的内核源码,学习系统调用的执行流程,为深入学习内核原理打下牢固基础
二.实验工具与设备
1.准备最新的Linux操作系统内核,或装有Linux操作系统的计算机并能直接连入Internet
2.实验设备:
计算机
三.实验内容
1.实验预备知识
内核是一个操作系统的核心,负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
Linux的一个重要特点是其源代码的公开性,所有的内核源程序都可以在/usr/src/linux下找到,大部分应用软件也遵循GPL而设计,任何人都可以获取相应的源程序代码。
全世界任何一个软件工程师都可以将自己认为优秀的代码加入到其中,由此带来的一个明显好处,是修补漏洞的快速以及对最新软件技术的利用。
Linux的内核是这些特点最直接的代表。
Linux作为一个自由软件,在广大爱好者的支持下,内核版本不断更新。
新的内核修订了旧内核的bug,并增加了许多新的特性。
如果用户想要使用这些新特性,或想根据自己的系统度身定制一个更高效、更稳定的内核,就需要重新编译内核。
通常,更新的内核支持更多的硬件,具备更好的进程管理能力,运行速度更快、更稳定,并且会修复老版本中发现的许多漏洞等。
经常选择升级更新的系统内核,是Linux用户的必要操作内容。
为了正确合理地设置内核编译配置选项,只编译系统需要功能的代码,原因如下。
(1)自己定制编译的内核运行更快(具有更少的代码)。
(2)系统将拥有更多的内存(内核部分将不会被交换到虚拟内存中)。
(3)不需要的功能编译进入内核,可能会增加被系统攻击者利用的漏洞。
(4)将某种功能编译为模块方式比编译到内核的方式速度要慢一些。
内核编译模式可以分为编译到内核和编译成模块两种模式。
要增加对某部分功能的支持,例如网络等,可以把相应部分编译到内核中(build-in),也可以把该部分编译成模块(module)动态调用。
如果编译到内核中,在内核启动时就可以自动支持相应部分的功能,其优点是方便、速度快,机器启动即可使用这部分功能。
其缺点是使内核变得庞大起来,无论是否需要这部分功能,它都会存在。
建议将经常使用的部分直接编译到内核中,如网卡;如果编译成模块,则生成对应的.o文件,使用时可以动态加载,优点是不会使内核过分庞大,缺点是必须得由用户自己来调用这些模块。
2.下载新内核
在http:
//www.kernel.org/pub/linux/kernel可以下载Linux的最新内核代码。
内核的源代码按内核版本(v2.4、v2.5等)组织到多个不同的目录中。
在每个目录中,文件被冠以“linux-x.y.z.tar.gz”和“linux-x.y.z.tar.bz2”等,这些就是Linux内核的源代码。
同时存在一些类似“patch-x.y.z.gz”和“patch-x.y.z.bz2”的文件,这是用来更新前面完整的内核源代码的补丁包。
本实验从http:
//www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.20.tar.gz下载linux-2.4.20.tar.gz内核,并将下载的内核linux-2.4.20.tar.gz保存在“/usr/src”目录下。
3.内核解包
编译内核前,应对下载的内核文件进行解包,操作方法如下。
(1)用以下命令将当前目录改到/usr/src下:
cd/usr/src
(2)如果/usr/src目录下存在一个“linux”的目录,应将其改名为“linux.old”;如果不存在,则直接执行以下命令:
tarxzvf./linux-2.4.20.tar.gz
(3)执行该命令后,内核源代码被释放到一个新的“linux-2.4.20”目录下。
注意:
目录名可能因版本的不同而有所区别。
为方便起见,将该目录名字改为“linux”,操作命令如下:
mvlinux-2.4.20linux
4.配置内核
Linux提供多种配置内核的方法,可以根据需要与爱好使用下面命令中的一个。
makeconfig命令:
基于文本配置界面的配置命令。
makemenuconfig命令:
基于文本菜单配置界面的配置命令。
makexconfig命令:
基于图形窗口模式配置界面的配置命令。
本实验以基于图形窗口模式配置界面的配置命令为例配置内核,具体操作步骤如下。
(1)用以下命令将当前目录改到解包文件目录“/usr/src/linux”下:
cd/usr/src/linux
(2)点选菜单进行配置(可和下面的(3)结合进行配置)
KDE->选项->系统->Linux内核配置程序
进入配置窗口后,在PathtoKernelSource下对于Architecture选i386。
对于每一选项,在“✓”左击可改变设置
(3)也可用以下配置命令打开配置对话框:
makexconfig
执行命令后,弹出配置对话框,如图4-1所示。
配置内核的选项很多。
选择每一项配置时,可以有三个选择按钮,如图4-2所示。
图4-1Linux内核配置对话框
每个按钮的意义如下。
y:
将该功能编译进内核。
n:
不将该功能编译进内核。
m:
将该功能编译成可以在需要时动态插入到内核中的模块。
单击“MainMenu”按钮,返回主配置窗口;单击“Next”按钮,配置下一个配置项;单击“Prev”按钮,配置上一个配置项。
在编译内核的过程中,大部分选项可以使用缺省值,只有部分要根据用户的需要进行更改。
修改的原则是将与内核其他部分关系较远且不经常使用的部分功能代码编译成为可加载模块,有利于减小内核的长度,减小内核消耗内存,简化该功能相应的环境改变时对内核的影响;不需要的功能不选;与内核关系紧密而且经常使用的部分功能代码则直接编译到内核中。
图4-2配置内核的选择按钮
几个主要的配置项如下:
①Loadablemodulesupport:
设置对可加载模块的支持,有以下三个选项:
–Enableloadablemodulesupport:
除非准备把所有需要的内容都编译到内核里面,否则该项应该是必选的(y)。
–Setversioninformationonallmodulesymbols:
有关版本信息加载项,可以不选它(n)。
–Kernelmoduleloader:
让内核在启动时有自己装入必需模块的能力,建议选上(y)。
②Processortypeandfeatures:
设置CPU的类型,有关的几个选项如下:
–Processorfamily:
根据所使用的计算机选择CPU类型。
–HighMemorySupport:
设置大容量内存的支持,可以支持到64GB,一般可以不选。
–Mathemulation:
协处理器仿真,如果CPU中没有数字协处理器则应选中,不过从486以后一般的CPU都有数字协处理器了,所以一般不选(n)。
–MTTRsupport:
MTTR支持,可不选(n)。
–Symmetricmulti-processingsupport:
对称多处理支持,如果计算机上有多于一个CPU就一定要选,若是单CPU,则不选(n)。
③Generalsetup:
对普通的一些属性进行设置。
一般使用缺省设置,经常使用的一些选项:
–Networkingsupport:
网络支持,必选,没有网卡也建议选上(y)。
–PCIsupport:
PCI卡的支持,如果使用了PCI接口卡,则必选(y)。
–PCIaccessmode:
PCI卡的存取模式,可供选择的有BIOS、Direct和Any,一般可选Any。
–Supportforhot-pluggabeldevices:
热插拔设备支持,支持的不是太好,可不选。
–PCMCIA/CardBussupport:
PCMCIA/CardBus支持,有PCMCIA就必选了(y)。
④Parallelportsupport:
并口的支持,一般应选上(y)。
⑤PlugandPlayconfiguration:
即插即用配置。
Linux有一定的即插即用功能,可选上。
⑥Blockdevices:
块设备支持,其中:
–NormalPCfloppydisksupport:
普通PC软盘支持,该项应选(y);
–Networkblockdevicesupport:
网络块设备支持,若希望访问网上邻居的内容,则应选取。
⑦Networkingoptions:
要选取TCP/IPnetworking选项。
⑧Networkdevicesupport:
网络设备支持,本项的选项很多,要注意选取正在使用的网络设备,例如正在使用Realtek8139的网卡,则“Ethernet(10or100Mbit)”就必须选上,还应选中对应的网卡型号“RealTeckRTL-8139PCIFastEthernetAdaptersupport”,若找不到所用网卡的型号,则应寻求厂商的支持,或到购买的网卡驱动盘中寻找。
⑨Mice:
鼠标设置。
可以支持总线、串口、PS/2、C&T82C710mouseport、PC110digitizerpad等类型的鼠标,应根据所用的鼠标类型进行选择。
⑩Filesystems:
文件系统类型。
内容很多,主要有以下几项:
–DOSFATfssupport:
DOSFAT文件格式的支持,可以支持FAT16、FAT32。
–NTFSfilesystemsupport:
NTFS是WindowsNT/2000使用的文件格式。
–/procfilesystemsupport:
/proc文件系统是Linux提供给用户和系统进行交互的通道,建议选上,否则某些功能没法正确执行。
⑪Sound:
声卡驱动,从列表中找到对应的声卡型号。
⑫USBsupport:
USB接口的支持,根据需要选择。
配置内核后,单击“SaveandExit”按钮存盘退出配置窗口。
5.生成依赖(dependency)信息,清除旧的编译结果
配置内核后,返回命令窗口。
为确保关键文件,在正确的位置输入以下命令:
makedep
为确保所有有关文件都处于最新版本状态,需要输入命令:
makeclean
检查是否生成依赖(dependency)信息并清除旧的编译结果。
6.编译二进制内核映像文件
在“/usr/src/linux”目录下建立二进制的内核映像文件,命令如下:
makebzImage(输入命令时请注意区分大小写)
编译过程持续几分钟。
编译结束后,在/usr/src/linux/arch/i386/boot目录下可找到名为“bzImage”的映像文件,即新内核的映像文件。
7.编译模块
编译二进制内核映像文件后,需要进行模块的编译,命令如下:
makemodules及makemodules_install
模块被编译且安装到/usr/lib/<内核版本号>目录下。
至此,内核被编译完成,内核模块也编译完成并被安装。
8.配置启动管理器
为了操作方便,先将编译好的新内核的映像文件(bzImage)复制到系统目录/boot下。
命令如下:
cp/usr/src/linux/arch/i386/boot/bzImage/boot
如果系统是用LILO启动,则修改/etc/lilo.conf,lilo.conf文件内容类似以下文本文件:
prompt
timeout=50
default=linux
boot=/dev/had
map=/boot/boot.b
message=/boot/message
linear
image=/boot/vmlinuz-2.4.7-10
…
label=linux
read-only
root=/dev/hda2
对以上文本修改后的内容如下:
prompt
timeout=50
default=linux
boot=/dev/had
map=/boot/boot.b
message=/boot/message
linear
image=/boot/bzImage
label=newlinux
image=/boot/vmlinuz-2.4.7-10
label=linux
read-only
root=/dev/hda2
其中,image=/boot/bzImage:
指定内核的映像文件,即告诉LILO应该到何处找到新内核;label=newlinux:
设置启动菜单选项的标签,即让启动的时候多一项“newlinux”的选择菜单。
修改完成后,保存并退出。
运行命令:
lilo
更新系统引导映象,使lilo.conf的修改起作用。
然后重新启动计算机,整个内核升级完成。
如果用Grub启动管理器,则添加以下几项:
titlenewlinux'设置启动菜单选项的标签,即让启动的时候多一项“newlinux”的选择菜单
root(hd0,0)
kernel/boot/bzImageroroot=/dev/hda2
注意:
第3句kernel/boot/bzImageroroot=/dev/hda2中,kernel后的/boot/bzImage必须指定新内核的路径和文件名。
Grub不需再次调用命令而自动生效,重启以后即可用新内核了。
重新启动计算机时,将看到启动菜单多了newlinux选项,选若中它启动,则选用新内核进行启动。
如果因前面的配置或操作不当引起升级失败使机器启动不了,可以在启动时选用旧的内核选项(如linux)引导系统。
9.阅读Linux的内核源码
(1)阅读sched.h源码文件,加深对进程管理概念的理解
(2)阅读Linux的fork.c源码文件,分析进程的创建过程
(3)阅读msg.c,sem.c和shm.c源码文件,熟悉Linux的三种通信机制。
Linux的内核源码可以通过许多途径得到。
一般来讲,在完整安装的Linux系统下,/usr/src/linux目录下的文件就是内核源码。
另外,还可以从Internet上下载,http:
//www.kernel.org/是比较权威的下载站点。
展开的源码一般包括以下几个子目录:
◆arch:
该目录包含了此内核源码所支持的硬件体系结构相关的内核源码。
在这个目录下,针对不同体系结构所移植的版本都有三个子目录:
kernel、lib和mm。
kernel子目录包含以来于体系结构实现的一般内核功能,如信号处理、时钟处理等;lib子目录包含库函数的本地实现,如果从依赖于体系结构的源码编译,则运行更快;mm子目录包含存储管理实现的代码。
◆kernel:
许多最常调用的内核函数放在该目录下。
调度器fork()和timer.c就放在这里,以及printk.c等。
与处理器结构相关的代码放在arch/*/kernel目录下。
◆lib:
该目录放置内核其他部分经常所需要的代码,如inflate.c就放在这里,它能够在引导时解压内核并装入内存。
与处理器结构相关的库代码放在arch/*/lib目录下。
◆mm:
包含了所有Linux实现虚拟内存管理的源码。
与具体硬件体协结构相关的内存管理代码位于arch/*/mm目录下,如对应X86的就是arch/i386/mm/fault.c
◆drivers:
这个目录拥有50%以上的内核源码,系统中所有的设备驱动程序都位于该目录中。
◆include:
包括了内核的大多数头文件,另外对每种支持的体系结构分别有一个子目录。
◆init:
包含了所有系统的初始化源码,许多主要的文件,如main.c就位于该目录下。
该文件还包含了许多核心代码——如实现fork()的代码和最常执行的代码——cpuidle()循环。
◆ipc:
处理进程间通信的全部所需的代码都放在目录下。
◆modules:
已编译好的可动态加载的模块。
◆fs:
Linux支持的文件系统代码。
不同的文件系统有不同的子目录与之对应。
◆net:
所有提供网络支持的代码,每个子目录对应网络的一个方面。
◆scripts:
用于配置内核的脚本文件角用户开发和维护手册。
Linux内核源码包含的内容较多,2.4.20版本的内核源码大约有40万行。
10.内核编码风格
如果用户需要修改Linux内核源码,那么一定要注意遵守下面的编码约定:
◆注释是/**/风格的,单行注释也是这样,不接受//风格的注释。
◆函数开始的大括号{}独占一行。
◆if语句以下面方式编码:
if(str[0]>=’0’&&str[0]<=’9’){
strcpy(name,“abcd”);
strncpy(name+4,str,1);
}else
printk(“errorparam”);
name[sizeof(name)-1]=0;
◆单行if语句是可以接受的:
if(!
strcmp(str,“abc”))strcpy(str,“abc”);
◆内核源码包含许多goto,差不多每80行代码就有一个goto,这是出于执行效率的考虑,如在一些while语句中,使用goto跳出代码块,而不是使用break。
四.思考题
1.为什么要经常重新编译内核?
2.根据实验所用计算机系统的硬件配置对内核进行配置,配置项所选用的配置参数有哪些?
3.内核编码风格和普通编码有何不同?