Linux基础篇之内核编译与管理

1 Linux内核简介


内核kernel,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。Linux 内核是一个庞大而复杂的操作系统的核心,不过尽管庞大,但是却采用子系统和分层的概念很好地进行了组织。以下为Linux操作系统的基本体系结构,

Linux基础篇之内核编译与管理

最上面是用户(或应用程序)空间。这是用户应用程序执行的地方。用户空间之下是内核空间,Linux 内核正是位于这里。

GNU C Library (glibc)也在这里。它提供了连接内核的系统调用接口,还提供了在用户空间应用程序和内核之间进行转换的机制。这点非常重要,因为内核和用户空间的应用程序使用的是不同的保护地址空间。每个用户空间的进程都使用自己的虚拟地址空间,而内核则占用单独的地址空间。

Linux 内核可以进一步划分成 3 层。最上面是系统调用接口,它实现了一些基本的功能,例如read 和 write。系统调用接口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码。这些代码是 Linux 所支持的所有处理器体系结构所通用的。在这些代码之下是依赖于体系结构的代码,构成了通常称为 BSP(Board        Support Package)的部分。这些代码用作给定体系结构的处理器和特定于平台的代码。


2 Linux内核版本号


由于linux的源程序是完全公开的,任何人只要遵循GPL,就可以对内核加以修改并发布给他人使用。Linux的开发采用的是集市模型(bazaar,与cathedral--教堂模型--对应),为了确保这些无序的开发过程能够有序地进行,Linux采用了双树系统。一个树是稳定树(stable tree),另一个树是非稳定树(unstable tree)或者开发树(development tree)。一些新特性、实验性改进等都将首先在开发树中进行。如果在开发树中所做的改进也可以应用于稳定树,那么在开发树中经过测试以后,在稳定树中将进行相同的改进。一旦开发树经过了足够的发展,开发树就会成为新的稳定树。开发数就体现在源程序的版本号中;源程序版本号的形式为x.y.z:对于稳定树来说,y是偶数;对于开发树来说,y比相应的稳定树大一(因此,是奇数)。最新的内核可查看http://www.kernel.org

注解:要注意2.4.x与2.6.x是两个具有相当大差异的内核版本,两者之间使用到的函数库基本上已经不相同了,所以在升级之前,如果你的内核原本是 2.4.xx 版,那就升级到 2.4.xx 版本的最新版,不要由 2.4.xx 直接升级到 2.6.xx 版,否则会出现内核错误等问题。


3 内核编译的目的


1. 新功能的需求

所需要的新功能在当前内核中不存在,就需要重新编译新的内核以获取这个新功能。例如 iptables 这个防火墙机制只有在 2.4.xx 以后的版本里面才有,而新开发的主板芯片组, 很多也需要新的内核推出之后,才能正常而有效率的工作。


2. 原本核心太过臃肿
对于系统稳定性要求很高的情况下,对于内核多编译了很多莫名其妙的功能,就可以重新编译内核来取消掉这些功能。

3. 与硬件搭配的稳定性
由于原本 Linux 核心大多是针对 Intel 的 CPU 来作开发的,所以如果你的 CPU 是 AMD 的系统时,有可能会让系统跑得不太稳定。此外,内核也可能没有正确的驱动新的硬件,此时就得重新编译内核来让系统取得正确的模块。

4. 其他需求 (如嵌入式系统)
某些特殊的环境需求时,就得自行设计内核。


为了正确的合理地设置内核编译配置选项,从而只编译系统需要的功能的代码,一般主要有下面四个考虑:
1. 自己定制编译的内核运行更快(具有更少的代码)

2. 系统将拥有更多的内存(内核部分将不会被交换到虚拟内存中)

3. 不需要的功能编译进入内核可能会增加被系统攻击者利用的漏洞

4. 将某种功能编译为模块方式会比编译到内核内的方式速度要慢一些


4 内核版本的获取和更新


Linux内核版本发布的官方网站是http://www.kernel.org。新版本的内核分两种,一种是full Source版本,另外一种是patch文件,即补丁。完整的内核版本比较大,一般是tar.gz或者是.bz2文件,二者分别是使用gzip或者bzip2进行压缩的文件,使用时需要解压缩。patch文件则比较小,一般只有几十K到几百K,但是patch文件是针对于特定的版本的,你需要找到自己对应的版本才能使用。


4.1 内核源码的目录分析


tar jxvf linux-2.6.32.61.tar.bz2 -C /usr/src/kernels/

此时会在/usr/src/kernels目录下产生一个linux-2.6.32.61目录,查看该目录:

arch :与硬件平台有关的项目,大部分指的是 CPU 的类别,例如 x86, x86_64, Xen 虚拟支持等;
block :与成组设备较相关的设定数据,区块数据通常指的是大量储存媒体,还包括类似 ext3 等文件系统的支持是否允许等。
crypto :核心所支持的加密的技术,例如 md5 戒者是 des 等等;
Documentation :与核心有关的一堆说明文件。
drivers :一些硬件的驱动程序,例如显示适配器、网络卡、PCI 相关硬件等等;
firmware :一些旧式硬件的微脚本 (韧体) 数据;
fs :核心所支持的 filesystems ,例如 vfat, reiserfs, nfs 等等;
include :一些可让其他过程调用的标头 (header) 定义数据;
init :一些核心初始化的定义功能,包括挂载与 init 程序的呼叫等;
ipc :定义Linux 操作系统内各程序的沟通;
kernel :定义核心的程序、核心状态、线程、程序的排程 (schedule)、程序的信号 (signle) 等
lib :一些函数库;
mm :与内存单元有关的各项数据,包括 swap 与虚拟内存等;
net :与网络有关的各项协议数据,还有防火墙模块 (net/ipv4/netfilter/*) 等等;
security :包括selinux 等在内的安全性设定;
sound :与音效有关的各项模块;
virt :与虚拟化机器有关的信息,目前核心支持的是 KVM (Kernel base Virtual Machine)

5 内核编译模式


要增加对某部分功能的支持,比如网络之类,可以把相应部分编译到内核中(build-in),也可以把该部分编译成模块(module),动态调用。如果编译到内核中,在内核启动时就可以自动支持相应部分的功能,这样的优点是方便、速度快,机器一启动,你就可以使用这部分功能了;缺点是会使内核变得庞大起来,不管你是否需要这部分功能,它都会存在,这就是Windows惯用的招数,建议经常使用的部分直接编译到内核中,比如网卡。如果编译成模块,就会生成对应的.o文件,在使用的时候可以动态加载,优点是不会使内核过分庞大,缺点是你得自己来调用这些模块。


6 内核编译前准备


6.1 硬件环境检查和内核功能要求


可通过/proc/cpuinfo以及lspci来检查硬件信息


6.2 保持干净源码


在解压出来的内核目录下执行:make mrproper

确保下载下来的内核源码中没有目标档案(*.o)以及相关的配置文件存在,此举也会将之前进行过的内核功能选择文件也一并删除,所以几乎只有第一次执行内核编译前才进行这个动作,其余的时刻,想要删除前一次编译过程的残留数据,可执行:make clean


6.3 配置内核


配置内核可使用以下命令之一:

make menuconfig
最常使用的,是文本模式底下可以显示类似图形接口的方式,不需要启动 X Window 就能够选择内核功能选单。

make oldconfig
透过使用已存在的 ./.config 档案内容,使用该档案内的设定值为默认值,叧将新版本核心内的新功能选项列出供用户选择, 可以简化内核功能的选择过程。对于作为升级内核原始码后的功能选择来说,是非常好用的一个项目。

make xconfig
透过以 Qt 为图形接口基础功能的图形化接口显示,需要具有 X window 的支持。例如 KDE 就是透过 Qt 来设计的 X Window,因此你如果在 KDE 画面中,可以使用此一项目。

make gconfig
透过以 Gtk 为图形接口基础功能的图形化接口显示,需要具有 X window 的支持。例如 GNOME 就是透过 Gtk 来设计的 X Window,因此你如果在 GNOME 画面中,可以使用此一项目。

make config
最旧式的功能选择方法,每个项目都以条列式一条一条的列出供你选择,如果设定错误只能够再次选择。


在编译内核的过程中,最烦杂的事情就是这步配置工作了,很多新手都不清楚到底该如何选取这些选项。实际上在配置时,大部分选项可以使用其缺省值,只有小部分需要根据用户不同的需要选择。选择的原则是将与内核其它部分关系较远且不经常使用的部分功能代码编译成为可加载模块,有利于减小内核的长度,减小内核消耗的内存,简化该功能相应的环境改变时对内核的影响;不需要的功能就不要选;与内核关心紧密而且经常使用的部分功能代码直接编译到内核中。


至于选项,因为比较复杂,只是简单做一介绍,编译时应视具体情况,参考帮助的内容再
加以选择:
1. Code maturity level options
代码成熟等级。此处只有一项:prompt for development and/or incomplete code/drivers,
如果你要试验现在仍处于实验阶段的功能,比如khttpd、IPv6等,就必须把该项选择为Y了;
否则可以把它选择为N。

2. Loadable module support
对模块的支持。这里面有三项:
Enable loadable module support:除非你准备把所有需要的内容都编译到内核里面,否则该项应该是必选的。
Set version inFORMation on all module symbols:可以不选它。
Kernel module loader:让内核在启动时有自己装入必需模块的能力,建议选上。

3. Processor type and features
CPU类型。内容蛮多的,不一一介绍了,有关的几个如下:
Processor family:根据你自己的情况选择CPU类型。
High Memory Support:大容量内存的支持。可以支持到4G、64G,一般可以不选。
Math emulation:协处理器仿真。协处理器是在386时代的宠儿,现在早已不用了。
MTTR support:MTTR支持。可不选。
Symmetric multi-processing support:对称多处理支持。除非你富到有多个CPU,否则就不用选了。

4. General setup
这里是对最普通的一些属性进行设置。这部分内容非常多,一般使用缺省设置就可以了。下面介绍一下经常使用的一些选项:
Networking support:网络支持。必须,没有网卡也建议你选上。
PCI support:PCI支持。如果使用了PCI的卡,当然必选。
PCI access mode:PCI存取模式。可供选择的有BIOS、Direct和Any,选Any吧。
Support for hot-pluggabel devices:热插拔设备支持。支持的不是太好,可不选。
PCMCIA/CardBus support:PCMCIA/CardBus支持。有PCMCIA就必选了。
System V IPC
BSD Process Accounting
Sysctl support:以上三项是有关进程处理/IPC调用的,主要就是System V和BSD两种风格。如果你不是使用BSD,就按照缺省吧。
Power Management support:电源管理支持。
Advanced Power Management BIOS support:高级电源管理BIOS支持。

5. Memory Technology Device(MTD)
MTD设备支持。可不选。

6. Parallel port support
并口支持。如果不打算使用串口,就别选了。

7. Plug and Play configuration
即插即用支持。虽然linux对即插即用目前支持的不如Windows好,但是还是选上吧,这样你可以拔下鼠标之类的体验一下Linux下即插即用的感觉。

8. Block devices
块设备支持。这个就得针对自己的情况来选了,简单说明一下吧:
Normal PC floppy disk support:普通PC软盘支持。这个应该必选。
XT hard disk support:
Compaq SMART2 support:
Mulex DAC960/DAC1100 PCI RAID Controller support:RAID镜像用的。
Loopback device support:
Network block device support:网络块设备支持。如果想访问网上邻居的东西,就选上。
Logical volume manager(LVM)support:逻辑卷管理支持。
Multiple devices driver support:多设备驱动支持。
RAM disk support:RAM盘支持。

9. Networking options
网络选项。这里配置的是网络协议。内容太多了,不一一介绍了,自己看吧,如果你对网络协议有所了解的话,应该可以看懂的。如果懒得看,使用缺省选项(肯定要选中TCP/IP networking哦)就可以了。让我们看看,TCP/IP、ATM、IPX、DECnet、Appletalk……支持的协议好多哦,IPv6也支持了,Qos and/or fair queueing(服务质量公平调度)也支持了,还有kHTTPd,不过这些都还在实验阶段。

10. Telephony Support
电话支持。linux下可以支持电话卡,这样你就可以在IP上使用普通的电话提供语音服务了。记住,电话卡可和modem没有任何关系哦。

11. ATA/IDE/MFM/RLL support
这个是有关各种接口的硬盘/光驱/磁带/软盘支持的,内容太多了,使用缺省的选项吧,如果你使用了比较特殊的设备,比如PCMCIA等,就到里面自己找相应的选项吧。

12. SCSI support
SCSI设备的支持。我没有SCSI的设备,所以根本就不用选,如果你用了SCSI的硬盘/光驱/磁带等设备,自己找好了。

13. Fusion MPT device support
需要Fusion MPT兼容PCI适配器,不用选。

14. I2O device support
需要I2O接口适配器支持,在智能Input/Output(I2O)体系接口中使用。

15. Network device support
网络设备支持。上面选好协议了,现在该选设备了,可想而知,内容肯定多得很。还好还好,里面大概分类了,有ARCnet设备、Ethernet(10 or 100 Mbit)、Ethernet(1000Mbit)、Wireless LAN(non-hamradio)、Token Ring device、Wan interfaces、PCMCIA network device support几大类。我用的是10/100M的以太网,看来只需要选则这个了。还是10/100M的以太网设备熟悉,内容虽然多,一眼就可以看到我所用的RealTeck RTL-8139 PCI Fast Ethernet Adapter support,为了免得麻烦,编译到内核里面好了,不选M了,选Y。耐心点,一般说来你都能找到自己用的网卡。如果没有,你只好自己到厂商那里去要驱动了。

16. Amateur Radio support
配置业余无线广播。

17. IrDA(infrared)support
红外线支持。

18. ISDN subsystem
如果你使用ISDN上网,这个就必不可少了。

19. Old CD-ROM drivers(not SCSI、not IDE)
做的可真周到,原来那些非SCSI/IDE口的光驱谁还在用啊,自己选吧,用IDE的CD-ROM不用选。

20. Character devices
字符设备。这个内容又太多了,先使用缺省设置,需要的话自己就修改。把大类介绍一下吧:
I2C support:I2C是Philips极力推动的微控制应用中使用的低速串行总线协议。如果你要选择下面的Video For linux,该项必选。
Mice:鼠标。现在可以支持总线、串口、PS/2、C&T 82C710 mouse port、PC110 digitizer pad,自己根据需要选择。
Joysticks:手柄。即使在linux下把手柄驱动起来意义也不是太大,游戏太少了。
Watchdog Cards:虽然称为Cards,这个可以用纯软件来实现,当然也有硬件的。如果你把这个选中,那么就会在你的/dev下创建一个名为watchdog的文件,它可以记录你的系统的运行情况,一直到系统重新启动的1分钟左右。有了这个文件,你就可以恢复系统到重启前的状态了。
Video For linux:支持有关的音频/视频卡。
Ftape, the floppy tape device driver:
PCMCIA character device support:

21. File systems
文件系统。内容又太多了,老法子,在缺省选项的基础上进行修改。介绍以下几项:
Quota support:Quota可以限制每个用户可以使用的硬盘空间的上限,在多用户共同使用一台主机的情况中十分有效。
DOS FAT fs support:DOS FAT文件格式的支持,可以支持FAT16、FAT32。
ISO 9660 CD-ROM file system support:光盘使用的就是ISO 9660的文件格式。
NTFS file system support:ntfs是NT使用的文件格式。
/proc file system support:/proc文件系统是linux提供给用户和系统进行交互的通道,建议选上,否则有些功能没法正确执行。
还有另外三个大类都归到这儿了:Network File Systems(网络文件系统)、Partition Types(分区类型)、Native Language Support(本地语言支持)。值得一提的是Network File Systems里面的两种:NFS和SMB分别是linux和Windows相互以网络邻居的形式访问对方所使用的文件系统,根据需要加以选择。

22. Console drivers
控制台驱动。一般使用VGA text console就可以了,标准的80*25的文本控制台。

23. Sound
声卡驱动。如果你能在列表中找到声卡驱动那自然最好,否则就试试OSS了。

24. USB supprot
USB支持。很多USB设备,比如鼠标、调制解调器、打印机、扫描仪等,在linux都可以得到支持,根据需要自行选择。

25. Kernel hacking
配置了这个,即使在系统崩溃时,你也可以进行一定的工作了。普通用户是用不着这个功能的。
至于选项,因为比较复杂,只是简单做一介绍,编译时应视具体情况,参考帮助的内容再
加以选择。


配置完内核后存盘退出,或者写入confg文件中,方便下次使用和参考。


7 内核的编译和安装


7.1 编译内核和内核模块


make dep
make clean
make bzImage或make zImage
make modules

注解:第一个命令make dep实际上读取配置过程生成的配置文件,来创建对应于配置的依赖关系树,从而决定哪些需要编译而那些不需要;第二命令make clean完成删除前面步骤留下的文件,以避免出现一些错误;make zImage和make bzImage则实现完全编译内核,二者生成的内核都是使用gzip压缩的,只要使用一个就够了,它们的区别在于使用make bzImage可以生成大一点的内核。建议大家使用make bzImage命令。make modules表示生成相应的功能模块。


ps:博主在编译此版本内核时出现以下错误:

/usr/src/linux-2.6.32.61/usr/include/asm/ptrace.h:5: included file ‘file/linkage.h‘ is not exported

make[2]: ***[/usr/src/linux-2.6.32.61/usr/include/asm/.check] error 123
make[1]:***[headers_check] error 2

make:***[vmlinux] error 2

解决方法:编辑linux-2.6.32.61/arch/x86/include/asm/ptrace.h,注释掉以下三行:

#include<linux/linkage.h>

extern asmregparm long syscall_trace_enter(struct pt_regs *);  (146行处)

extern asmregparm void syscall_trace_leave(struct pt_regs *);

注意此处是c语言的头文件,注释方法为/*......*/。

增加以下两行:

extern long syscall_trace_enter(struct pt_regs *);

extern void syscall_trace_leave(struct pt_regs *);  

通过修改syscall_trace_enter和syscall_trace_leave函数的类型而解决问题。


7.2 安装模块


make module_install

相应的在/lib/modules 底下建立起与这个内核相关的模块。

注解:如果同一个版本的模块被反复编译后来安装时,会产生模块放置目录冲突的问题,两个解决办法:

1. 先将旧的模块目彔更名,然后才安装核心模块到目标目彔去;
2. 在 make menuconfig 时,那个 General setup 内的 Local version 修改成新的名称。


7.3 安装内核


cp /usr/src/kernels/linux-2.6.32.61/arch/x86/bzImage /boot/vmlinuz-2.6.32.61

cp /usr/src/kernels/linux-2.6.32.61/System.map /boot/System.map-2.6.32.61

cp /usr/src/kernels/linux-2.6.32.61/.config /boot/config-2.6.32.61

注解:配置文件一并复制备份。

建立相应的initrd:mkinitrd -v /boot/initrd-2.6.32.61.img 2.6.32.61


7.4 编辑开机选单(grub),添加启动项


vim /boot/grub/menu.lst:

title CentOS testing kernel
   root (hd0,0)
   kernel /vmlinuz-2.6.32.61 ro root=LABEL=/ rhgb
   initrd /initrd-2.6.32.61.img


7.5 重启并选择新内核开机


重启选择新内核成功开机后,可用过uname -a查看当前内核版本信息:

uname -a

至此,内核编译与安装完成。

                                                                                                                     ——Rango Chen



本文出自 “游响云停” 博客,请务必保留此出处http://rangochen.blog.51cto.com/2445286/1388626

Linux基础篇之内核编译与管理,布布扣,bubuko.com

Linux基础篇之内核编译与管理

上一篇:准循环 LDPC 码的多码长设计 | 带你读《5G-NR信道编码》之十


下一篇:Linux中Grep常用的15个例子