第26章 Linux内核编译与管理

我们说的Linux其实指的就是内核(kernel)而已。这个内核控制你主机的所有硬件并提供系统所有的功能,所以你说它重不重要啊!我们开机的时候其实就是利用开机管理程序加载这个内核文件来检测硬件,在内核加载适当的驱动程序后,你的系统才能够顺利运行。现今的系统由于强调在线升级机制,因此非常不建议自定义内核编译!但是,如果你想要将你的 Linux 安装到 USB 移动设备,想要将你的 Eee PC(上网本)安装自己的 Linux,想让你的 Linux 可以驱动你的上网本,此时,内核编译就是相当重要的一个任务了!这一篇比较高级,如果你对系统移植没有兴趣的话,这一篇可以先略过。

26.1 编译前的任务:认识内核与取得内核源代码

我们在第1章里面就谈过Linux其实指的是内核。这个“内核”(kernel)是整个操作系统的最底层,它负责了整个硬件的驱动以及提供各种系统所需的内核功能,包括防火墙机制、是否支持LVM或Quota等文件系统,这些都是内核所负责的。所以,在第20章的启动流程中,我们也会看到MBR内的loader加载内核文件来驱动整个系统的硬件呢!也就是说,如果你的内核不认识某个最新的硬件,那么该硬件也就无法被驱动,你当然也就无法使用该硬件。

26.1.1 什么是内核(Kernel)

这已经是整个Linux基础的最后一篇了,所以,下面这些数据你应该都要“很有概念”才行。不能只是“好像有印象”。好了,那就复习一下内核的相关知识吧!

Kernel

还记得我们在第11章的bash shell提到过:计算机真正在工作的东西其实是“硬件”,例如数值运算要使用到CPU,数据存储要使用到硬盘,图形显示会用到显卡,音乐发声要有声卡,连接 Internet 可能需要网卡等。那么如何控制这些硬件呢?那就是内核的工作了!也就是说,你所希望计算机帮你达成的各项工作都需要通过“内核”的帮助才行。当然,如果你想要达成的工作是内核所没有提供的,那么你自然就没有办法通过内核来控制计算机使它工作。

举例来说,如果你想要有某个网络功能(例如内核防火墙机制),但是你的内核偏偏忘记加进去这项功能,那么不论你如何“卖力”地设置该网络组件,很抱歉!不来电!换句话说,你想要让计算机进行的工作,都必须要内核支持才可以。这个标准不论在Windows或Linux上都相同。如果有一个人开发出来一个全新的硬件,目前的内核不论Windows或Linux都不支持,那么不论你用什么系统,这个硬件都是英雄无用武之地。那么是否了解了“内核”的重要了呢?所以我们才需要来了解一下如何编译我们的内核。

那么内核到底是什么啊?其实内核就是系统上面的一个文件而已,这个文件包含了驱动主机各项硬件的检测程序与驱动模块。在第20章的开机流程分析中,我们也提到这个文件被读入主存储器的时机,当系统读完BIOS并加载MBR内的引导装载程序后,就能够加载内核到内存当中。然后内核开始检测硬件,挂载根目录并取得内核模块来驱动所有的硬件,之后调用/sbin/init就能够依序启动所有系统所需要的服务了!

这个内核文件通常被放置在/boot/vmlinuz 中,不过也不见得,因为一台主机上面可以拥有多个内核文件,只是开机的时候仅能选择一个来加载而已。甚至我们也可以在一个 distribution上面放置多个内核,然后以这些内核来做成多重开机呢!

内核模块(kernel module)的用途

既然内核文件都已经包含了硬件检测与驱动模块,那么什么是内核模块啊?要注意的是,现在的硬件更新速度太快了,如果我的内核比较旧,但我换了新的硬件,那么,这个内核肯定无法支持。怎么办?重新拿一个新的内核来处理吗?开玩笑,内核的编译过程可是很麻烦的。

所以,为了这个缘故,我们的Linux很早之前就已经开始使用所谓的模块化设置了!即是将一些不常用的类似驱动程序的内容独立出内核,编译成为模块,然后,内核可以在系统正常运行的过程当中加载这个模块到内核的支持。如此一来,我在不需要改动内核的前提之下,只要编译出适当的内核模块并且加载它,我的Linux就可以使用这个硬件,简单又方便!

那我的模块放在哪里啊?可恶!怎么会问这个傻问题呢?当然一定要知道的。就是/lib/modules/$(uname-r)/kernel/当中。

内核编译

刚才上面谈到的内核其实是一个文件,那么这个文件怎么来的?当然是通过源代码(sourcecode)编译而成的啊!因为内核是直接被读入到内存当中的,所以当然要将它编译成为系统可以认识的数据才行!也就是说,我们必须要取得内核的源代码,然后利用第 22 章 Tarball安装方式提到的编译概念来实现内核的编译才行啊!(这也是本章的重点啊!)

关于驱动程序:是厂商的责任还是内核的责任

现在我们知道硬件的驱动程序可以编译成为内核模块,所以可以在不改变内核的前提下驱动你的新硬件。但是,很多朋友还是常常感到困惑,就是 Linux 上面针对最新硬件的驱动程序总是慢了几个脚步,所以觉得好像Linux的支持度不足。其实不可以这么说的,为什么呢?因为在Windows上面,对于最新硬件的驱动程序需求,基本上,也都是厂商提供的驱动程序才能让该硬件工作,因此,在这个驱动程序开发的工作上面来说,应该是属于硬件发展厂商的问题,因为他要我们买他的硬件,自然就要提供消费者能够使用的驱动程序。

所以,如果大家想要让某个硬件能够在 Linux 上面跑的话,那么似乎可以发起联名的方式,强烈要求硬件开发商发展 Linux 上面的驱动程序!这样一来,也可以促进 Linux 的发展呢!

26.1.2 更新内核的目的

除了 BIOS 之外,内核是操作系统中最早被加载到内存的,它包含了所有可以让硬件与软件工作的信息,所以,如果没有搞定内核的话,那么你的系统肯定会有点小问题!好了,那么是不是将所有目前内核有支持的东西都编译进去我的内核中,那就可以支持目前所有的硬件与可执行的工作。

这话说得是没错,但是你是否曾经看过一个为了怕自己今天出门会口渴、会饿、会冷、会热、会被车撞、会摔跤,而在自己的大包包里面放了大瓶矿泉水、便当、厚外套、短裤、防撞钢梁、止滑垫等一大堆东西,结果却累死在半路上的案例吗?当然有!但是很少。我相信不太有人会这样做!取而代之的是会看一下天气,冷了就只带外套,热了就只带短衣,出远门到没有便利商店的地方才多带矿泉水⋯⋯

说这个干什么?就是要你了解到,内核的编译重点在于你要你的Linux做什么,是的,如果没有必要的工作,就干脆不要加在你的内核当中了!这样才能让你的Linux跑得更稳、更顺畅!这也是为什么我们要编译内核的最主要原因了!

Linux内核特色与默认内核对终端用户的角色

Linux的内核有几个主要的特色,除了可以随时随各人喜好而改动之外,版本改动次数太频繁也是一个特点。所以,除非你有特殊需求,否则一次编译成功就可以。不需要随时保持最新的内核版本,而且也没有必要(编译一次内核要很久的)。话说到这里又突然想到看到的一篇文章,大意是说老板想要雇用的人会希望是Linux的老手,因为他们比较容易了解问题的所在,除此之外,如果有任何问题发生,由于其使用 Linux 是可以随时修补漏洞的。但是如果是Windows的话,就得要将机器关闭,直到MS推出修复补丁后才能再启用。

那么是否我就一定需要在安装好了Linux之后就赶紧编译内核呢?,老实说,并不需要的,这是因为几乎每一个distribution都已经默认编译好了相当大量的模块了,所以用户常常或者可能会使用到的数据都已经被编译成为模块,也因此,我们用户确实不太需要重新来编译内核,尤其是普通用户,由于系统已经将内核编译得相当适合普通用户使用了,因此一般入门的用户基本上不太需要编译内核。

内核编译的可能目的

OK!那么鸟哥闲着没事干跑来写个什么东西?既然都不需要编译内核还写编译内核的文章,鸟哥卖弄才学呀?很抱歉,鸟哥虽然是个“不学有术”的混混,却也不会平白无故地写东西请你来指教。当然是有需要才会来编译内核。编译内核的时机可以归纳为几大类:

新功能的需求

我需要新的功能,而这个功能只有在新的内核里面才有,那么为了获得这个功能,只好来重新编译我的内核了。例如iptables这个防火墙机制只有在2.4.xx以后的版本里面才有,而新开发的主机板芯片组很多也需要新的内核推出之后才能正常而且有效率地工作。

原内核太过臃肿

如果你是那种对于系统“稳定性”要求很高的人,对于内核多编译了很多莫名其妙的功能而不太喜欢的时候,那么就可以重新编译内核来取消掉该功能。

与硬件搭配的稳定性

由于原本 Linux内核大多是针对 Intel的 CPU来做开发的,所以如果你的 CPU是 AMD的系统时,有可能(注意:只是有可能,不见得一定会如此)会让系统跑得不太稳。此外,内核也可能没有正确的驱动新的硬件,此时就得重新编译内核来让系统取得正确的模块才好。

其他需求(如嵌入式系统)

就是你需要特殊的环境需求时,就得自行设计你的内核!(像是一些商业的软件包系统,由于需要较为精简的操作系统,那么它们的内核就需要更精简了!)

另外,需要注意重新编译内核虽然可以针对你的硬件做最佳化的步骤(例如刚才提到的 CPU的问题),不过由于这些优化步骤对于整体性能的影响是很小很小的,因此如果是为了增加性能来编译内核的话,基本上,效益不大。然而,如果是针对系统稳定性来考虑的话,那么就有充分的理由来支持你重新编译内核。

如果系统已经运行很久了,而且也没有什么大问题,加上你又不增加冷门的硬件,那么建议就不需要重新编译内核了,因为重新编译内核的最主要目的是想让系统变得更稳,既然你的Linux主机已经达到这个目的了,何必再编译内核?不过,就如同前面提到的,由于默认的内核不见得适合你的需要,加上默认的内核可能并无法与你的硬件配备相配合,此时才开始考虑重新编译内核吧!

早期鸟哥是强调最好重新编译内核的一群。不过,最近这个想法改变了。既然原本的distribution 都已经帮我们考虑好如何使用内核了,那么,我们也不需要再重新的编译内核。尤其是 distribution 都会主动释出新版的内核 RPM 版本,所以,实在不需要自己重新编译的!当然啦,如同前面提到的,如果你有特殊需求的话,那就另当别论!

由于内核的主要工作是控制硬件,所以编译内核之前,请先了解一下你的硬件配备与你这台主机将用于做什么,由于内核是越简单越好,所以只要将这台主机想要的功能编进去就好了!其他的就不用去理它。

26.1.3 内核的版本

内核的版本问题我们在第1章已经谈论过,主要的版本定义为“[主].[次].[发布]-[修改]”的样式。你只要知道2.6.x是稳定版本,2.5.x是测试版本即可。我们要使用最新的内核来重新编译内核时,大多就是使用那种偶数的内核版本。不过这里还是要再提一遍,就是2.4.x与2.6.x是两个具有相当大差异的内核版本,两者之间使用到的函数库基本上已经不相同了,所以在升级之前,如果你的内核原本是2.4.xx版,那么就升级到2.4.xx版本的最新版,不要由2.4.xx直接升级到2.6.xx版,否则到时可能会欲哭无泪,这个问题在讨论区一再地被提起!这里再次说明!

为什么不能从 2.4版升级到 2.6版呢?其实还是可以。只是过程很复杂! 我们知道软件包(packages)是架构在系统内核上面来进行编译、安装与执行的,也就是说,这些 packages与内核之间是有相关性的。这些 packages 会用到很多内核提供的功能。但是不同的[主][次]版本之间,它们提供的功能架构差异太大,因此,若你由 2.4 升级到 2.6 的话,那么绝大部分的软件都需要重新再编译!这样了解了为何不要在不同的版本间升级了吧?

此外,2.4.xx与2.6.xx的比较中,并不是2.6.xx就一定比2.4.xx还要新,因为这两种版本同时在进行维护与升级的工作!如果有兴趣的话,可以前往Linux内核网站http://www.kernel.org一看究竟,你就可以了解目前的内核变动情况了!

基本上,目前最新的 distributions,包括 CentOS, FC, SuSE, Mandriva 等,都使用 2.6 的内核,所以,你可以直接由 http://www.kernel.org 下载最新的 2.6.xx 版本的内核来尝试编译啊!目前(2009/07/27)鸟哥可以查到的最新版本是2.6.30,下面我们将主要以这个版本来测试。另外,由于较新的内核版本可能会多出一些选项,因此若有不同的选项也没有关系,稍微查看一下说明内容就可以了解。

26.1.4 内核源代码的取得方式

既然内核是个文件,要制作这个文件给系统使用则需要编译,既然要有编译,当然就得要有源代码啊!那么源代码怎么来?基本上,依据你的distributions去挑选的内核源代码来源主要有:

原本distribution提供的内核源代码文件

事实上,各主要 distributions在推出他们的产品时,其实已经都附上了内核源代码了!以我们的 CentOS 5.x 为例,你可以下载相关的内核 SRPM 的文件!由于 CentOS 5.x 一直有在进行更新动作,因此你也可以在 update 的目录下面找到内核源代码。如下链接所示:

原始推出内核代码:http://ftp.twaren.net/Linux/CentOS/5/os/SRPMS/

更新代码:http://ftp.twaren.net/Linux/CentOS/5/updates/SRPMS/

你或许会说:既然要重新编译,那么干嘛还要使用原本distributions发布的源代码啊?真没创意!话不是这么说,因为原本的distribution发布的源代码当中,含有他们设置好的默认设置值,所以,我们可以轻易就了解到当初他们是如何选择与内核及模块有关的各项设置参数的参数值,那么就可以利用这些可以配合我们Linux系统的默认参数来加以修改,如此一来,我们就可以修改内核,调整到自己喜欢的样子!而且编译的难度也会比较低一点!

取得最新的稳定版内核源代码

虽然使用 distribution 发布的内核 source code 来重新编译比较方便,但是,如此一来,新硬件所需要的新驱动程序也就无法通过原本的内核源代码来编译啊!所以,如果是站在要更新驱动程序的立场来看,当然使用最新的内核可能会比较好啊!

Linux 的内核目前是由其发明者 Linus Torvalds 所属团队在负责维护的,在其网站可以找到最新的kernel 信息。不过,美中不足的是目前的内核越来越大了(linux-2.6.30.3.tar.bz2 这一版这一个文件大约57MB了),所以如果你的ISP网速很慢的话,那么使用镜像站点来下载不失为一个好方法:

内核官网:http://www.kernel.org/

保留原本设置:利用patch升级内核源代码

如果你曾经自行编译过内核,那么你的系统当中应该已经存在前

几个版本的内核源代码,以及上次你自行编译的参数设置值才对;如果你只是想要在原本的内核下面加入某些特殊功能,而该功能已经针对内核源代码推出 patch 补丁文件时。那你该如何进行内核源代码的更新,以便后续的编译呢?

其实每一次内核发布时,除了发布完整的内核压缩文件之外,也会发布该版本与前一版本的差异性补丁(patch)文件,关于patch的制作我们已经在第22章当中提及,你可以自行前往参考。这里仅是要提供给你的信息是,每个内核的补丁仅有针对前一版的内核来分析而已,所以,万一你想要由 2.6.27 升级到 2.6.30 的话,那么你就得要下载 patch-2.6.28, patch-2.6.29, patch-2.6.30 等文件,然后依序一个一个去进行 patch 的动作后,才能够升级到2.6.30。这个重要!不要忘记了。

但是,如果你想要升级2.6.30的修改版本到2.6.30.3时,由于修改版本是针对2.6.30来制作的,因此你只要下载patch-2.6.30.3来直接将2.6.30升级至2.6.30.3即可。但反过来说,如果你要从2.6.30.2升级到2.6.30.3呢?很抱歉的是,并没有2.6.30.2到2.6.30.3的补丁文件,所以你必须要将2.6.30.2还原至2.6.30,然后才能使用patch-2.6.30.3来升级2.6.30。注意这个差异!

同样,如果是某个硬件或某些非官方认定的内核添加功能网站所推出的 patch 文件时,你也必须要了解该patch文件所适用的内核版本,然后才能够进行patch,否则容易出现重大错误。这个选项对于某些商业公司的工程师来说是很重要的。举例来说,鸟哥的一个高中同学在业界服务,他主要是进行类似EeePC开发的计划,然而该计划的硬件是该公司自行推出的,因此,该公司必须要自行搭配内核版本来设计他们自己的驱动程序,而该驱动程序并非GPL授权,因此他们就得要自行将驱动程序整合进内核。如果改天他们要将这个驱动程序发布,那么就得要利用patch的方式,将硬件驱动程序文件释出,我们就得要自行以补丁来更新内核。

在进行完patch之后,你可以直接检查一下原本的设置值,如果没有问题,就可以直接编译,而不需要重新选择内核的参数值,这也是一个省时间的方法啊!至于patchfile的下载,同样是在kernel的相同目录下,寻找文件名是patch开头的就是了。

26.1.5 内核源代码的解压缩/安装/观察

由于鸟哥是比较喜欢直接由内核官网取得原始内核的家伙,所以,下面的动作是使用2.6.30.3这个版本的内核来安装的。如果你想要使用distributions提供的SRPM来处理的话,得自行找到SRPM的相关安装方法来处理。其实看一下第 22 章就知道该如何处理啦。总之,本章的内核源代码是由下面的链接取得的:

ftp://linux.cis.nctu.edu.tw/kernel/linux/kernel/v2.6/linux-2.6.30.3.tar.bz2

内核源代码的解压缩与放置目录

鸟哥这里假设你也是下载上述链接内的文件,然后该文件放置到/root下面。由于2.6.x内核源代码一般建议放置于/usr/src/kernels/目录下面,因此你可以这样处理:

[root@www ~]# tar -jxvf linux-2.6.30.3.tar.bz2 -C/usr/src/kernels/

此时会在/usr/src/kernels下面产生一个新的目录,那就是linux-2.6.30.3这个目录。我们在下个小节会谈到的各项编译与设置都必须要在这个目录下面进行才行。好了,那么这个目录下面的相关文件有什么东东?下面就来谈谈:

内核源代码下的次目录

在上述内核目录下含有哪些重要数据呢?基本上有下面这些东西:

arch:与硬件平台有关的选项,大部分指的是CPU的类型,例如x86, x86_64, Xen虚拟支持等;

block:与区块设备较相关的设置数据,区块数据通常指的是大量储存媒质,还包括类似ext3等文件系统的支持是否允许等;

crypto:内核所支持的加密的技术,例如md5或者是des等;

Documentation:与内核有关的一堆帮助文档,若对内核有极大的兴趣,要瞧瞧这里!

drivers:一些硬件的驱动程序,例如显卡、网卡、PCI相关硬件等;

firmware:一些旧式硬件的微指令(固件)数据;

fs:内核所支持的文件系统,例如 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)。

这些数据先大致有个印象即可,至少将来如果你想要使用patch的方法加入额外的新功能时,你要将你的源代码放置于何处?这里就能够提供一些指引了。当然,最好还是跑到Documentation那个目录下面去瞧瞧正确的说明,对你的内核编译会更有帮助。

26.2 内核编译的前处理与内核功能选择

什么?内核编译还要进行前处理?没错!事实上,内核的目的在于管理硬件与提供系统内核功能,因此你必须要先找到你的系统硬件,并且规划你的主机将来的任务,这样才能够编译出适合你这台主机的内核。所以,整个内核编译的重要工作就是在挑选你想要的功能。下面鸟哥就以自己的一台主机软/硬件环境来说明,解释一下如何处理内核编译。

26.2.1 硬件环境查看与内核功能要求

鸟哥的一台主机硬件环境如下(通过/proc/cpuinfo及lspci查看):

CPU:AMD 的 Athlon64 3000+(旧式,不含虚拟化功能);

主板芯片组:ALi M1689 K8 北桥及 M5249, M1563 南桥芯片(较冷门的硬件);

显卡:AGP 8X 的 NVidia GeForce 6600LE;

内存:2.0GB内存;

硬盘:WD(西部数据) 2.5GB 硬盘,使用 ALi, ULi 5289 SATA 接口;

电源控制器:ALi M7101 Power Management Controller(PMU);

网卡:3Com 3c905C-TX/TX-M(对外);

网卡:Realtek Semiconductor RTL-8139/8139C/8139C+。

硬件大致如上,至于这部主机的需求,是希望作为将来在鸟哥上课时,可以通过虚拟化功能来处理学生的练习用虚拟机器。这部主机也是鸟哥用来放置学校上课教材的机器,因此,这部主机的 I/O需求必须要好一点,将来还需要开启防火墙、WWW服务器功能、FTP服务器功能等,基本上,用途就是一部小型的服务器环境,大致上需要这样的功能。

26.2.2 保持干净源代码:make mrproper

了解了硬件相关的数据后,我们还得要处理一下内核源代码下面的残留文件才行!假设我们是第一次编译,但是我们不清楚到下面载下来的源代码当中有没有保留目标文件(*.o)以及相关的设置文件存在,此时我们可以通过下面的方式来处理这些编译过程的目标文件以及设置文件:

[root@www linux-2.6.30.3]# make mrproper

请注意,这个操作会将你以前进行过的内核功能选择文件也删除掉,所以几乎只有第一次执行内核编译前才进行这个操作,其余的时刻,你想要删除前一次编译过程的残留数据,只要执行:

[root@www linux-2.6.30.3]# make clean

因为make clean 仅会删除类似目标文件之类的编译过程生成的中间文件,而不会删除设置文件。很重要的!千万不要搞乱了。好了,既然我们是第一次进行编译,因此,请执行“make mrproper”吧!

26.2.3 开始挑选内核功能:make XXconfig

不知道你有没有发现/boot/下面存在一个名为config-xxx的文件?那个文件其实就是内核功能列表文件。我们下面要进行的动作,其实就是制作出该文件。而我们后续小节所要进行的编译动作,其实也就是通过这个文件来处理的。内核功能的挑选,最后会在/usr/src/kernels/linux-2.6.30.3/下面生成一个名为.config的隐藏文件,这个文件就是/boot/config-xxx的文件。那么这个文件如何创建呢?你可以通过非常多的方法来创建这个文件。常见的方法有 [19]

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

最老式的功能挑选方法,每个选项都以条列式一条一条地列出让你选择,如果设置错误只能够再次选择,很不人性化啊!

大致的功能选择有上述的方法,不过鸟哥个人比较偏好 make menuconfig 这个选项。如果你喜欢使用图形界面,然后使用鼠标去挑选所需要的功能时,也能使用 make xconfig 或make gconfig,不过需要有相关的图形界面支持。如果你是升级内核源代码并且需要重新编译,那么使用make oldconfig会比较适当。好了,那么如何选择呢?以 make menuconfig 来说,出现的画面如图 26-1 所示。

看到图 26-1 之后,你会发现画面主要分为两大部分,一个是大框框内的反白光柱,另一个则是下面的小框框,里面有 select, exit 与help 三个选项的内容。这几个组件的大致用法如下:

左右方向键:可以移动最下面的<Select>, <Exit>, <Help>选项;

上下方向键:可以移动上面大框框部分的反白光标,若该行有箭头则表示该行内部还有其他具体选项需要来设置的意思;

选定选项:以上下键选择好想要设置的选项之后,并以左右键选择<Select>之后,按下[Enter]就可以进入该选项去作更进一步的详细设置;

可挑选的功能:在详细选项的设置当中,如果前面有[ ]或< >符号时,该选项才可以选择,而选择可以使用空格键来选择;

figure_0751_0424

图26-1 make menuconfig内核功能挑选菜单示意图

若为[]、<>则表示编译进内核;若为<M>则表示编译成模块。如果在不知道该选项为何时,且有模块可以选,那么就可以直接选择为模块。

当在具体选项中选择[Exit]后,并按下[Enter],那么就可以离开该具体选项。

基本上建议只要上下左右的方向键、空格键、[Enter]这六个按键就好了!不要使用[Esc],否则一不小心就有可能按错的。另外,关于整个内核功能的选择上面,建议你可以这样思考:

X “肯定”内核一定要的功能,直接编译进内核内;

X 可能在将来会用到的功能,那么尽量编译成为模块;

X 不知道那个东西要干嘛的,看帮助也看不懂的话,那么就保留默认值,或者将它编译成为模块。

总之,尽量保持内核小而美,剩下的功能就编译成为模块,尤其是需要考虑到将来扩展性,像鸟哥之前认为螃蟹卡就够我用的了,结果,后来竟然网站流量大增,鸟哥只好改换3Com的网卡。不过,我的内核却没有相关的模块可以使用,因为鸟哥自己编译的内核忘记加入这个模块了。最后,只好重新编译一次内核的模块,真是惨痛的教训啊!

26.2.4 内核功能细项选择

由上面的图示当中,我们知道内核可以选择的选项有很多啊!光是首页,就有 16 个选项,每个选项内还有不同的子选项!真是很麻烦。每个选项其实都可能有<Help>的说明,所以,如果看到不懂的选项,务必要使用Help查阅查阅!好了,下面我们就一个一个选项来看看如何选择吧!

General setup

与Linux最相关的程序互动、内核版本说明、是否使用开发中程序代码等信息都在这里设置的。这里的选项主要都是针对内核与程序之间的相关性来设计的,基本上,保留默认值即可!不要随便取消下面的任何一个选项,因为可能会造成某些程序无法被同时执行的困境。不过下面有非常多新的功能,如果你有不清楚的地方,可以按<Help>进入查阅,里面会有一些建议!你可以依据Help的建议来选择新功能的启动与否。

[ ] Prompt for development and/or incomplete code/drivers

这个建议不要选择,因为我们不是内核专家,不需要使用开发中或不完整的程序代码!

(vbird) Local version - append to kernel release

[*] Automatically append version information to the version string

我希望我的内核版本成为 2.6.30.3.vbird,那这里可以就这样设置!

Kernel compression mode(Bzip2) —->

建议选择成为 Bzip2 即可,因为压缩比较佳。

[*] Support for paging of anonymous memory(swap)

任何人均可访问 swap 是合理的,所以这里务必要勾选。

[*] System V IPC

IPC 是 Inter Process Communication(程序通信)缩写,与程序通信有关,要选。

[*] BSD Process Accounting

[ ] BSD Process Accounting version 3 file format

与标准 UNIX(BSD)的程序支持有关,但不要支持 version 3,可能有兼容性问题。

[ ] Export task/process statistics through netlink(EXPERIMENTAL)

这个额外的进阶选项可以将它取消的。

[*] Auditing support

[*] Enable system-call auditing support

上面这两个是额外内核功能(如 SELinux)加载时所需要的设置,务必选择!

RCU Subsystem —->

RCU Implementation(Classic RCU) —->

选择标准 RCU 即可,不需要使用大量 CPU 的整合功能。

<M> Kernel .config support

[ ] Enable access to .config through/proc/config.gz(NEW)

让 .config 这个内核功能列表可以写入实际的内核文件中。

(17)Kernel log buffer size(16 => 64KB, 17 => 128KB)

[ ] Control Group support(NEW) —->

整合 CPU 或分离设备的功能,属于高级设置,我们先不要使用这功能。

[*] Create deprecated sysfs layout for older userspace tools(NEW)

如果使用支持旧式设备,如/sys/devices,这里要勾选,但如果是 2008

年后的 distribution,这里可能需要取消。CentOS 5.x 要选的。

-*- Kernel->user space relay support(formerly relayfs)

-*- Namespaces support

[*] UTS namespace(NEW)

[*] IPC namespace(NEW)

使用 uname 时,会输出较多的信息,所以可以尝试选择看看。

[*] Initial RAM filesystem and RAM disk(initramfs/initrd)support

() Initramfs source file(s)

这是一定要的!因为要支持开机时加载 initail RAM disk 嘛!

[*] Optimize for size

可以减低内核的文件大小,其实是 gcc 参数使用 -Os 而不是 -O2

[ ] Configure standard kernel features(for small systems) —->

给嵌入式系统使用的,我们用 PC,所以这里不选。

[ ] Strip assembler-generated symbols during link(NEW)

[ ] Disable heap randomization(NEW)

2000 年后推出的版本,可以取消这个选项。

Choose SLAB allocator(SLAB) —->

[*] Profiling support(EXPERIMENTAL)

[ ] Activate markers(NEW)

<M> OProfile system profiling(EXPERIMENTAL)

[ ] OProfile AMD IBS support(EXPERIMENTAL)(NEW)

[*] Kprobes

loadable module + block layer

要让你的内核能够支持动态的内核模块,那么下面的第一个设置就得要启动才行!至于第二个block layer则默认是启动的,你也可以进入该选项的详细设置,选择其中你认为需要的功能即可!

[*] Enable loadable module support —-> <==下面为子选项

—- Enable loadable module support

[ ] Forced module loading <==大概就是这个不要选,其他的都选起来!

[*] Module unloading

[*] Module versioning support

[*] Source checksum for all module

===========================================================================

-*- Enable the block layer —-> <==看吧!默认就是已经选择了!下面为子选项

[ ] Block layer data integrity support <==特殊存储设备支持,可以不选

IO Schedulers —->

<*> Anticipatory I/O scheduler <==较复杂的一种I/O调度

<*> Deadline I/O scheduler <==较适用于 database 的载入

<*> CFQ I/O scheduler  <==较适用于 desktop 的环境

Default I/O scheduler(Deadline) —-> <==适用于鸟哥的机器环境

CPU的类型与功能选择

进入“Processor type and features”后,请挑选你主机的实际 CPU 形式。鸟哥这里使用的是 Athlon 64 的 CPU,而且鸟哥的主机还有启动 Xen 这个虚拟化的服务(在一部主机上面同时启动多个操作系统),因此,所以下面的选择是这样的:

[*] Tickless System(Dynamic Ticks) <==可增加一些省电功能

[ ] High Resolution Timer Support

[*] Symmetric multi-processing support <==多内核 CPU 环境必选

[ ] Support sparse irq numbering

[*] Enable MPS table    <==让多 CPU 支持 ACPI

[ ] Support for extended(non-PC)x86 platforms

[*] Single-depth WCHAN output

[*] Paravirtualized guest support —-> <==支持半虚拟化功能

—- Paravirtualized guest support <==下面为 Xen 与 KVM 两种虚拟机器支持!

[*] Xen guest support

(32) Maximum allowed size of a domain in gigabytes

[*] Enable Xen debug and tuning parameters in debugfs

[n] KVM paravirtualized clock

[*] KVM Guest support

-*- Enable paravirtualization code

===========================================================================

[ ] paravirt-ops debugging(NEW) <==不需要具有 debug 的功能

[ ] Memtest

Processor family(Opteron/Athlon64/Hammer/K8) —-> <==要选对啊!

[*] AMD IOMMU support <==启动 AMD 的 IOMMU 功能!

(8)Maximum number of CPUs

[ ] SMT(Hyperthreading)scheduler support <==Intel CPU 的超线程功能

[*] Multi-core scheduler support <==多内核功能的支持

Preemption Model(No Forced Preemption(Server)) —->

这是与程序有关的设置选项,鸟哥这里新建 Server 主机,因此选这项!

如果是桌面计算机的使用,建议选择 desktop 选项。

[ ] Reroute for broken boot IRQs

[*] Machine Check Exception <==可将内核检测的错误返回到终端机显示!

[*] Intel MCE features(NEW)

[*] AMD MCE features(NEW)

< > Dell laptop support

<M>/dev/cpu/microcode - microcode support

[ ] Intel microcode patch loading support

[*] AMD microcode patch loading support

<M>/dev/cpu/*/msr - Model-specific register support

<>/dev/cpu//cpuid - CPU information support

< >/sys/kernel/debug/x86/cpu/* - CPU Debug support

[ ] Numa Memory Allocation and Scheduler Support

Memory model(Sparse Memory) —->

[*] Sparse Memory virtual memmap <==可强化一些内核性能

[ ] Allow for memory hot-add

[*] Add LRU list to track non-evictable pages

(65536)Low address space to protect from user allocation

[ ] Check for low memory corruption

[*] Reserve low 64K of RAM on AMI/Phoenix BIOSen <==重新检测 BIOS 信息

[*] MTRR(Memory Type Range Register)support

可以让 CPU 具有读取内存特殊区块的能力,尤其在高性能的显卡方面,

可以提高性能。这个选项会产生/proc/mtrr,X 会读取它。

[*] MTRR cleanup support

(0) MTRR cleanup enable value(0-1)

(1) MTRR cleanup spare reg num(0-7)

[ ] x86 PAT support

[ ] EFI runtime service support

[*] Enable seccomp to safely compute untrusted bytecode

Timer frequency(300 HZ) —->

这个选项则与内核针对某个事件立即响应的速度有关。Server 用途可以调整到

300Hz 即可,如果是桌面计算机使用,需要调整高一点,例如 1000Hz 较佳!

[*] kexec system call

[ ] kernel crash dumps

-*- Support for hot-pluggable CPUs

[ ] Compat VDSO support <==旧式功能,可以不要选择

[ ] Built-in kernel command line <==正常开机选单(grub)环境,不需要此项功能

电源管理功能

如果选择了“Power management and ACPI options”之后,就会进入系统的电源管理机制中。其实电源管理机制还需要搭配主板以及CPU的相关省电功能,才能够实际达到省电的效率。不论是Server还是Desktop的使用,在目前电力不足的情况下,能省电就加以省电吧!

[*] Power Management support

[ ] Power Management Debug Support

[*] Suspend to RAM and standby

[ ] Hibernation(aka 'suspend to disk')

[*] ACPI(Advanced Configuration and Power Interface)Support —->

这是个较新的电源管理模块,由于选择后会增加内核约 70K,所以

对嵌入式系统来说,可能需要考虑考虑。至于 desktop/server 当然就选择啊!

—- ACPI(Advanced Configuration and Power Interface)Support

[ ] Deprecated/proc/acpi files

[*] Deprecated power/proc/acpi directories

[*] Future power/sys interface

[*] Deprecated/proc/acpi/event support

<M> AC Adapter

<M> Battery

<M> Button

-M- Video

<*> Fan

<*> Processor

<*> Thermal Zone

[ ] Debug Statements

<M> PCI slot detection driver

<M> Smart Battery System

===========================================================================

CPU Frequency scaling —->

可以经过内核修改 CPU 的运行频率,在说明文件当中也提及,还需要启动下面的

dynamic cpufreq governor 才可以顺利启动这个选项。

[*] CPU Frequency scaling

[*] Enable CPUfreq debugging

<M> CPU frequency translation statistics

[*] CPU frequency translation statistics details

Default CPUFreq governor(userspace) —->

-*- 'performance' governor

<M> 'powersave' governor

<M> 'userspace' governor for userspace frequency scaling

<M> 'ondemand' cpufreq policy governor

-*- 'conservative' cpufreq governor

CPUFreq processor drivers

<M> ACPI Processor P-States driver

<*> AMD Opteron/Athlon64 PowerNow! <==因为我们是 AMD 的 CPU 啊!

<M> Intel Enhanced SpeedStep(deprecated)

< > Intel Pentium 4 clock modulation

===========================================================================

-*- CPU idle PM support

Memory power savings —->

一些总线(bus)的选项

这个选项则与总线有关。分为最常见的 PCI 与 PCI-express 的支持,还有笔记本电脑常见的PCMCIA接口。要记住的是,那个PCI-E的界面务必要选择!不然你的新显卡可能会检测不到!

[*] PCI support

[*] Support mmconfig PCI config space access

[*] PCI Express support

<M> PCI Express Hotplug driver

[*] Root Port Advanced Error Reporting support

-*- Message Signaled Interrupts(MSI and MSI-X)

[] Enable deprecated pcifind API

[ ] PCI Debugging

<M> PCI Stub driver

[*] Interrupts on hypertransport devices

[*] PCI IOV support <==与虚拟化有关!请加选此项!

< > PCCard(PCMCIA/CardBus)support —-> <==鸟哥的主机不是笔记本,所以不选。

<*> Support for PCI Hotplug —-> <==不关机情况下,热拔插 PCI 设备

—- Support for PCI Hotplug

<M> Fake PCI Hotplug driver

<M> ACPI PCI Hotplug driver

<M> ACPI PCI Hotplug driver IBM extensions

[ ] CompactPCI Hotplug driver

<M> SHPC PCI Hotplug driver

编译成可执行文件的格式

选择“Executable file formats/Emulations”会见到如下选项。下面的选项必须要勾选才行。

因为是给Linux内核运行可执行文件之用的数据。通常是与编译行为有关。

[*] Kernel support for ELF binaries

[ ] Write ELF core dumps with partial segments

<*> Kernel support for MISC binaries

[*] IA32 Emulation <==因为我们这里是 64 位,因此 32 位为仿真结果

<M> IA32 a.out support

内核的网络功能

这个“Networking support”选项是相当重要的选项,因为它还包含了防火墙相关的选项,就是将来在服务器篇会谈到的防火墙 iptables 这个数据。所以,千万注意了!在这个设置选项当中,很多东西其实我们在基础篇还没有讲到,因为大部分的参数都与网络、防火墙有关。

由于防火墙是在启动网络之后再设置即可,所以绝大部分的内容都可以被编译成为模块,而且也建议你编成模块。有用到再载入到内核即可啊!

—- Networking support

Networking options —->

里面的数据全部都是重要的防火墙选项!尽量编成模块!

至于不确定功能的部分,就尽量保留默认值即可!

<*> Packet socket  <==网络包,当然要选择啊!

[*] Packet socket: mmapped IO

<*> UNIX domain sockets <==UNIX 插槽文件,也一定要选择啊!

<*> Transformation user configuration interface

<M> PF_KEY sockets

[*] TCP/IP networking <==能不选择 TCP/IP 吗?

[*] IP: multicasting

[*] IP: advanced router

Choose IP: FIB lookup algorithm(FIB_HASH) —->

[*] IP: policy routing

[*] IP: equal cost multipath

[*] IP: verbose route monitoring

[ ] IP: kernel level autoconfiguration

<M> IP: tunneling

<M> IP: GRE tunnels over IP

[*] IP: broadcast GRE over IP

[*] IP: multicast routing

[*] IP: PIM-SM version 1 support

[*] IP: PIM-SM version 2 support

[*] IP: TCP syncookie support(disabled per default)

<M> IP: AH transformation

<M> IP: ESP transformation

<M> IP: IPComp transformation

<M> IP: IPsec transport mode

<M> IP: IPsec tunnel mode

<*> IP: IPsec BEET mode

-*- Large Receive Offload(ipv4/tcp)

<M> INET: socket monitoring interface

[*] TCP: advanced congestion control —-> <==内部子选项全为模块

<M> The IPv6 protocol —-> <==除必选外,内部子选项全为模块

[*] NetLabel subsystem support

-*- Security Marking

[*] Network packet filtering framework(Netfilter) —->

这个就是我们一直讲的防火墙部分!里面子选项几乎全选择成为模块!

—- Network packet filtering framework(Netfilter)

[ ] Network packet filtering debugging <==debug 部分不选!

[*] Advanced netfilter configuration

[*] Bridged IP/ARP packets filtering

Core Netfilter Configuration —->

<M> IP virtual server support —->

IP: Netfilter Configuration —->

IPv6: Netfilter Configuration —->

<M> Ethernet Bridge tables(ebtables)support —->

上面的子选项,除了必选外,其他的都编成模块。原始没选的也请选为模块

===========================================================================

<M> Asynchronous Transfer Mode(ATM)

<M> Classical IP over ATM

[ ] Do NOT send ICMP if no neighbour

<M> LAN Emulation(LANE)support

< > Multi-Protocol Over ATM(MPOA)support

<M> RFC1483/2684 Bridged protocols

[ ] Per-VC IP filter kludge

<M> 802.1d Ethernet Bridging

<M> 802.1Q VLAN Support

[ ] GVRP(GARP VLAN Registration Protocol)support

<M> DECnet Support

<M> ANSI/IEEE 802.2 LLC type 2 Support

[ ] IPX: Full internal IPX network(NEW)

<M> Appletalk protocol support

< > Appletalk interfaces support

<M> Phonet protocols family

[*] QoS and/or fair queueing —-> <==内容同样全为模块!

[ ] Data Center Bridging support

Network testing —-> <==保留成模块默认值

===========================================================================

下面的则是一些特殊的网络设备,例如红外线、蓝牙。

如果不清楚的话,就使用模块吧!除非你真的知道不要该选项!

[ ] Amateur Radio support —->

< > CAN bus subsystem support —->

< > IrDA(infrared)subsystem support —->

<M> Bluetooth subsystem support —->

这个是蓝牙支持,同样,里面除了必选之外,其他通通挑选成为模块!

[*] Wireless —->

这个则是无线网络设备,里面保留默认值,但可编成模块的就选模块。

<M> WiMAX Wireless Broadband support —->

新一代的无线网络,也请勾选成为模块!

{M} RF switch subsystem support —->

各项设备的驱动程序

进入“Device Drivers”,这个是所有硬件设备的驱动程序库。光是看到里面这么多内容,鸟哥头都昏了。不过,为了你自己的主机好,建议你还是得要一个选项一个选项去挑选挑选才行。这里面的数据就与你主机的硬件有绝对的关系了!

在这里面真的很重要,因为很多数据都与你的硬件有关。内核推出时的默认值是比较符合一般状态的,所以很多数据其实保留默认值就可以编得很不错了!不过,也因为较符合一般状态,所以内核额外编译进来很多跟你的主机系统不符合的数据,例如网卡设备,你可以针对你的主板与相关硬件来进行编译。不过,还是要记得有扩展性的考虑。之前鸟哥不是谈过吗,我的网络卡由螃蟹卡换成 3Com 时,内核检测不出来。因为鸟哥并没有将 3Com 的网卡编译成为模块啊!

Generic Driver Options —-> <==与固件有关,保留默认值即可

<*> Connector - unified userspace <-> kernelspace linker —->

与用户/内核层级的信息沟通有关,务必要选择啊!

<M> Memory Technology Device(MTD)support —->

例如闪存(U盘之类)的支持,通常与嵌入式系统有关!

但由于我们也会用到移动设备,所以里面的数据全编为模块!

<M> Parallel port support —->

平行串行端口的支持,例如早期的 25 针打印机与 9 针鼠标等,子选项全编为模块

-*- Plug and Play support —-> <==不嗌唆!当然要选择这个选项

[*] Block devices —-> <==块设备,就是一些储存媒质!子选项内容请全编为模块

[*] Misc devices —-> <==一些较冷门的设备,建议还是全部编为模块

<*> ATA/ATAPI/MFM/RLL support —-> <==IDE 接口相关的芯片组

这个其实与主板的南桥芯片有关。由于鸟哥的主机为 ALi 的板子,所以:

<*> ALI M15x3 chipset support

除了可以保留默认值之外,你也可以将没用到的驱动程序取消选择。较重要的还有:

[ ] Support for SATA(deprecated; conflicts with libata SATA driver)

这个一定不能选!因为 SATA 的模块是在 SCSI 中!

<*> Include IDE/ATAPI CDROM support

IDE 的 CDROM 最好直接编译进内核!

其余的驱动程序鸟哥几乎都选择成为模块了!没用到的芯片也将 * 也改成 M。

===========================================================================

SCSI device support —->

这部分是 SCSI 储存媒质的驱动程序,请一定要选择!因为:

1. 因为 USB 设备用的就是仿真 SCSI 啊!

2. 因为 SATA 的设置选项就在这里面!

<M> RAID Transport Class

{M} SCSI device support

[*] legacy/proc/scsi/support

SCSI support type(disk, tape, CD-ROM)

<M> SCSI disk support <==几乎全编为模块即可!

<M> SCSI tape support

<M> SCSI OnStream SC-x0 tape support

<M> SCSI CDROM support

[*] Enable vendor-specific extensions(for SCSI CDROM)

<M> SCSI generic support

<M> SCSI media changer support

<M> SCSI Enclosure Support

Some SCSI devices(e.g. CD jukebox)support multiple LUNs

[*] Probe all LUNs on each SCSI device

[*] Verbose SCSI error reporting(kernel size +=12K)

[*] SCSI logging facility

[*] Asynchronous SCSI scanning

SCSI Transports —->  <==子选项保留默认值

[*] SCSI low-level drivers —-> <==主要是磁盘阵列卡,子选项可全选为模块

<M> SCSI Device Handlers —-> <==子选项全选为模块

< > OSD-Initiator library

===========================================================================

<M> Serial ATA(prod)and Parallel ATA(experimental)drivers —->

SATA 之类的磁盘驱动程序,这里的模块与 SCSI 模块是有相依属性的关系。

下面的子选项全部选择模块,尤其是 ALi 的这个选项,对鸟哥来说,是一定要勾选的

<M> ALi PATA support

[*] Multiple devices driver support(RAID and LVM) —->

RAID 与 LVM 怎可不选?我们第15章才讲过这东西!细项均保留默认值即可

[ ] Fusion MPT device support —->

一种高级的 SCSI 控制器,可选可不选!因为鸟哥这里不会用到,所以不选。

IEEE 1394(FireWire)support —->

这个就是俗称的“火线”,许多外接式设备可能会用这个接口,因此,

在此部分内的子选项部分,请务必设置为模块。不要忘了!

<M> I2O device support —->  <==子选项也全选为模块!

[ ] Macintosh device drivers —-> <==我们是 PC,所以不需要支持Mac

[*] Network device support —-> <==网络设备的支持是必选!

—- Network device support

[*] Enable older network device API compatibility

<M> Intermediate Functional Block support

<M> Dummy net driver support

<M> Bonding driver support

<M> EQL(serial line load balancing)support

<M> Universal TUN/TAP device driver support

<M> Virtual ethernet pair device

<M> General Instruments Surfboard 1000

< > ARCnet support —-> <==较早期的网卡规格,可不选择!

{M} PHY Device support and infrastructure —-> <==子选项全为模块

[*] Ethernet(10 or 100Mbit) —->

[*] Ethernet(1000 Mbit) —->

[*] Ethernet(10000 Mbit) —->

上面三个以太网络网卡支持,不论是否用得到,子选项请全编为模块来待命吧!

< > Token Ring driver support —-> <==IBM 的 LAN,可不选!

Wireless LAN —->

WiMAX Wireless Broadband devices —->

USB Network Adapters —->

上面三个为现阶段很热门的无线网络设备,所以全部内容的子选项全选择

为模块!免得将来你的主机加上新的无线设备时会找不到驱动程序!

[ ] Wan interfaces support —-> <==WAN 的广域网设备应该就不用选择了!

[ ] ATM drivers —-> <==高级的 ATM 设备也不用选吧!

<*> Xen network device frontend driver

<*> FDDI driver support

<M> Digital DEFTA/DEFEA/DEFPA adapter support

[ ]  Use MMIO instead of PIO(NEW)

<M> SysKonnect FDDI PCI support

<M> PLIP(parallel port)support

<M> PPP(point-to-point protocol)support

[*] PPP filtering

<M> PPP support for async serial ports

<M> PPP support for sync tty ports

<M> PPP Deflate compression

<M> PPP BSD-Compress compression

<M> PPP over ATM

如果你有 ADSL 拨接的话,呵呵!PPP 的设备也要选择上。

<M> SLIP(serial line)support

[*] CSLIP compressed headers

[*] Keepalive and linefill

[ ] Six bit SLIP encapsulation

[*] Fibre Channel driver support

===========================================================================

[ ] ISDN support —->

< > Telephony support —->

这两个设备没用到,所以也可以不要选择!

Input device support —->

这里面含有鼠标、键盘、游戏杆、触摸板等输入设备,尽量全选为模块吧!

Character devices —->

周边组件设备部分,也全选为模块吧!

{M} I2C support —->

还记得我们去检测主机板的温度与压力吧?那就是通过内核的这个 I2C

的模块功能!ALi 默认没有被编入内核,所以请进入选择成模块!

[ ] SPI support —->

[ ] GPIO Support —->

< > Dallas's 1-wire support —->

-*- Power supply class support —->

绝大部分都没有用到的东东,所以保留默认值,不选择。

<M> Hardware Monitoring support —->

硬件检测器的支持,记得也要挑选,然后内容全编为模块。

-*- Generic Thermal sysfs driver —->

[*] Watchdog Timer Support —-> <==需搭配 watchdog 服务

若搭配 watchdog 服务,可以设置在某些特定状况下重新启动主机。

Sonics Silicon Backplane —->

Multifunction device drivers —->

鸟哥没有这样的设备,所以也没有选择。

[ ] Voltage and Current Regulator Support —->

Multimedia devices —->

一堆多媒体设备,如图像采集卡、声卡。但如果你的 Linux 是台式机,

里面需要挑选成模块较佳!

Graphics support —-> <==这就重要了!选择显卡!

嘿嘿!重点之一,显卡的芯片组~刚才前面提到的都是主板对显卡的

总线支持(PCI-E 与 AGP),这里则是针对显卡芯片!鸟哥的显卡是 NVidia

的,所以将它选择即可!其他的可以编成模块。

<M> Sound card support —->

声卡部分,也全部选择成为模块。反正编成模块又不用钱

[*] HID Devices —-> <==人机接口设备,保留默认值即可(也可不选)

[*] USB support —->

不能不选的 USB,内容也全部是模块即可!尤其下面这三个:

<M> EHCI HCD(USB 2.0)support

<M> OHCI HCD support

<M> UHCI HCD(most Intel and VIA)support

<M> MMC/SD/SDIO card support —-> <==多媒体适配卡,保留默认值

< > Sony MemoryStick card support(EXPERIMENTAL) —->

-*- LED Support —->

[ ] Accessibility support —->

<M> InfiniBand support —-> <==高级网络设备

[*] EDAC - error detection and reporting —->

<M> Real Time Clock —-> <==内容选为模块吧!

[ ] DMA Engine support —->

[ ] Auxiliary Display support —->

< > Userspace I/O drivers —->

[*] Xen memory balloon driver

[*] Scrub pages before returning them to system

<*> Xen filesystem

[*] Create compatibility mount point/proc/xen

[ ] Staging drivers —->

[ ] X86 Platform Specific Device Drivers —->

一堆笔记本电脑的驱动,可以不选。

下面则与 Firmware Drivers 有关。基本上,都保留默认值就好了!

<M> BIOS Enhanced Disk Drive calls determine boot disk

[ ] Sets default behavior for EDD detection to off(NEW)

<M> BIOS update support for DELL systems via sysfs

<M> Dell Systems Management Base Driver

[*] Export DMI identification via sysfs to userspace

[*] iSCSI Boot Firmware Table Attributes

<M> iSCSI Boot Firmware Table Attributes module

文件系统的支持

文件系统的支持也是很重要的一项内核功能。因为如果不支持某个文件系统,那么我们的 Linux kernel 就无法认识,当然也就无法使用。例如 Quota, NTFS 等等特殊的文件系统。这部分也是有够麻烦,因为涉及内核是否能够支持某些文件系统,以及某些操作系统支持的partition table选项。在进行选择时,也务必要特别小心在意。尤其是我们常常用到的网络操作系统(NFS/Samba等),以及基础篇谈到的Quota等,你都得要勾选啊!否则是无法被支持的。比较有趣的是 NTFS 在这一版的内核里面竟然有支持可写入的选项,着实让鸟哥吓了一跳了!

<*> Second extended fs support

[*] Ext2 extended attributes

[*] Ext2 POSIX Access Control Lists

[*] Ext2 Security Labels

[*] Ext2 execute in place support

<*> Ext3 journalling file system support <==建议这里直接编进内核

[ ] Default to 'data=ordered' in ext3(legacy option)

[*] Ext3 extended attributes

[*] Ext3 POSIX Access Control Lists

[*] Ext3 Security Labels

<M> The Extended 4(ext4)filesystem

[*] Enable ext4dev compatibility

[*] Ext4 extended attributes(NEW)

[*] Ext4 POSIX Access Control Lists

[*] Ext4 Security Labels

上面是传统的 EXT2/EXT3 及高级的 EXT4 支持!除了 EXT4 外,其他编入内核吧!

===========================================================================

[ ] JBD(ext3)debugging support

[ ] JBD2(ext4)debugging support(NEW)

<M> Reiserfs support

[ ] Enable reiserfs debug mode(NEW)

[ ] Stats in/proc/fs/reiserfs(NEW)

[ ] ReiserFS extended attributes(NEW)

< > JFS filesystem support

<M> XFS filesystem support

[*] XFS Quota support

[*] XFS POSIX ACL support

[*] XFS Realtime subvolume support

< > OCFS2 file system support

[*] Dnotify support

[*] Inotify file change notification support

[*] Inotify support for userspace

[*] Quota support

[ ] Report quota messages through netlink interface

[*] Print quota warnings to console(OBSOLETE)

< > Old quota format support

<*> Quota format v2 support

<M> Kernel automounter support

<M> Kernel automounter version 4 support(also supports v3)

< > FUSE(Filesystem in Userspace)support

XFS 以及 Reiserfs 与 Quota 也是建议选择。

===========================================================================

Caches —->

CD-ROM/DVD Filesystems —-> <==CD内的文件格式,默认值即可

DOS/FAT/NT Filesystems —-> <==有支持 NTFS,要进入挑挑!

<M> MSDOS fs support

<M> VFAT(Windows-95)fs support

(950)Default codepage for FAT <==支持繁体中文

(utf8)Default iocharset for FAT <==只能支持utf8编码

<M> NTFS file system support

[ ] NTFS debugging support(NEW)

[*] NTFS write support

===========================================================================

Pseudo filesystems —->  <==类似/proc,保留默认值

[*] Miscellaneous filesystems —-> <==其他文件系统的支持,保留默认值

[*] Network File Systems —-> <==网络文件系统!很重要!

—- Network File Systems

<M> NFS client support

[*] NFS client support for NFS version 3

[*]  NFS client support for the NFSv3 ACL protocol extension

<M> NFS server support

[*] NFS server support for NFS version 3

[*]  NFS server support for the NFSv3 ACL protocol extension

< > SMB file system support(OBSOLETE, please use CIFS)

<M> CIFS support(advanced network filesystem, SMBFS successor)

最重要就这几项,其他保留默认值即可!

===========================================================================

Partition Types —->  <==分区类型,也是保持默认值即可!

-*- Native language support —-> <==选择默认的语系

—- Native language support

(utf8)Default NLS Option

<*> Traditional Chinese charset(Big5)

除了上述这两个之外,其他的请选择成为模块即可!

Kernel hacking、信息安全、密码应用

再接下来有个“Kernel hacking”的选项,那是与内核开发者比较有关的部分,这部分建议保留默认值即可,应该不需要去修改它,除非你想要进行内核方面的研究。然后下面有个“Security Options”,那是属于信息安全方面的设置,包括 SELinux 这个具体权限强化模块也在这里编入内核的!这部分可以做一些额外的设置。另外还有“Cryptographic API”这个密码应用程序接口工具选项,也是可以保留默认值。我们来看看有什么比较特殊的地方吧!

Security options —->

[*] Enable access key retention support

[*] Enable the/proc/keys file by which keys may be viewed

[*] Enable different security models

[ ] Enable the securityfs filesystem

[*] Socket and Networking Security Hooks

[*] XFRM(IPSec)Networking Security Hooks

[ ] Security hooks for pathname based access control

[ ] File POSIX Capabilities

[ ] Root Plug Support

[*] NSA SELinux Support

[*] NSA SELinux boot parameter

(1) NSA SELinux boot parameter default value

[*] NSA SELinux runtime disable

[*] NSA SELinux Development Support

[*] NSA SELinux AVC Statistics

(1) NSA SELinux checkreqprot default value

[ ] NSA SELinux maximum supported policy format version

[ ] Simplified Mandatory Access Control Kernel Support

[ ] TOMOYO Linux Support

[ ] Integrity Measurement Architecture(IMA)

基本上,这部分保留默认值就对了!你也会发现 NSA 的资料都是直接编进内核!

===========================================================================

Cryptographic API —->

基本上,除了下面这两个编译进内核之外,其他的通通选择成为模块吧!

{*} MD5 digest algorithm

{*} SHA1 digest algorithm

在密码应用程序接口方面,一般我们使用的账号密码登录利用的就是 MD5 这个加密机制,要让内核有支持才行啊!几乎所有的选项都做成模块即可!不过MD5与SHA1必须要直接由内核支持比较好!

虚拟化与函数库

虚拟化是近年来非常热门的一个议题,因为计算机的能力太强,所以时常闲置在那边,此时,我们可以通过虚拟化技术在一部主机上面同时启动多个操作系统来运行,这就是所谓的虚拟化。Linux内核已经主动纳入虚拟化功能。而 Linux 认可的虚拟化使用的机制为KVM(Kernel base Virtual Machine)。至于常用的内核函数库也可以全部编为模块。

[*] Virtualization —->

—- Virtualization

<M> Kernel-based Virtual Machine(KVM)support

<M> KVM for Intel processors support

<M> KVM for AMD processors support

[ ] KVM trace support(NEW)

<M> Virtio balloon driver(EXPERIMENTAL)

===========================================================================

Library routines —->

{M} CRC-CCITT functions

{M} CRC16 functions

{M} CRC calculation for the T10 Data Integrity Field

{M} CRC ITU-T V.41 functions

-*- CRC32 functions

<M> CRC7 functions

{*} CRC32c(Castagnoli, et al)Cyclic Redundancy-Check

最后,还有下面这两个选项,这两个选项与内核功能无关,但是与挑选时的设置文件有关:

Load an Alternate Configuration File

Save an Alternate Configuration File

这两个选项分别是存储刚才做好的所有选项的设置数据,另一个则是将其他人的选择读入。事实上,刚才我们所做的设置只要在离开时选择SAVE,那么这些选项通通会记录到目前这个目录下的. config 文件内。而我们也可以使用上面提到的 Save Configuration 这个选项来将刚才做完的设置存储成另外的文件,做成这个文件的好处是,你可以在下次在其他版本的内核作选择时,直接以 Load 来将这个文件的设置选项读入,这样可以减少你还要重新挑选一遍的困境啊!

要请你注意的是,上面的资料主要是适用在鸟哥的个人机器上面的,目前鸟哥比较习惯使用原本distributions提供的默认内核,因为会主动进行更新,所以鸟哥就懒得自己重编内核了。

此外,因为鸟哥重视的地方在于“网络服务器”上面,所以里头的设置少了相当多的桌面Linux 的硬件编译。所以,如果你想要编译出一个适合你的机器的内核,那么可能还有相当多的地方需要来修正的。不论如何,请随时以 Help 那个选项来看一看内容吧!反正Kernel重编的几率不大。花多一点时间重新编译一次,然后将该编译完成的参数文件存储下来,将来就可以直接将该文件调出来读入了!所以花多一点时间安装一次就好!那也是相当值得的!

26.3 内核的编译与安装

将最复杂的内核功能选择完毕后,接下来就是进行这些内核、内核模块的编译了!而编译完成后,当然就是需要使用。那如何使用新内核呢?就得要考虑 grub 这个玩意儿。下面我们就来处理处理。

26.3.1 编译内核与内核模块

内核与内核模块需要先编译起来,而编译的过程其实非常简单,你可以先使用“make help”去查阅一下所有可用编译参数,就会知道有下面这些基本功能:

[root@www linux-2.6.30.3]# make vmlinux <==未经压缩的内核

[root@www linux-2.6.30.3]# make modules <==仅内核模块

[root@www linux-2.6.30.3]# make bzImage <==经压缩过的内核(默认)

[root@www linux-2.6.30.3]# make all <==进行上述的三个操作

我们常见的/boot/下面的内核文件都是经过压缩过的内核文件,因此,上述的动作中比较常用的是 modules与 bzImage这两个,其中 bzImage第三个字母是英文大写的 I。bzImage可以制作出压缩过后的内核,也就是一般我们拿来进行系统开机的信息。所以,基本上我们会进行的操作是:

[root@www linux-2.6.30.3]# make clean <==先清除临时文件

[root@www linux-2.6.30.3]# make bzImage <==先编译内核

[root@www linux-2.6.30.3]# make modules <==再编译模块

上述的操作会花费非常长的时间,编译的动作依据你选择的选项以及你主机硬件的性能而不同。最后制作出来的数据是被放置在/usr/src/kernels/linux-2.6.30.3/这个目录下,还没有被放到系统的相关路径中。在上面的编译过程当中,如果有发生任何错误的话,很可能是由于内核选项的选择不好,可能你需要重新以 make menuconfig 再次检查一下你的相关设置。如果还是无法成功的话,那么或许将原本的内核数据内的.config文件复制到你的内核源文件目录下,然后据以修改,应该就可以顺利编译出你的内核了。最后注意到,执行了 make bzImage 后,最终的结果应该会像这样:

Root device is(8, 1)

Setup is 12696 bytes(padded to 12800 bytes).

System is 2207 kB

CRC 7701ab0e

Kernel: arch/x86/boot/bzImage is ready(#1)

[root@www linux-2.6.30.3]# ll arch/x86/boot/bzImage

-rw-r—r— 1 root root 2272432 7月 30 13:35 arch/x86/boot/bzImage

可以发现你的内核已经编译好而且放置在/usr/src/kernels/linux-2.6.30.3/arch/x86/boot/bzImage 里面。那个就是我们的内核文件。最重要就是它。我们等一下就会安装到这个文件。然后就是编译模块的部分。make modules 进行完毕后,就等着安装。

26.3.2 实际安装模块

安装模块前有个地方得要特别强调。我们知道模块是放置到/lib/modules/$(uname -r)目录下的,那如果同一个版本的模块被反复编译后来安装时,会不会产生冲突呢?举例来说,鸟哥这个2.6.30.3 的版本第一次编译完成且安装妥当后,发现有个小细节想要重新处理,因此又重新编译过一次,那两个版本一模一样时,模块放置的目录会一样,此时就会产生冲突了!如何是好?有两个解决方法:

先将旧的模块目录更名,然后才安装内核模块到目标目录去;

在 make menuconfig 时,将那个 General setup 内的Local version 修改成新的名称。

鸟哥建议使用第二个方式,因为如此一来,你的模块放置的目录名称就不会相同,这样也就能略过上述的目录同名问题。好,那么如何安装模块到正确的目标目录呢?很简单,同样使用make的功能即可:

[root@www linux-2.6.30.3]# make modules_install

[root@www linux-2.6.30.3]# ll/lib/modules/

drwxr-xr-x 3 root root 4096 7月 30 14:31 2.6.30.3vbird

看到否?最终会在/lib/modules 下面新建起你这个内核的相关模块。不错吧!模块这样就已经处理妥当。接下来,就是准备要进行内核的安装。哈哈!又跟grub有关。

26.3.3 开始安装新内核与多重内核菜单(grub)

现在我们知道内核文件放置在/usr/src/kernels/linux-2.6.30.3/arch/x86/boot/bzImage下,但是其实系统内核理论上都是摆在/boot下面且为vmlinuz开头的文件名。此外,我们也晓得一部主机是可以做成多重开机系统的!这样说,应该知道鸟哥想要干嘛了吧?对。我们将同时保留旧版的内核,并且新增新版的内核在我们的主机上面。

移动内核到/boot且保留旧内核文件

保留旧内核有什么好处呢?最大的好处是可以确保系统能够顺利开机。因为内核虽然被编译成功了,但是并不保证我们刚才挑选的内核选项完全适合于目前这部主机系统,可能有某些地方我们忘记选择了,这将导致新内核无法顺利驱动整个主机系统,更差的情况是,你的主机无法成功开机成功。此时,如果我们保留旧的内核,若新内核测试不通过,就用旧内核来启动啊!保证比较不会有问题嘛!新内核通常可以这样做的:

[root@www ~]# cp/usr/src/kernels/linux-2.6.30.3/arch/x86/boot/bzImage \

>/boot/vmlinuz-2.6.30.3vbird <==实际内核

[root@www ~]# cp/usr/src/kernels/linux-2.6.30.3/.config \

>/boot/config-2.6.30.3vbird <==建议设置文件也复制备份

新建相对应的 Initial Ram Disk(initrd)

还记得第20章谈过的initrd这个玩意儿吧?由于鸟哥的系统使用SATA磁盘,加上刚才SATA磁盘支持的功能并没有直接编译到内核去,所以当然要使用initrd来加载才行!使用如下的方法来建立initrd吧!记得搭配正确的内核版本。

[root@www ~]# mkinitrd -v/boot/initrd-2.6.30.3vbird.img 2.6.30.3vbird

…(前面省略)…

Adding module ehci-hcd

Adding module ohci-hcd

Adding module uhci-hcd

…(后面省略)…

编辑开机菜单(grub)

鸟哥这部测试机之前是使用Xen的内核来启动的,但因为Xen内核的制作比较复杂,本章并没有实现出 Xen 虚拟机器的内核。下面鸟哥使用的是刚才编译成功的内核来进行开机菜单的设置,你会看到的设置文件与你的环境可能会有不一样。那就来看看吧!

[root@www ~]# vim/boot/grub/menu.lst

default=0

timeout=10

splashimage=(hd0,0)/boot/grub/splash.xpm.gz

hiddenmenu

title CentOS(2.6.18-128.2.1.el5xen)

root(hd0,0)

kernel/boot/xen.gz-2.6.18-128.2.1.el5

module/boot/vmlinuz-2.6.18-128.2.1.el5xen ro root=LABEL=/rhgb quiet

module/boot/initrd-2.6.18-128.2.1.el5xen.img

title CentOS testing kernel from vbird

root(hd0,0)

kernel/boot/vmlinuz-2.6.30.3vbird ro root=LABEL=/rhgb

initrd/boot/initrd-2.6.30.3vbird.img

添加上述的特殊字体到你的设置文件当中。另外,你会发现我上头的default并没有修改到最新的那个内核的菜单上,因为我必须要测试一下新内核能否顺利开机!如果顺利开机且运行没有问题后,那么才来修改这个default的值吧!

重新以新内核开机、测试、修改

如果上述的操作都成功后,接下来就是重新开机并选择新内核来启动系统。如果系统顺利启动之后,你使用 uname -a 会出现类似下面的数据:

[root@www ~]# uname -a

Linux www.vbird.tsai 2.6.30.3vbird #1 SMP Thu Jul 30 13:34:31

CST 2009 x86_64 x86_64 x86_64 GNU/Linux

包括内核版本与支持的硬件平台都是OK的!那你所编译的内核就是差不多成功的。如果运行一阵子后,你的系统还是稳定的情况下,那就能够将default值使用这个新的内核来作为默认开机。这就是内核编译!那你也可以自己处理嵌入式系统的内核编译!^_^

26.4 额外(单一)内核模块编译

我们现在知道内核所支持的功能当中,有直接编译到内核内部的,也有使用外挂模块的,外挂模块可以简单想成就是驱动程序。那么也知道这些内核模块依据不同的版本,被分别放置到/lib/modules/$(uname -r)/kernel/目录中,各个硬件的驱动程序则是放置到/lib/modules/$(uname -r)/kernel/drivers/当中。换个角度再来思考一下,如果刚才我自己编译的数据中有些驱动程序忘记编译成为模块了,那是否需要重新进行上述的所有操作?又如果我想要使用硬件厂商释出的新驱动程序,那该如何是好?

26.4.1 编译前注意事项

由于我们的内核原本就有提供很多的内核工具给硬件开发商来使用,而硬件开发商也需要针对内核所提供的功能来设计他们的驱动程序模块,因此,我们如果想要自行使用硬件开发商所提供的模块来进行编译时,就需要使用到内核所提供的源文件当中所谓的头文件(header include file)来取得驱动模块所需要的一些函数库或头的定义。也因此我们常常会发现到,如果想要自行编译内核模块时,就得要拥有内核源代码。

那内核源代码我们知道它是可能放置在/usr/src/下面,早期的内核源代码被要求一定要放置到/usr/src/linux/目录下,不过,如果你有多个内核在一个 Linux 系统当中,而且使用的源代码并不相同时,问题可就大了!所以,在2.6版以后,内核使用比较有趣的方法来设计它的源代码放置目录,那就是以/lib/modules/$(uname -r)/build 及/lib/modules/$(uname -r)/source 这两个链接文件来指向正确的内核源代码放置目录。如果以我们刚才由 kernel 2.6.30.3 建立的内核模块来说,那么它的内核模块目录下面有什么?

[root@www ~]# ll -h/lib/modules/2.6.30.3vbird/

lrwxrwxrwx 1 root root 31 7月 30 14:29 build ->/usr/src/kernels/linux-2.6.30.3

drwxr-xr-x 10 root root 4.0K 7月 30 14:30 kernel

-rw-r—r— 1 root root 337K 7月 30 14:31 modules.alias

-rw-r—r— 1 root root 69 7月 30 14:31 modules.ccwmap

-rw-r—r— 1 root root 224K 7月 30 14:31 modules.dep

….(中间省略)….

lrwxrwxrwx 1 root root 31 7月 30 14:29 source ->/usr/src/kernels/linux-2.6.30.3

比较有趣的除了那两个链接文件之外,还有那个modules.dep文件也挺有趣的,那个文件是记录了内核模块的相依属性的地方,依据该文件,我们可以简单使用modprobe这个指令来加载模块呢!至于内核源代码提供的头文件,在上面的例子当中,则是放置到/usr/src/kernels/linux-2.6.30.3/include/目录中,当然就是通过build/source这两个链接文件来取得目录所在的。

由于内核模块的编译其实与内核原本的源代码有点关系的,因此如果你需要重新编译模块时,那除了 make, gcc 等主要的编译软件工具外,你还需要的就是kernel-devel 这个软件。记得一定要安装。而如果你想要在默认的内核下面添加模块的话,那么就得要找到kernel的SRPM文件了!安装该文件并且取得 source code 后,才能够顺利编译。

26.4.2 单一模块编译

想象两个情况:

如果我的默认内核忘记添加某个功能,而且该功能可以编译成为模块,不过,默认内核却也没有将该项功能编译成为模块,害我不能使用时,该如何是好?

如果 Linux 内核源代码并没有某个硬件的驱动程序(module),但是开发该硬件的厂商有提供给Linux使用的驱动程序源代码,那么我又该如何将该项功能编进内核模块呢?

很有趣对吧!不过,在这样的情况下其实没有什么好说的,反正就是去取得源代码后重新编译成为系统可以加载的模块啊!很简单,对吧!但是,上面那两种情况的模块编译行为是不太一样的,不过,都是需要 make, gcc 以及内核所提供的 include 头文件与函数库等。

硬件开发商提供的额外模块

很多时候,可能由于内核默认的内核驱动模块所提供的功能你不满意,或者是硬件开发商所提供的内核模块具有更强大的功能,又或者该硬件是新的,所以默认的内核并没有该硬件的驱动模块时,那你只好自行由硬件开发商处取得驱动模块,然后自行编译。

如果你的硬件开发商有提供驱动程序的话,那么真的很好解决,直接下载该源代码,重新编译,将它放置到内核模块该放置的地方后就能够使用了。举个例子来说,为了省电,鸟哥在2009 年初买了集成主板来架设家用的服务器,没想到 CentOS 5.1 以前的版本对鸟哥新买的主板内置网卡支持度不足,使用的网卡驱动程序r8169有问题!搜寻了google才发现大家都有这个问题。解决方法就是到Realtek官网下载网卡驱动程序来编译即可。

Realtek的r8168网卡驱动程序:http://www.realtek.com.cn/downloads/

选择“Communications Network ICs”—>“Network Interface Controlllers”—>“10/100/1000M Gigabit Ethernet”—>“PCI Express”—>“Software”就能够下载了!

你可以利用各种方法将它下载后,假设这个文件放置到/root,那么直接将它解压缩吧!之后就可以读一读INSTALL/README,然后找一下Makefile,就能够编译了。整体流程有点像这样:

1. 将文件解压缩:

[root@www ~]# cd/usr/local/src

[root@www src]# tar -jxvf/root/r8168-8.013.00.tar.bz2

[root@www src]# cd r8168-8.013.00/

2. 开始进行编译与安装:

[root@www r8168-8.013.00]# vi readme <==注意查一下该文件内容

[root@www r8168-8.013.00]# make clean modules

[root@www r8168-8.013.00]# ll src/*.ko <==新建下面的模块文件!

-rw-r—r— 1 root root 112216 7月 31 01:11 src/r8168.ko

[root@www r8168-8.013.00]# make install

install -m 744 -c r8168.ko/lib/modules/2.6.30.3vbird/kernel/drivers/net/

重点在上面这行!会发现模块已经被移动到内核模块目录!

  1. 更新模块相依属性!

[root@www r8168-8.013.00]# depmod -a

有趣吧!通过这样的操作,我们就可以轻易地将模块编译起来,并且还可以将它直接放置到内核模块目录中,同时以depmod将模块建立相关性,将来就能够利用modprobe来直接取用。但是需要提醒你的是,当自行编译模块时,若你的内核有更新(例如利用自动更新机制进行在线更新)时,则你必须要重新编译该模块一次,重复上面的步骤才行!因为这个模块仅针对目前的内核来编译的啊!对吧!

利用旧有的内核源代码进行编译

如果你后来发现忘记加入某个模块功能了,那该如何是好?其实如果仅是重新编译模块的话,那么整个过程就会变得非常简单。我们先到目前的内核源代码所在目录执行makemenuconfig,然后将NTFS的选项设置成为模块,之后直接执行:

make fs/ntfs/

那么 ntfs 的模块(ntfs.ko)就会自动被编译出来了!然后将该模块复制到/lib/modules/ 2.6.30.3 vbird/kernel/fs/ntsf/目录下,再执行 depmod -a,就可以在原来的内核下面新增某个想要加入的模块功能。

26.4.3 内核模块管理

内核与内核模块是分不开的,至于驱动程序模块在编译的时候更与内核的源代码功能分不开。因此,你必须要先了解到内核、内核模块、驱动程序模块、内核源代码与头文件的相关性,然后才有办法了解到为何编译驱动程序的时候老是需要找到内核的源代码才能够顺利编译,然后也才会知道,为何当内核更新之后自己之前所编译的内核模块会失效。

此外,与内核模块有相关的,还有那个很常被使用的modprobe命令,以及开机的时候会读取到的模块定义数据文件/etc/modprobe.conf,这些数据你也必须要了解才行。相关的命令说明我们已经在第20章内谈过了,你应该自行前往了解。

26.5 重点回顾

其实内核就是系统上面的一个文件而已,这个文件包含了驱动主机各项硬件的检测程序与驱动模块。

上述的内核模块放置于/lib/modules/$(uname-r)/kernel/中。

驱动程序开发的工作应该是属于硬件开发商的问题。

由于系统已经将内核编译得相当适合一般用户使用了,因此一般入门的用户基本上不太需要编译内核。

编译内核的一般原因是新功能的需求、原本的内核太过臃肿、与硬件搭配的稳定性、其他需求(如嵌入式系统)。

编译内核前,最好先了解你主机的硬件以及主机的用途,才能选择好内核功能。

编译前若想要保持内核源代码的干净,可使用 make mrproper 来清除临时文件与设置文件。

挑选内核功能与模块可用 make 配合 menuconfig, oldconfig, xconfig, gconfig 等。

内核功能挑选完毕后,一般常见的编译过程为 make bzImage, make modules。

模块编译成功后的安装方式为 make modules_install。

内核的安装过程中,需要移动 bzImage文件、创建initrd文件、编辑/boot/grub/menu.lst等操作。

我们可以自行由硬件开发商的官网下载驱动程序来自行编译内核模块。

26.6 本章习题

简单说明内核编译的步骤。

如果你利用新编译的内核来操作系统,发现系统并不稳定,你想要删除这个自行编译的内核,该如何处理?

26.7 参考数据与扩展阅读

内核编译可以用来测试CPU性能,因为编译非常耗费系统资源。

http://lxr.xensource.com/lxr/source/README?a=x86_64

注 释

[1].BIOS的POST功能解释:http://en.wikipedia.org/wiki/Power-on_self-test

[2].BIOS的INT13硬件中断解释:http://en.wikipedia.org/wiki/INT_13

[3].关于splash的相关说明:http://ruslug.rutgers.edu/~mcgrof/grub-images/

[4].一些grub出错时的解决之道:http://wiki.linuxquestions.org/wiki/GRUB_boot_menu http://forums.gentoo.org/viewtopic.php?t=1 22656&highlight=grub+error+collection

[5].PPD的解释:http://en.wikipedia.org/wiki/PostScript_Printer_Description

[6].USB的相关解释与书籍维基百科的解释:http://en.wikipedia.org/wiki/Universal_Serial_Bus USB的在线书籍:http://www.linux-usb.org/USB-guide/book1.html LinuxUSB:http://www.linux-usb.org/

[7].内核代码的相关网页:http://www.kernel.org/pub/linux/docs/device-list/devices.txt

[8].关于udev的简单说明:内核网站的说明:http://kernel.org/pub/linux/utils/kernel/hotplug/udev.html linuxjournal的说明:http://www.linuxjournal.com/article/7316

[9].hal的官网http://www.freedesktop.org/wiki/Software/halLM_sensors官方网站:http://www.lm-sensors.org/

[10].GNU的make网页:http://www.gnu.org/software/make/manual/make.html

[11].GNU Privacy Guard(GPG)官方网站的介绍:http://www.gnupg.org/

[12].维基百科对 X Window 的介绍:http://en.wikipedia.org/wiki/X_Window_System

[13].X Server/X Client 与网络相关性的参考图标:http://en.wikipedia.org/wiki/File:X_client_sever_example.svg

[14].系统的 man page:man xinit、man Xorg、man startx

[15].一些与中文字体有关的网页链接:洪朝贵老师主笔的字体设置(繁体):http://www.cyut.edu.tw/~ckhung/b/gnu/font.php 李果正先生的《GNU/Linux初探》第16章:http://edt1023.sayya.org/node17.html EricCheng的fontconfig软件简介:http://fractal.csie.org/~eric/wiki/Fontconfig

[16].维基百科的备份说明:http://en.wikipedia.org/wiki/Incremental_backup

[17].关于 differential 与 incremental 备份的优缺点说明:http://www.backupschedule.net/databackup/differentialbackup.html

[18].一些备份计划的实施:http://en.wikipedia.org/wiki/Backup_rotation_scheme

[19].通过在/usr/src/kernels/linux-2.6.30.3 下面的 README 以及 make help 可以得到相当多的解释。