Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46784
  • 博文数量: 16
  • 博客积分: 792
  • 博客等级: 军士长
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-06 12:04
文章分类
文章存档

2010年(16)

我的朋友

分类: LINUX

2010-04-28 23:21:39

详解定制一个Liunx内核
 

为什么要编译内核?

本文的焦点是为你的服务器和桌面计算机建立一个定制的linux内核。这个内核将针对机器的处理器进行优化,并且只提供需要的驱动和特征。另一个原因是为内核增加新的支持特性,有些特性在发行商提供的内核中有可能没有包括进来,或让硬件工作得更好。

最终结果是建立一个更小的,更快的,打上所有最新最稳定的补丁和增强特性的内核。

我?编译内核?

是的,就是你。这个任务听起来瞒吓人的,但事实上它并不复杂。首先,如果你知道你的机器配置并熟悉linux,那么配置内核对于你来说就非常直观而且变得容易。即使你不知道,我们将为你展示如何收集需要的信息,请不要害怕。

只要我们为关键的芯片组选择的正确的配置选项,尝试做这件事情是非常安全的。不用担心数据会丢失,我们总是保留发行商提供的原始内核,模块树和引导加载项,因此如果我们因为某些原因需要回退到原始内核是可能的,简单到只需要重新启动计算机在启动菜单处选择原始内核就可以了。如果你是在远程操作一台服务器,当你失去控制的时候需要请一个能接触到服务器的人帮你重新启动它【译者注:在使用独立主机托管时可能会遇到这种情况】。如果你小心点,这种事情通常不会发生。

收集信息

首先,大部分过程可以使用正常的非特权系统用户来执行。直到我们真正安装最终的内核时才需要root权限。无论如何,这个用户必须能访问系统。如果一个用户被限制到它的home目录将不行(如web虚拟主机上提供的shell帐户就不行)。

我们将在终端里敲入命令,可以是tty登陆或xterm或类似的GUI终端程序登陆到本地机器或远程机器(如ssh)
让我们假设已经登陆到一台我们并不了解的机器上。首先要做的事情是弄清楚它上面安装的哪个linux发行版。通常,在/etc目录下有一个文本文件来标明你的发行版的信息。它可能叫做release,issue,redhat-release,slackware-version等,/etc/issue这个文件通常被用来显示欢迎信息,当你登陆到系统时你就会看到它。然后我们要知道正在运行的内核版本。

你可以看到我在$符号后敲入的命令(bash shell环境):


我们查看文件/etc/issue后看到我们正在运行的是Redhat Linux 7.2。uname命令给出了内核版本,它是普通的,redhat提供的2.4.18单处理器内核。

检查启动信息将得到丰富的有关当前运行内核的信息。这个信息可以使用dmesg命令的输出来方便地收集。



它将让你看到当前运行的内核的特征和硬件初始化信息,如IDE控制器。


dmesg输出的第一行向我们展示了内核的版本号,编译人和编译主机,当它被编译后。编译人编译后将它发布。让人非常好奇的是,这台Redhat 7.2服务器当前运行的内核是在Redhat 7.3上编译的。那仅仅意味着那个人已经安装了一个新版本的二进制内核包。下面的几行,我们可以看到这台机器有1G内存。(这意味着我们将可以在内核中开启HIGHMEM支持)

在你的机器上检验dmesg命令的输出。当我们配置新内核时会用到其中一些信息。

检查/proc虚拟文件系统下的许多文件也可以收集到丰富的信息,/proc文件系统是由内核提供与可变内核数据结构关联的接口。

要找到关于处理器的详细信息,我们用cat命令查看/proc/cpuinfo。

我们已经从dmesg命令输出中清楚了我们是一个单处理器系统(不是一个SMP架构多处理器系统),并且我们有一颗运行在接近2GHz的Pentium4处理器,我们也可以看到处理器支持的标志信息(如指令)

接下来,我们要知道芯片组和PCI总线设备类型,可以使用不加参数的lspci命令来获取到一个简单的信息。

好,现在我们知道了是Intel 845芯片组,ICH2 IDE控制器和主板集成的AC’97声卡和Nvidia显示控制器。
如果要知道更多的细节信息,请使用lspci –v命令。

如果你当前运行的内核是向后兼容的话—“legacy /proc/pci support”,用cat查看/proc/pci可以看到更详细的信息。

这当中大部分信息没什么意义,如其中的Intel 82801BA/BAM/CA/CAM以太网控制器,我们猜测它可能是一个主板集成的设备,幸运的是,我们已经从dmesg的输出中弄清楚了。

我们知道这是使用Intel EtherExpress Pro驱动,主板集成的以太网控制器。

好,这是一个Intel系统,它与AMD系统有什么不同之处?这儿有几个例子。第一个例子,lspci命令的输出告诉我们是VIA芯片组,假如这是我们工作的机器,在配置内核的时候,这个信息非常重要。

下面是一些相关的dmesg输出摘录
 

注意IDE控制器的不同之处,请与上面的Intel配置比较。

现在回到Intel Pentium 4架构,即我们将要用它工作的机器,在开始内核代码编译前,我们还有许多事情需要考察。
我们可以看到当前运行内核加载了哪些模块,使用lsmod命令就可以,注意如果不是root用户,你可能需要输入命令的的全路径才行。

普通输出没什么信息,注意这里有部分驱动不是作为模块加载的,为了让我们定制的内核在没有initrd的情况仍然可以启动,类似ext3文件系统和磁盘控制器驱动都必须包含进内核。我们可以将网卡驱动编译为一个模块。

我们需要查看文件系统的布局,同时也要关注我们使用的分区设备和文件系统类型。我们已经可以从dmesg输出看到一些信息,但我们也可以用df命令的输出来查看。-h和-T参数的含义分别是“容易读的”和“显示类型”。

这是一个非常漂亮的安装,一个小的启动分区存放内核和启动加载器,一个大的根分区放在第一块IDE硬盘上,/dev/hda。这里没有scsi磁盘分区,如果有它将显示为/dev/sda1,sda2,sdb1等。此处的文件系统使用的是ext3。temfs被挂载(/dev/shm文件系统),它与ramdisk类似,但它更具动态性。没有内存被真正使用,直到有一些内容复制到那里和当被移除的时候,它存在于页面缓存或swap中。

我们必须查看/etc/fstab文件,这是系统在初始化时加载你文件系统的文件系统表,有一些非常重要的内容需要接受检查。注意在fstab中空格是不重要的,只要在参数之间至少有一个空白或tab就可以了。

看最前面以LABEL=开头的2行,卷标的内容提示支持ext3文件系统,在Redhat系统中,默认情况下,分区通过卷标来挂载,使得切换磁盘驱动器变得很容易。

在redhat内核上需要安装一些补丁,如果我们建立一个标准的内核,系统启动脚本不能加载我们的文件系统,系统将不能启动。

注意:当你打上补丁后,通过卷标加载成为可能,假如你要使用initrd,你可以不用改变它。
因此我们建议使用一个文本编辑器编辑fstab,使用真实的分区设备,做起来并不困难,因为我们已经从df –hT输出知道了/文件系统挂载在/dev/hda2,/boot挂载在/dev/hda1,因此改变LABEL=语句,像下面这样:

为你的系统在fstab中使用真实的分区设备,同时你也应确定在启动加载配置文件中没有类似root=’label=/’或内核甚至不能加载root文件系统的语句,本文稍后将会提及到。

在编辑类似fstab的配置文件时请小心,如果你破坏了它们,你可能需要一张紧急救援磁盘来修复它们,在编辑前创建一个备份是非常不错的注意,当你需要恢复时只要重新命名即可。

现在我们已经收集到足够的信息,可以开始了,下面的任务是解压缩内核代码包,开始阅读那些文档文本。

准备代码树

下载最新稳定的内核代码包,在写本文的时候最新的是2.4.22【译者注:截至翻译本文时已经更新到2.6.24】,到找到下载的链接,你要下载的是用bzip2压缩过的linux-2.4.22.tar.bz2,我们选择.tar.gz格式的包,因为它对文件校验支持更好和签名更小。将其保存到你的home目录,实际上编译内核时不需要root权限,除了在安装它时。我将内核解压到我的home目录下的build目录:

注意老版本的tar使用-y参数比bzip2使用j参数更好,同时,如果你想滚动显示文件名以便于你阅读它,那么你需要加上-v参数。进入解压后的内核目录,浏览README文件,注意它对使用/usr/src/linux区域来解压内核包的警告提示

现在进入Documentation目录阅读Changes文件,这是必须要阅读的,特别是下面的章节,

在每一行的最右边显示了你应使用的命令的版本提示信息,此外,如果你使用了磁盘限额(在这台服务器就使用了),你还需要用到最新的限额工具,请到该链接去下载。

如果你的系统已经运行着2.4系列内核,可能你非常满意这个要求,在Changes文件中已经说明,你不用担心不能使用,如果你在任何地方不需要使用reiserfs文件系统,你不要在编译时选中它,也不用担心reiserfs工具,如果你不用ISDN网络链接,也不用担心ISDN工具。

虽然编译器推荐使用gcc 2.95.3版本,但gcc 3.2.x工作得更好。

注意如果你是redhat7.0,你可能已经安装了有问题的gcc 2.96,它不能原来编译内核,不过,它也提供了kgcc(实际上是egcs)可以原来编译内核,确定这个包已经安装了,kgcc在你的命令目录下,编辑内核目录(linux-2.4.22目录)下最顶层的Makefile文件,将编译器名字从gcc改为kgcc,有下面2处需要改动:

仅仅Redhat7.0有这个问题,在Redhat中2.96以后的版本都能工作得很好。现在你已经检查及/或安装了支持软件所需要的版本,我们可以开始了。我们发出的第一个命令是make mrproper,它用于清除建立树【译者注:我们在该内核目录每次配置及编译后都会产生一些文件,这个命令就是用来清除这些文件的】。这个命令不会修改Makefile的。

现在我们已经准备好可以开始配置内核了。

配置内核

我们已经清楚机器的配置及我们的目的,该收集的信息我们已经收集好了,现在我们开始配置内核,体系架构已经确定是i386,我们为内核选择需要的特征和驱动。有许多配置内核的工具可以选择,但是我们将精力放在menuconfig,它是基于菜单驱动的命令行工具,它需要ncurses库,不过在大多数发行版中默认情况下就已经安装好了,如果你运行了Xfree86,在我看来你也可以选择xconfig,但它比menuconfig更让人困惑,速度更慢一些,并且它需要tk系列包

首先我们来看看make oldconfig这个命令,如果已经编译了2.4以前的内核版本,并且有一个.config文件,你可以将它复制到内核目录的最顶层来覆盖配置信息,然后就可以使用make oldconfig了,如果遇到什么新特性,oldconfig会停下来并问你选择Y,N还是M(选择M将编译为模块),做完配置工作后就可以开始build了,但是你应该运行menuconfig再检查一遍,并有选择性地改变一些配置,没有.config文件的话请不要使用oldconfig。

在提示符后你确定好选择Y/M/N后,按回车即可。
现在在内核目录的最顶层下,敲入make menuconfig命令

它将产生一串输出信息【译者注:这个时候就会产生.config文件了】,然后你的屏幕就会显示如下图的画面

画面颜色将很少(它可能只有黑白2色),这取决于你的终端或ncurses库。实际上,你要做的仅仅是进入每个子菜单然后选择你所需要的特征及清除不需要的特征,它是以一个默认的配置启动的【译者注:只要你运行make menuconfig,画面出来后你就可以看到默认的配置选项了】,但它并没有什么实际意义,因为它并没有针对你的硬件进行选择。

此时你必须仔细分析你收集到的信息,遇到不明白的选项时阅读帮助信息,帮助通常非常有用,有时甚至会给你一个答案,如“if unsure,say N”,我们将涉及到主要的子菜单,你也可以浏览到其他的子菜单,假如它对你有用的话。使用箭头键或tab键进行导航,使用空格键进行选择或清除,如果选择项是尖括号【译者注:即<>】,暗示该项可以编译成模块,按空格键在Y/N/M之间进行切换;如果选项是方括号【译者注:即[ ]】,暗示只能编译进内核,要么就不选择它不编译,你只能选择Y或N。

在菜单的底部有一个help按钮,用箭头键或tab激活它,你可以看到关于该项的帮助信息。第一个子菜单是Code Maturity Level Options,请按回车进入该子菜单。

将焦点移动到help按钮上,回车进入帮助页面

再按回车又返回到子菜单了。我们希望激活这个选项,因此我们能在菜单上看到所有可用的驱动。

按一下空格键,将这个选择选中,选中后将显示一个星号【译者注:这里*表示编译进内核】,你也可以用Y键来完成同样的事情,将焦点移动到exit按钮,按回车返回上一层菜单,返回主菜单后,用下箭头键选择下一个子菜单Loadable Module Support,按回车进入该子菜单。

默认情况下,这里的3个选项都被选中了,我建议你保留默认选择,真正需要的可能仅仅只有"Enable Loadable Module Support",但是在Redhat系统中,你可能需要Kernel Module Loader(请阅读帮助查看更多信息),模块版本信息选不选择都没什么影响。内核模块型的驱动可以在内核运行中动态插入或移除,相反地,静态编译驱动的只能放在主内核里运行,我们将部分驱动作为模块编译,在启动进程初始化后就可以使用了,但是,启动系统必须的内容必须静态编译进内核,意味着你必须选择Y。按exit回到主菜单,选择下一个子菜单Processor Type and Features

按回车进入该子菜单。

用上、下箭头键滚动来查看所有的选项,这台服务器使用的是Pentium4处理器,因此选择不用费力,如果你的CPU没有在列表中,请选择与它接近的匹配项。当你选择好后,回到Processor Type and Features子菜单,这儿还有一些选项需要处理。首先来看Machine Check Exception,在服务器上我大多数时候将它关掉,实际上开启它报告的虚假的异常事件。

在这台服务器上,我们使用了1G的内存,因此我们必须选择High Memory Support,选择4Gb,启用它后,你会看到Highmem I/O,也将它选中。

MTRR支持应该或许被启用,现代操作系统都支持它。

因为我们只有一颗处理器,所以这里的Symmetric Multiprocessing Support应该被禁用掉。下面是我们为处理器类型和特征进行的选择

下一个子菜单是General Setup,这里我们将要选择内核支持的总线类型

 

前面2个都没什么说的,必须选上,一个用于网络支持,一个用于PCI支持。我没有使用到PCI设备呀,但是你阅读一下帮助就知道,即使选择了它也没有什么影响(它仅仅增大了内核映像的尺寸,但不影响内存开销)。
在这台服务器上我们不打算提供ISA总线的支持。(注意哪些仍然使用ISA总线的设备,如软驱,这里将不再提供支持)。同样热插拔在这台机器上也不提供支持,我们不需要它,但是加入你的机器是一台笔记本电脑,或者你计划使用USB设备,请你加入对热插拔的支持。

开启BSD进程计数,让system V IPC和sysctl得到启用,你会用到它们的。

Kernel core格式请选择ELF,并启用二进制类型支持。

因为这是一台服务器,我将高级电源管理禁用掉了,我也没有启用ACPI,在这里没有ACPI支持仍然会工作得很好,但是依赖于你正在编译的内核所在系统的类型,可能开启ACPI支持会很重要。在我家里的机器上,我开启了ACPI支持,至少它给了我软关机的功能。

为了让处理器节能,(当处理器无事可干的时候,内核将发出暂停指令),在一个笔记本电脑上或其他特殊的系统上,你或许需要更多的ACPI支持选项,请阅读每个选项的帮助信息。注意这将取决于你的芯片组,启用ACPI支持可能导致一些问题,系统可能启动不了,ACPI启动后它将控制IRQ,不过可以在启动加载配置项中用参数来控制是否启用它或禁用它。如在kernel启动参数中附加acpi=off来禁用它。除此之外,ACPI还会显著地增大你的内核尺寸,下面是我在General Setup下的选择

回到主菜单,下一个子菜单是Memory Technology Devices,我们将跳过它,不要启用这些特征,除非你要使用类似Flash ROM/RAM芯片,同样,你可以阅读帮助来了解详细信息。
在列表中的下一个子菜单是Parallel port support,我们将其编译为模块,尽管它可能在这台服务器上都不会用到,这些模块不会被加载,请选择M,其余选项就会变得可用了。IEEE1284传输模式选项没有模块可选,但是它将包括在并口支持模块中。

回到主菜单,下一个子菜单是Plug and Play configuration,我通常禁用掉它里面的选项,因为我不会用到ISA PNP设备,请阅读帮助信息来决定你是否需要它,如果你有卡设备或许你应该启用它。下一个议程是Block Devices。

我喜欢将软盘支持编译为一个模块,没有理由将其编译到内核中去,因此我我选择了M。

我也喜欢将loopback设备编译为模块,在本文中我不需要加载任何磁盘镜像文件(如iso文件),如果我们将它编译为模块,不会有什么代价,除非需要的时候会加载,其他时候是不会加载的。

Per Partition Statistics in /proc/partitions允许系统监视工具来显示可用磁盘的使用情况,请选中它。

回到主菜单,下一个子菜单是Multi Device Support (RAID and LVM),如果你计划使用软RAID或逻辑磁盘管理LVM,我将它禁用掉了,因为我在这台服务器上不会用到它们。

在主菜单中的下一个子菜单是Networking Options,它包含有许多选项,下面是默认的设置情况:

在redhat系统上,请将Packet Socket support启用。

启用Network Packet Filtering,将会进入Netfilter Configuration子菜单。

启用Unix Domain Sockets,只要你用了tcp/ip网络就应该启用它。

但是你可能不需要IP Multicasting,我将其禁用掉了,如果你不是很清楚每个选项的含义请阅读帮助信息。

向下滚动到Netfilter Configuration子菜单,按回车键,这些都是内核内置的过滤驱动,你可以选择使用iptables,或ipchains来实施过滤规则,你的发行版可能有一个前端配置程序来配置防火墙的。

在这里我们将防火墙编译为模块,但是我没有选择处于试验性质的选项,但是你可以将它们选择作为模块进行编译,仅仅当模块被使用时才会加载,在这台服务器上,我必须开启老式的ipchains支持,跳过检索lsmod命令的输出,那个模块在当前运行的内核中已经被加载了。下面是我为这台服务器选择的网络选项

请按你的实际需求来决定要启用的其他功能。回到主菜单,列表中的下一条是Telephony Support,你可能不会用到这个功能,但如果你要使用VoIP的话请你开启它。

现在下一个子菜单是ATA/IDE/MFM/RLL support,如果使用的是IDE设备,这里的信息非常重要了,我们配置IDE设备,芯片组,和类似DMA的功能,除非你使用的是scsi磁盘,并且不想提供对IDE控制器的支持,你可以不选择它。在这里我们将其编译到内核中去,而不是作为模块。

请保持ATA/IDE/MFM/RLL support被启用,并且不用将其改为M,下面我们进入ATA and ATAPI Block devices子菜单

请保持Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support被启用,如果你禁用它,它将释放大部分选项。
Include IDE/ATA-2 DISK support也必须被启用。
Use multi-mode默认情况下可能是被禁用掉的,我们宁愿驱动能应用适当的UDMA模式,请阅读帮助信息,我在这台服务器上将其启用了。
Include IDE/ATAPI CDROM support建议你将其编译为模块。
如果你有一台CD刻录机,SCSI Emulation Support也应该设置为M,我在这里将其禁用掉。
注意Include IDE/ATAPI CDROM support和SCSI Emulation Support都可以编译为模块。如果你需要同时加载它们俩(或者将它们俩静态编译进内核),你需要在启动参数中知道特殊的参数,如果你要使用scsi仿真模式,可以在启动参数后追加hdc=ide-scci来为第二个主通道上的CD刻录机提供支持。
CMD640 chipset bugfix/support可以禁用掉,除非你有这种芯片组。
PCI IDE Chipset Support应该是你需要的,反正我这里需要,并且将其编译进内核。
如果你还不清楚的你的芯片组类型,请你开启Generic PCI IDE Chipset Support这个选项,我这里禁用掉了,因为我清楚我的机器配置。
如果你的机器支持共享的PCI IDE中断,你可以启用它,我这里将其禁用掉。Generic PCI bus-master DMA support我将它启用了。如果你对其它选项充满好奇,请阅读帮助信息。跳过下面的芯片组选择,默认情况下,Intel PIIXn芯片组是被启用了的,那正是我们想要选择的,它检查并支持Intel IDE控制器。然而,下面我给你展示的例子一台AMD Duron的机器,它使用的是VIA芯片组。

在这个例子中,我们希望启用VIA82CXXX芯片组,用它来提供对VIA IDE控制器的支持,我们也希望启用Sharing PCI IDE Interrupts Support

请根据你机器的IDE控制器情况选择启用的支持选项。在我们这台机器上使用的是pentium4,因此IDE/ATAPI Block Devices配置如下:

回到主菜单,下一个子菜单是SCSI Support,我在这台机器上将其禁用掉了,因为它没有scsi设备。但是,你可能需要用到它,即使你没有scsi磁盘,但你如果有CD刻录机,你仍需要用到它,因为CD刻录机使用了模拟scsi,如果有外接的zip驱动器也要启用这个选项。

这是默认设置,如果你有scsi磁盘,甚至你使用scsi设备来启动系统,你必须将它编译进内核。同时你还必须得进入SCSI low level drivers子菜单进行设置。

反选SYM53C8XX SCSI support,除非你有这样的控制器。请为你的scsi控制器选择一个合适驱动,如果你有并口zip驱动器,请将IOMEGA parallel port选中,如果你仅仅打算为Cd刻录机提供scsi支持,或其它不是太重要的设备如zip驱动器,你可以将所以scsi支持选项全部编译为模块。下面是为Cd刻录机提供scsi支持的菜单选择:

回到主菜单,下一个子菜单是Fusion MPT device support,这是一个特殊的高性能的scsi控制器(光线通道),它们有自己的菜单,但它取决于scsi支持情况,如果你有这样的控制器,请启用它。
主菜单中的下一项是IEEE 1394 (FireWire) support,你可以将它启用,在下面选择合适的驱动。
再下一项是I2O Device Support,你可能没有这类设备,有问题请阅读帮助。
下一个子菜单是Network Device Support,这是一个非常重要的小节,在这里我配置网卡。

Dummy net driver support默认被设置为M,我通常保留这个设置,它是一个虚拟的网络设备,通过它的任何数据都被丢掉,我从来都没有用过它。有疑问请参考帮助信息。

进入Ethernet (10 or 100Mbit)子菜单,默认情况EtherExpressPro/100 support是启用了的,这正是我要选择的,但我想将其设置为M将其编译为模块,如果你不是这种网卡,请反选它,在合适你的驱动上选择M,注意你可能会选择3com网卡或Western Digital/SMC卡,请明确你的设备类型。

我强烈建议你将网卡驱动编译为模块,在redhat系统上,我曾经在redhat上将其编译进内核,我用的是Intel Gigabit e1000驱动,但它不能启动,我不得不用旧内核来启动系统,当我返回系统后,在系统日志中发现网卡不能正常加载,当我将其编译为模块后,每次都能启动。

当然,如果你有其它的10/100以太网设备,反选EtherExpressPro后,回到Network Device菜单,可以选择的有Gigabit或Wireless子菜单。如果你是在家里使用拨号连接,下面给你展示了如何配置ppp:

你需要ppp支持,同时还需要ppp on asynchronous serial ports支持,如果你喜欢,你可以将ppp支持编译进内核,你就不用担心什么时候这个模块会被加载,当我使用拨号连接的时候就是这样干的,但是我将压缩器编译为模块的。当配置完后,退出Network Devices子菜单,回到主菜单,下一个子菜单是Amateur Radio support,很明显我们不是用到它,如果有兴趣请参考帮助信息。下一子菜单是IrDA (infrared) support,如果你在一台笔记本电脑上工作,你或许应该有兴趣。如果你有一个ISDN moden和连线,请进入ISDN subsystem菜单,启用它并选择合适的驱动,也也许还需要ppp支持和ppp over synchronous ports支持。

下一个子菜单是Input core support,我没有启用它,但是如果你有一个usb鼠标,键盘或任何游戏杆,你应该将其编译为模块。

有usb人体接口设备(HID)的话,这个选项是必须的,你不需要为串口或ps/2鼠标或键盘启用它。主菜单列表中的下一个子菜单是Character Devices,其它输入输出设备就在这里配置了。

你需要为使用虚拟终端将Virtual terminal和Support for console on virtual terminal启用。如果你要使用拨号moden或其它基于串口的设备(如你pc机上的串口),你需要将Standard/generic (8250/16550 and compatible UARTs) serial support启用。如果你很少使用这个,建议将其编译为模块,我这里就要这样做。

你需要为伪终端启用Unix98 PTY support。如果你机器上有一台并口的打印机,你需要将Parallel Printing Support设置为Y或者M,就随你喜欢了。在鼠标子菜单,默认情况下ps/2鼠标支持被启用,我通常保留这个设置,因为ps/2键盘和鼠标使用的是同一个源文件。

我将增强的实时时钟支持启用,因此系统时间(软件时钟)与主板硬件时间同步时,它就可以使用/dev/rtc接口来替代直接写入寄存器。 

如果你想在Xfree86中使用直接渲染(direct rendering)(如为支持openGL提供硬件加速),你应该将/dev/agpgart支持编译为模块,将其设置为M,我在这台服务器上将它们禁用掉了,服务器一般不需要使用X,也就不需要硬件加速了。下面是我为这台服务器设置的字符设备选项:

回到主菜单,下一个子菜单是Multimedia Devices,如果你需要为声卡/显卡或收音机设备提供支持,进入这个子菜单,参考帮助信息完成设置。下一个子菜单是Filesystems,这是一个非常重要的小节,应将其编译进内核,这意味着我们需要内置对ext3日志文件系统和ext2文件系统的支持,ext3实际上是基于ext2而且可以在加载时作为ext2加载。

我不得不在这台服务器上使用磁盘限额,但是你或许不会使用它。如果你是双系统启动(通常是还有一个windows系统),你可以将fat和vfat或ntfs文件系统编译为模块,如果你选择了ntfs支持,你还必须要查看另外一个关于ntfs写支持的选项,如果它标记了危险标识,请你一定要相信这个提示,最好不要提供ntfs写支持【译者注:在最新的2.6内核中已经很好改进了这一功能,可以放心使用ntfs写支持了】,否则你会哭的,但对读支持得非常好,注意对fat/fat32支持得也很好,你可以安全地对它们进行读和写。

我将ISO9660(CDROM文件系统)支持编译为模块,我还选择了Joliet和transparent compression扩展支持,它们也作为模块加载,Joliet或许在服务器上用不着(cdrom驱动器通常只用于应急救援),但它仅仅会增加一点点模块的尺寸,我们不用担心。

你应该要使用/proc文件系统以及/dev/pts文件系统,将它们编译进内核。

进入Network Filesystems子菜单,如果你想建立NFS网络支持,将它们设置为模块,如果你要加载windows文件系统的话,SMBFS非常有用,也将其编译为模块。下面是我为这台服务器设置的文件系统选项:

记住:将本地文件系统支持编译进内核!我这里将ext2和ext3编译进内核了,然而,如果你要使用其他的文件系统如reiserfs,不要忘记将它们也包括进来。回到主菜单,下一个子菜单是Console Drivers,这里有几个有趣的选项。

如果你要使用一个文本模式的显示,你必须将VGA text console启用。如果你将Video mode selection support启用的话,你可以在启动配置参数里指定一个图形模式(使用vga=参数)。你也可以启用Frame Buffer support,它允许你在文本模式下运行高分辨率,更丰富的色彩深度和刷新频率。你可以将VESA VGA graphics console(VESA缓冲器)启用,或为你的显卡指定缓冲支持,请阅读帮助信息和参考文档(Documentation/fb/framebuffer.txt),你也可以在内核启动配置中设置参数。

注意对于某些卡,缓冲驱动和直接渲染会有冲突,通常结果是直接渲染(DRI)不能工作,例如,从个人体验出发,ATI镭用户,如果你启用缓冲支持(甚至你将其编译为模块,你要考虑使用fbset工具来设置它的模式),Xfree86初始化agpgart和DRI模式将会失败,但是我在基于Rage128的显卡上没有发现这个问题。在这台服务器上我也不需要填充,因此我将图形模式或缓冲支持禁用掉了。下一个子菜单是Sound,这里为我们提供了对声卡支持的选择,我不会将其启用,因为我是为一台服务器编译内核,如果要启用它的话,我会选择Intel ICH(i8xx)驱动,因为我们已经从lspci输出中得到了足够的声卡信息。(请阅读帮助信息了解更多)

你可以选择启用声卡支持,提示还可以指定一个特定的驱动作为模块编译,如果你选择了OSS声音驱动模块,你会看到更多驱动选项,反选默认被选中的Creative Ensoniq,除非这就是你要的驱动(如:Soundblaster PCI 16位或128位声卡就会使用这个驱动)。注意如果你的发行版使用的是ALSA(高级linux声音架构)系统,或你计划以后建立和安装一个扩展的内核模块,你都应将Sound Card Support启用,禁用其他任何一个驱动,你以后建立和安装ALSA驱动。查阅得到更多关于ALSA支持的信息。

下一个子菜单是USB Support,我这里将其禁用掉了,因为这是一台服务器(在目前运行的内核中它是一个模块,但是一直没有使用它)

注意因为我们将scsi支持和输入设备支持禁用掉了,它会警告我们必须将这些特性编译进内核。如果你要使用usb设备的话,请将其启用,例如,如果你有一个usb鼠标,你应该将Human Interface Devices启用;如要使用usb闪存卡,你应将USB Mass Storage driver启用,请阅读帮助信息。回到主菜单,下一个子菜单是Bluetooth Support,它是一种小范围无线通讯形式,仅当你有蓝牙设备的时候才启用它。下一个子菜单是Kernel Hacking,你或许不会在调试内核的时候用到它,你或许也不需要新的内置加密选项。

在Library Routines菜单下将CRC32 functions编译为一个模块是个好主意。

回到主菜单,现在配置结束了,退出menuconfig界面选择Yes老保存配置信息。

配置完后我们就可以开始构建了,开始之前你应该再次进入menuconfig仔细检查你的选择,如果不做变动,检查完之后直接退出就可以,不用再保存了。

构建内核

与menuconfig提示一样,在有任何变动后请保存变动,首先我们得建立依赖关系,它将确保必须的,正确的头文件被发现,用下面的命令开始

敲入make dep命令后有一连串快速滚动的输出,你可以快速阅读你看到的内容,当它运行结束后,象下面这样:

好了,现在我们已经建立好了我们的内核映像,下面我们该干什么呢?建立一个bzImage压缩内核映像文件(实际上是用gzip压缩的),过去,如果象保持较小的内核映像一般使用make zImage,那时候,内核映像小于500K,现在变大了,使用bzImage。



你将看到非常多的编译输出,这个过程将持续几分钟(如果你机器比较慢,可能会更久),当它执行完毕时,就象下面这样:


我们的内核映像文件刚刚600K左右,尺寸上还比较满意,因为所有重要的东西都编译进内核了。
下面我们就要开始编译所有选择为模块(M)的驱动了,使用make modules命令。


你将再一次看到一连串的屏幕输出,当执行完之后,象下面这样子:

看起来make操作都执行得非常成功,如果make操作失败了(如编译器或连接器错误),你将看到错误和星号,象下面这样:

看起来make操作失败了,你应明白有麻烦了,假如make以那种方式结束了,你就会看到这样的错误信息,你不能继续下一步操作了,你应该具体问题具体分析,在这个错误里,它属于源代码文件问题,由于我移除了一个函数【译者注:看图中提示信息知道是函数calibrate_delay出了问题】,造成了这个错误。

现在我们完成了linux内核编译,可以开始安装了。

安装内核

首先,我们不要将之前的配置人为地损坏,正确安装我们的新内核必须要保证安全。运行make modules_install模块来将模块安装到/lib/modules下,并将内核映像文件拷贝到/boot目录,包括redhat在内的许多发行版都基于这个目录启动的。但是在有的系统中可能是在/目录下,同时我们还要将System.map文件(内核连接表)文件拷贝到boot目录,最后编辑启动加载器配置文件。在安装模块之前,到/lib/modules下去检查与我们内核版本同名的目录不存在,如果你建立是一个新内核版本它往往是不存在的,在本文中,模块目录的名字将是2.4.22,这取决与你的内核主版本,补丁级别,子级别和在顶层Makefile中指定外部变量:

在你开始建立前一定要先做这件事情(现在已经太迟了),但是你可以在源文件里向外部变量增加内核版本字符串,模块目录名就依据这个来创建的。
好,开始安装模块,从现在开始我们需要使用root权限来完成后面的任务了,使用su(substitute user的缩写,替换用户的意思)目录切换到root用户,输入root密码,注意提示符会从$转为#,在bash下,敲入下面的命令:


屏幕又会滚动输出,当安装结束时,它象下图这样,最后一行展示了模块依赖信息。


现在我们的模块被安装到了/lib/modules/2.4.22下了,最终的内核映像被放放到内核构建树下的arch/i386/boot目录了,它的名字叫bzImage。安装它很简单,只需要将它拷贝到/boot目录命名为vmliuz-2.4.22即可,我喜欢遵守这个约定,虽然它可以是任何一个名字,只要在一起在启动加载器配置文件中一并修改即可。


System.map文件被放置在内核代码目录下的顶层目录,我们将其拷贝到/boot目录,并重命名为System.map-2.4.22,然后将符号连接重新指定到System.map文件,ln –sf 命令中的-f开关意味着“强制”的意思,它实际上是覆盖之前旧的符号连接,当你使用强制参数的时候,请记得仔细检查一下你输入的命令,如果你犯了一个错误,它不会给你提示和告警,在覆盖前先检查一下/boot/System.map确实是一个符号连接而不是一个实实在在的文件,如果你担心出什么以外,将它重命名是个好主意。


自此我们完成了构建树,如果你清楚并确信不会尝试在当前运行的内核上编译任何扩展的模块或软件,你可以将正在运行内核删除掉。一个例子是ALSA项目可能会需要它,除非你已经编译了它。在/lib/modules/2.4.22下有一个叫做build的符号链接,它指向了构建树的位置,这就是在编译扩展模块时配置脚本总是能找到合适的内核代码的原因所在。我在make clean后,留下构建树,当从构建树清除所有对象文件和二进制文件时,保留了.config文件和依赖信息,make clean命令是为再此编译做准备的。接下来的任务是配置启动加载器来启动新的内核。

编辑启动加载器配置

在x86 linux下通常有两个主流的启动加载器grub(Grand Unified Boot Loader)和lilo(Linux Loader),通常你会发现两个启动加载器都安装和配置好了,但在使用时仅仅能激活一个(依据谁被安装到主引导记录MBR中而定),在这台服务器上,有/boot/grub/grub.conf配置文件,也有一个/etc/lilo.conf文件。

如果你能物理上接触到机器,在启动时你自然就能看到使用的是哪个启动加载器了,然而,我不能物理接触到这台服务器,通过查看/boot下的内容(存在LILO的映像文件boot.0300,一个用于删除LILO的MBR或启动扇区的重做文件),我猜测我们正在使用的是LILO,但我不确定。为了确定究竟使用的是哪个加载器,我将制作一个MBR的映像,然后用strings命令来检验,我用root用户运行了下面的命令,它将为/dev/hda上的第一个扇区创建一个512字节的dump文件。

#dd if=/dev/hda bs=512 count=1 of=mbr.img
if=/dev/hda是输入文件,bs=512是输入和输出块的数量,count=1指定我们仅仅只要一块(512字节),of=mbr.img是输出文件。



我获得root权限后,敲入dd命令,看到了一列文件,将所有权赋予我们的用户(我们作为root用户创建的文件)然后退出root登陆,当你使用root权限完成你要做的事情后都请立即退出,然后我们用grep命令在strings命令的输出中查找GRUB,然后再查找LILO,文本GRUB没有找到,因此它不会返回任何输出,字符串LILO找到了,这台机器使用的就是LILO。用一个文本编辑器在二进制模式下查看MBR映像文件,注意lbaLILO字符串。

与另外一台使用GRUB的机器的MBR dump文件进行对比

我们将以GRUB启动,在这台机器上有/boot/grub/grub.conf文件。(注意它也将调用menu.lst,它实际上是grub.conf的软链接)

GRUB并不是很难配置,但是它更加神秘,除非你理解了它,注释信息是以#开头的部分,如果/boot是一个独立的分区,在grub.conf中指定kernel和initrd的路径要相对于/boot,因为还没有linux根文件系统的概念,root分区是存放内核映像的地方,那样的话就不再神秘了。

Grub.conf中以数字0作为开始

default=0
这样指定默认的启动映像,在列表中是以0作为第一条记录的,当我们增加一个新的内核条目是,这个数字将是1。

timeout=10
这里的时间是指等待多长时间后默认的选择就自动启动,单位是秒。

splashimage=(hd0,0)/grub/splash.xpm.gz
这里指定grub启动时显示的图像,首先要指定磁盘设备,因为root没有定义它。

title Red Hat Linux (2.4.18-17.7.x)
title是要在GRUB启动菜单上显示的内容,可以是任何字符串,也允许你使用空格。

root (hd0,0)
这是我们内核映像文件放置的分区。(但不一定是Linux的根文件系统,在同一行也可以指定内核映像文件),(hd0,0)意味着是第一块磁盘的第一个分区,注意如果你配置过其他启动加载器,这并不神秘,不要异想天开地认为与windowsNT的boot.ini文件有一样的约定,磁盘号是从0开始的,分区号也是从0开始的,但是,在一块磁盘上不管有多少主分区,第一个逻辑分区是从4开始的,因此我们说在第一块磁盘上你有且仅有一个主分区和一个扩展分区,主分区将表示成(hd0,0),第一个逻辑扩展分区将表示成(hd0,4),注意在grub.conf里并没有区别IDE磁盘和SCSI磁盘,而是用磁盘号来解决这个问题。

kernel /vmlinuz-2.4.18-17.7.x ro root=/dev/hda2
这一行代码告诉grub如何找到内核,可以在这一行指定一些参数,例如,内核告诉加载根文件系统的时候以“ro”只读模式初始化,在启动进程完成后系统启动脚本重新以读/写模式加载,root=/dev/hda2告诉内核我们的根文件系统在哪里,/sbin/init就要靠这个来查找内核的。

当我们编辑/etc/fstab改变LABEL=为真实的分区设备时,你也应将内核命令行中的root=LABEL=/修改为真实分区设备(在本文中是/dev/hda2)。

initrd /initrd-2.4.18-17.7.x.img
这一行指定了initrd(初始化内存磁盘)映像文件,它象一个文件系统一样被加载,重要的驱动就被载入到这里,我们将不再为我们的新内核指定一个initrd了,因为我们不再用它了,我们将内新内核增加一个新的小节,保留旧有的信息:

我指定default=1将新内核作为默认的启动选项。我还增加了一行fallback 0,当GRUB启动新内核失败时就自动切换到列表中的第一个内核启动,否则GRUB就会一直停留在失败处,等待用户输入命令来恢复。

这就是我们要做的修改了,其实很简单,注意使用GRUB时简单修改grub.conf文件会很受益。

在这台机器上有一个/etc/lilo.conf文件,你机器上的可能与这有些不同,这取决于是谁用什么产生的lilo.conf文件,象下面这样修改你的文件,将会非常安全。

prompt
这直接告诉LILO启动程序提示选择一个操作系统进行启动。

timeout=50
这是一个在使用提示时必须要指定的参数,否则机器不能远程启动,它指定了直到默认的启动映像自动加载等待的时间,以10进制的秒为单位,50意味着5秒的等待。

default=linux
这一行指定了默认的启动选择,=后面的名字就是在image小节中label=行给出的名字,如果默认没有指定一个值,这个文件中列出的第一个将被作为默认的启动选择。

boot=/dev/hda
这一行指定LILO将安装到/dev/hda,意味着安装到第一块磁盘的MBR里,大多数情况下,这就符号你的要求了,但是为其他启动程序将LILO安装到一个启动分区的超级块(类似启动扇区)也是可行的。

map=/boot/map
这一行指定了LILO的map文件,如果不指定,默认就是/boot/map,这个文件包含了LILO代码在MBR里找到它自己的数据(第二阶段的stage),第二阶段stage的数据用来载入内核映像。

install=/boot/boot.b
这一行指出了第二阶段stage需要的文件位置,文件就是boot.b。

message=/boot/message
这一行指出在LILO加载时显示信息文件的位置,它是一个传统的文本文件,但这取决于你的发行版,它可以是一个.pcx图像文件。

linear
下面是从lilo.conf帮助中拷贝粘贴来的:

产生24位线性扇区地址代替柱面/头/扇区(几何学名词)地址,线性地址在运行是转换成几何地址,几何地址要限制与1023柱面(即<=1023),当使用大磁盘时使用线性地址,/sbin/lilo可以产生到不可到达的磁盘柱面的引用,lba32避免了许多这样的陷阱,但是需要最新的BIOS(1998以后的)。

在一个大的IDE硬盘上,我们将用lba32代替linear,但是我们现在使用的是一个小的/boot分区所以不要紧,一个内核映像在超过1023柱面后不会结束。linear在scsi硬盘上一样可以使用。

因此,除非你有一个小的/boot分区,你应该使用LBA32以便内核可以从磁盘的任何地方被加载。下面是我编辑好的lilo.conf文件,增加了新内核:

我将等待时间设置为了10秒,并将标记为2422的新内核作为默认启动项,注意在label=name之间不能有空格,这里也没有指定initrd文件,因为在这个内核上我们不会用到它。现在lilo.conf已经被编辑好了,我们必须要重新载入LILO来是改变生效,通过root用户敲入lilo命令来实现(如果/sbin没有在你的path环境变量中,请敲入/sbin/lilo),这个命令将会去读取lilo.conf文件,重写lilo代码到MBR中去,并重写map文件。

遇到错误时,LILO通常会提示你,但我们在真正使用之前应该先测试一下我们的配置,使用-t开关实现,还可以加上-v开关来显示更多的输出。

从图中可以看出没有错误和警告,测试顺利通过。注意默认的启动标签使用‘*’来标识出来了。一旦你确定你的配置无误后,可以使用lilo命令来使其生效,不需要-t开关了。

重新启动计算机

现在你可以重新启动计算机到你的新内核了,你需要确保启动系统所需的驱动全部都被编译好了,同时在新内核出现问题时你可以恢复到以前的老内核,因此你最好保留老内核。

如果你是工作在一台远程控制的服务器上,你必须等待你在配置启动参数中设置的等待时间后才能进入系统。

附录A(为内核代码打补丁)

有时你可能需要在编译一个内核前为了修复一个问题或增加一点特性或hack一下你需要应用一些补丁(通常是一个压缩的比较文件)。一个很好的例子就是预发行的内核版本。在一套稳定的内核如2.4中,它将是成熟的,在你自己的系统中或非生产系统中尝试这些内核都应该是非常安全的,即使它们是处于beta状态。这儿介绍一个特性,为Xfree86 4.3 DRI支持已经包括在2.4.23-pre中了。如果你用的是X4.3,你不得不从XFree86 4.3发行包中编译扩展的模块来获得DRI支持。

从一个干净的创建树开始,我通常是从干净的解压的内核源代码包开始,依靠补丁的特性来避免这个问题,至少运行一次make mrproper。

首先,我们下载的需要的补丁,放置到包括我们的创建树的目录下,(与源代码目录同级),这通常是当进行内容比较应用补丁时的一个约定,当进入源代码目录的顶层时,敲入下面的目录来应用补丁。

这是一个bzip2个压缩比较文件,如果它是.gz格式就用gzip替代bzip2命令,-d开关是解压缩,-c开关是将命令执行结果输出屏幕上。../ patch-2.4.23-pre9.bz2指定这个补丁文件在上层目录。命令输出通过管道传输到补丁程序,-s开关指定它将安静地执行,除非遇到错误否则不打印任何输出。-p开关告诉它从文件名去除目录前缀。有时它指的是‘补丁等级’。在文件名中的目录路径前缀在比较文件中已经被处理过了。依靠指定的等级,补丁元素从文件名中被去除。如果给出的参数是-p0,文件中写入的路径就当作使用的路径了,意思就是你必须与补丁作者有相同的目录结构,相同的层次。如果给出-p1参数,文件名中的第一个路径将被去除。因为我们使用了-s,如果成功执行将不返回任何输出。现在,如果你正在应用一个已经解压的补丁,你需要象下面这样来应用:

cat ../filename.diff | patch -s -p1

如果应用失败,通常会收到“file to patch?”提示,可能就是你使用了错误的-p等级,如果没有东西被打上补丁,可以简单地按ctrl-c来终止,尝试使用一个不同的-p等级重新来过。在如上面的例子应用完这个补丁后,在顶级的Makefile中将额外产生一个变量-pre9。下面通常开始建立和安装内核。

附录B(建立一个2.6内核)

现在2.6.0内核已经正式发布了,我们将指出一些在建立和配置过程的不同之处。虽然是相同的原理应用,但在配置过程中也有不同之处和潜在的‘转向’。

首先,即使它是目前最新的最稳定的发行版,但它仍然需要更多的更大范围内的系统测试,在生产系统上使用它并不是一个好主意,在这颗树下还有一些容易出问题的驱动,等待有些人的测试和修复,因为它在主流的硬件上表现稳定,所以它成为一个正式的发行,测试和调优已经开始,除非没有问题才可接收。
当前.4内核已经是非常稳固了,为什么我们要尝试这个新版本呢?当然我们看中的是新增加的许多增强特性,下面是它们半官方的讨论文档:

  The Wonderful World of Linux 2.6

象解压2.4内核包那样解压2.6内核包。首先阅读Documentation/Changes文件,确顶你已经安装了有关工具的所需版本,相当重要的是内核模块加载系统的module-init-tools做了非常大的变动。cd到顶层目录,运行make mrproper,注意现在屏幕已经变得更加安静了,不再显示所有的命令执行情况了,但如果你想回到过去一样能看到所有输出,内核编译系统提供了一个环境变量,在bash shell下,你开始之前,敲入下面的命令(c shell环境使用setenv命令)
export KBUILD_VERBOSE=1

现在准备好内核配置选项了,我使用我的家用pc机器,一个桌面系统,使用的是pentium2GHz处理器,intel845芯片组(技嘉主板),运行slackware linux,和签名例子中2.4内核运行的服务器芯片组类似,我的硬件支持得相当好,我已经使用过2.5/2.6测试内核了。

从2.4内核和make oldconfig命令不要使用.config文件,否则你会遇到许多问题。配置内核时有一些新的选项了,make xconfig命令现在是基于取代了TK的qt的GUI了,它需要你安装了qt GUI 工具包库(qt-devel包依赖你的发行版)。make gconfig是一个基于GTK+的GUI配置器,它需要安装GTK+工具包库。

 

注意颜色风格来源于你的KDE配置。

我们还是使用make menuconfig

你首先注意到的可能是有许多选项已经被移动到各个设备驱动子菜单下去了,看起来主菜单更加简洁了。注意那些默认被启用了的选项,除非你阅读了帮助信息并理解了,否则不要禁用它们,例如在General Setup菜单下

你将看到一个选项Support for paging of anonymous memory,如果你禁用它,内核将不能使用swap设备了。这里同样重要的有Kernel .config support,它指定内核配置细节存储进内核映像,它能从运行中的内核直接检索,阅读帮助信息:

“需要使用时能从内核映像文件释放信息作为重新编译当前内核或创建一个新内核的输入配置脚本”

如果你启用/proc/config.gz支持,所有你需要做的就拷贝/proc/config.gz文件到某个地方然后解压它,并重新命名为.config作为工作用的配置文件,我不愿意启用它,因为它将使得内核映像文件增大,我知道我要使用哪些选项(我将配置信息直接保存到我的.config文件)。下一个议程是Loadable Module Support,这里也有度多新的选项了。

我建议启用Module Unloading 和 Forced Module Unloading(因此在需要时你可以通过rmmod –f命令从运行的内核中移除一个模块,但在移除前你要确定你正在干什么,否则你会遇到非常吃惊的困难)。阅读帮助信息,如果你不启用被移除的模块,一旦被加载你就不能移除它了,在我自己的系统上我不使用Automatic kernel module loading,但是你或许想使用这个特性,我通常是手动加载模块,或编制脚本实现半自动加载,自动模块加载功能调用modprobe。下面我要指出的是在Processor Type and Features下的不同之处

首先,这里有一个subarchitecture type菜单,还有一个Preemptible Kernel,它允许一些低优先级的内核模块进程被高优先级的进程预先清空(如键盘输入),为了能在低负载下增强系统的响应,这对于桌面系统来说是一个非常有用的改进。其他部分和2.4内核的配置就类似了,在这个系统上我启用了本地apic支持,因此我的高级可编程中断控制器就可以发送IRQ了。

Power Management, Bus Options 和 Executable File Formats和2.4内核配置也是类似的。

Device Drivers子菜单你将感觉非常熟悉了

基本上,也没大的改动,我这里将指出一点有意思的改动和潜在的转向。Generic Driver Options现在不做任何事情,大概,将来它将属于杂项驱动的范畴,或者我们在该菜单下将不能启用任何选项。
跳到ATA/ATAPI/MFM/RLL support,这里也没有太多的改变,仅仅不同的是,你再需要配置SCSI模拟支持了,因为现在CD刻录使用的是ATAPI驱动(ide-cd)支持了。

现在IEEE 1394 (FireWire) support被默认启用了,如果你不使用火线硬件请禁用它。现在Networking support菜单包含所有有关网络的选项,包括那些早先在Network Device Support下的内容,进入这个子菜单请小心,配置适合你系统的选项,例如,我的D-link 530TXS网卡使用的是Sundance Alta驱动,它在Ethernet (10 or 100Mbit)子菜单下

在Input Device Support下他们已经移除了一部分选项,但是又增加了一些新的选项

垂直和水平分辨率是为图形输入板和类似的硬件准备的,他们忽略了普通鼠标。如果你使用了串口输入设备(如一个串口鼠标)确保启用了Serial Port Line Discipline。

注意:如果你想看下面额外的选项,关于鼠标和键盘控制器,确保你启用了它们,如果你有XF86Config文件为你的ps/2鼠标工作,老式的/dev/psaux支持或许需要,如果你的输入设备支持菜单看起来和上面的差不多,那么那些默认启用的选项是非常安全的,看起来如果我从一颗干净的树开始,第一次编译我不会看那些额外的选项,如果我再一次make mrproper和make menuconfig,它们将是可选的了。

在Character Devices下为Serial Drivers单独设立一个子菜单,通常你需要的已经默认为你启用了,字符设备也为你启用了AGP支持,并且也如2.4内核那样启用了DRI支持。

在Graphics Support下,他们移除了一部分内容也新增加了一部分内容

首先看看Framebuffer Support,现在它终于支持ATI Radeon显卡agpgart和DRI共存了(在以前的版本中是不行的,会与内核发生冲突),现在我可以在我的系统上将其都开启了,好棒!

如果你配置了帧支持,这里有一个转向,向下定位到Console display driver support将Framebuffer Console support启用,没有它,你就不能在字符模式下使用帧了,同时也启用Video Mode Selection Support。

仅仅有兴趣的缘故,这里还有一个转向就是VGA text console,禁用它将导致你在启动新内核时将会黑屏,当人们在使用它们旧的2.5/2.6测试内核配置时老是遇到这个现象,因此,如果你是使用的一个从2.4或早先的2.5/2.6测试内核得到的.config文件的话,请确保这个选项被启用了的!注意如果使用一个从2.6测试内核得到的配置文件,你可能仍然会看到这些选项。

在sound菜单下有一些改动,ALSA(高级linux声音架构)系统已经被合并到内核中了,因此如果你的发行版使用的就是ALSA,你就不用再编译额外的内核模块了。原来的OSS(开放声音系统)驱动仍然有效,为那些不愿做出改动的用户(象我这样的人...我已经计划使用简单的Soundblaster PCI...在OOS驱动下我的声卡工作得很好,我不象再去尝试复杂的ALSA了)

不是你系统上的所有音频程序都能顺利使用,因此你最好将OSS启用以向后兼容,这样的话,基本上应用程序还能使用/dev/dsp和/dev/mixer。

进入PCI Devices子菜单,启用你需要的pci卡支持,同时在Generic Devices下也检查一下。

换句话说,完全禁用掉ALSA支持,启用OSS支持选项来代替也是可以的。

配置你的USB Support选项,如果你有USB设备的话(我没有),它和你在2.4内核中的配置没有什么变化的。
回到主菜单,Filesystems菜单已经有一点变化了,他们浓缩了一部分选项到子菜单中去了,但是,这些选项本身并没有做什么变动。

再次提醒一次,不要忘了启动系统需要的东西必须编译进内核映像文件(如ext2/ext3文件系统支持)而不是一个模块。

进入Kernel Hacking子菜单,有一组选项默认就已经被启用了,如果你不打算调试内核的话,你可以禁用掉它们,如果你想为报告一个bug收集到更多的有用信息,你可以在重新编译时将它们打开即可。


你在配置完内核选项后,退出menuconfig菜单并保存你的改动。

现在你明白了编译过程有哪些变化了吧,实际上变得更加容易了,不再有make dep(自动产生依赖信息),只需要简单地敲入make编译即可创建bzImage和模块了。

注意新内核构建的系统仍然支持旧有的命令(make dep,bzImage,modules),不会导致任何失败的。这就是为什么他们没有制止人们创建象下面这样的脚本。

su到root,然后make modules_install

和2.4内核一样手动安装你的新内核文件(arch/i386/boot/bzImage)和System.map文件,增加你的新内核到你的启动配置文件中去,确保你保留了以前的内核,以备不时之需。

附录C:2.6开发笔记

2.6内核将有一些值得注意的改动使其更加成熟,例如我们已经发布了2.6.1版本,随着时间推移,我将增加更多的特性进去,请周期性地保持注意。

为大小进行的优化
首先你的内核应只包括需要的驱动和特性,编译非必须的或不常用的驱动为模块,编译优化能减少你内核代码的大小尺寸。

在2.6.1内核版本中,他们已经增加了一个新的配置选项来优化大小,这个选项将在编译脚本中使用-Os优化标志,将其传递给编译器,代替了很长的Makefile默认的-O2(是大些的字母o,不是零)该大小优化选项将有效地降低内核大小,如果使用新版本的gcc编译器可能会更小,同时gcc3.2.x或gcc3.3.x(gcc3.3实际上用于内核编译不是很成熟,我通常使用的是3.3.2)版本的选择。你可以在这里阅读到有关编译器优化的内容:

内核不是用来做编译器优化实验的,这个链接仅仅为爱好者提供参考。

以前,为了能在编译时使用-Os选项,你不得不编辑顶级目录下的Makefile文科,我就那样做了很长一段时间,看起来它对我的内核并没有什么损害而且确实降低了内核的大小,原因就是如果代码更小的话,就更容易在内存缓存中找到它。现在它成为一个配置选项了,使用起来更加简单了,我向你推荐使用它。在General Setup 下激活Remove Kernel Features选项。

按回车,你将看到崭新的Optimize for Size配置选项。

在这里你可以安全地将Load all symbols for debugging禁用掉。不要禁用掉Eventpoll or Futex支持,除非你知道你在干什么。

在2.6.1内核中有一个关于调度器的说法,因为不同的机器有不同的用途,不同的负载,磁盘块i/o调度器在启动的时候有一个选择,通过使用elevator=""(="as","deadline",或者"noop")参数实现,和在lilo.conf文件中使用append=类似。

Anticipatory I/O Scheduler是默认的调度器,它被人为是大多数常见的负载最好的调度器,它的算法是一个读操作完成后如果附加有另外一个读需要它将暂停下来。但这并不总是一个最好的行为,例如在一些主要是单个快速读取所有磁盘的数据库服务器上,推荐使用Deadline Scheduler调度器,它在一个指定的时间片内最小化查找操作并且只允许一个i/o请求,它也更小和更简单。

因为我只希望在我的工作站上使用Anticipatory调度器,我将其他两个都禁用掉了,如果我想转换到deadline调度器,我将再次启用它并重新创建一个新的内核,不可能不希望那样...保留其他的调度器可能不会增加内核大小,甚至不会有真实的代码会被载入。

使用-Os优化选项我最后的内核映像文件小于770k。

附录D:使用initrd

在这篇教程里我主张在编译一个自定义的内核时不使用initrd(初始化内存磁盘),因为我们可以将所有启动系统需要的东西全部编译进内核,过去,我总是在为任何系统编译内核时没有任何进展,例如,在redhat系统上我配置/etc/fstab和启动配置文件时总是使用标签,现在它终于被克服了。

使用2.6内核的流行版本,可能使用的是udev系统来创建初始化系统设备节点,实际上它们并不完全依赖于带下划线的/dev目录设备节点来启动一个系统,这是为了向后兼容。例如当我在一个空余的磁盘上运行装备了2.6.10内核的Fedora Core3时,系统不能启动,最显著的症状是无法创建一个初始化控制台,在启动进程后就会挂起。因此我用不同的显示选项重新编译(如不启用framebuffer),但仍然不能正常工作,然后我认识到它于我的图形/控制台配置毫无关系,而是因为在启动过程中必须的设备节点不可用,先有鸡还是先有蛋的问题。如果我想在那个系统上启动一个内核的话,我需要initrd因此udev应该初始化设备,现在我假设我已经通过应急救援盘启动了系统,用mknod创建了真实的/dev/console和/dev/hda和有关的设备,但是为什么仍然不行呢。

另外一个使用initrd的理由是如果你或你的发行版安装工具已经设置分区为LVM卷了,如果root分区是一个逻辑卷,你需要initrd来初始化它否则系统就启动不了。例如,在安装Fedora Core 3过程中"自动分区"选项被选中,将把root分区创建为一个LVM逻辑卷。因此,首先要做的事情就是回去重新配置内核启用要使用initrd和udev系统必须的选项。在General Setup菜单下,确保热插拔支持是启用了的。

在Device Drivers下,在Block Devices子菜单里,确保RAM DIsk Support和Initial Ram Disk Support被启用了。
注意:更新的发行版使用的initrd会增大RAM磁盘的大小,Fedora Core 4指定的是16384,SuSE 9.3指定的是64000,例如

你也可以将loopback device support启用。
在Filesystem下,启用ext2文件系统支持,initrd映像文件会用到,在Pseudo Filesystem子菜单下,确保sysfs是启用了的,默认它应该是启用了的,除非你特意将其禁用了。

这儿有点偏离主题了,但是如果你正在为你的分区使用LVM,你也应该在Device Drivers下Multi Device Support子菜单中将下面这些选项也启用。


按正常步骤建立你的内核,安装你的bzImage和运行make modules_install(它将是创建initrd必须的),mkinitrd工具是由你使用的发行版的发行商提供(也可能是自定义的)的一个脚本,请参考对应你发行版的文档或帮助信息,因为不同发行版的使用方法可能不一样。其实用法非常简单,例如:
mkinitrd /boot/initrd-2.6.10.img 2.6.10

第一个参数就是你要创建的initrd映像文件的名字,第二个参数是内核的版本号。(如版本,补丁等级和额外版本号,与/lib/modules下的内核模块的版本号一致)

如果执行成功,命令将不会有任何输出(如果你想看到输出信息请加上-v开关)。在IDE硬盘上安装一般都很顺利,但我在vmware虚拟机上就遇到麻烦了的,可能是虚拟机使用的是模拟scsi适配器的缘故。

[root@localhost linux-2.6.10]# /sbin/mkinitrd /boot/initrd-2.6.10.img 2.6.10
No module BusLogic found for kernel 2.6.10, aborting.

如果你看到类似的错误信息,mkinitrd脚本可能想重新载入一些模块,也可能是想插入你在/etc/modprobe.conf文件中定义的模块。回去重新配置内核,将设备编译为模块而不是直接编译进如内核,或者编辑你的modprobe.conf文件。(我建议你保留modprobe.conf文件不动,因此你还可以工作在发行商提供的内核版本之上)

如果你重新配置2.6内核,你将不再需要make clean了,只要运行menuconfig改动设置后运行make命令,它将只重新构建和连接需要的部分。

构建低级别的SCSI驱动为一个模块后,重新安装内核,下面是mkinitrd –v的输出(命令执行成功的输出)

[root@localhost linux-2.6.10]# /sbin/mkinitrd -v /boot/initrd-2.6.10.img 2.6.10
Creating initramfs
Looking for deps of module scsi_mod
Looking for deps of module sd_mod
Looking for deps of module unknown
Looking for deps of module BusLogic
Looking for deps of module ide-disk
Looking for deps of module ext3
Using modules: ./kernel/drivers/scsi/BusLogic.ko
/sbin/nash -> /tmp/initrd.LF5984/bin/nash
/sbin/insmod.static -> /tmp/initrd.LF5984/bin/insmod
/sbin/udev.static -> /tmp/initrd.LF5984/sbin/udev
/etc/udev/udev.conf -> /tmp/initrd.LF5984/etc/udev/udev.conf
copy from /lib/modules/2.6.10/./kernel/drivers/scsi/BusLogic.ko(elf32-i386) to /tmp/initrd.LF5984/lib/BusLogic.ko(elf32-i386)
Loading module BusLogic

在你安装好内核后,拷贝你的Initrd映像文件到/boot下后你必须编辑你的启动配置文件:

按照这些步骤操作后内核在Fedora Core 3工作得很好。

Fedora Core 4(gcc4.0)的注意事项
如果使用gcc4.0编译器来编译2.6内核,不要使用优化参数-Os,因为它可能对某些驱动来说非常敏感,当前最新的内核是2.6.12-rc6,2.6.12马上就要出来了【译者注:截至翻译本文时2.6.24.2已经放出了】。

Fedora Core 4使用的是gcc4.0,我使用-Os优化参数进行编译(多年来这个参数一直工作得很好,包括gcc3.4.x)时,我遇到一个极其出色的问题而被终止了。

由于RTNETLINK(或有关的)代码变得非常敏感,启动时网卡不能通过ip route命令指定路由,在启动完成后使用旧的route add命令手动完成,工作得很好。这个奇怪的问题使我花了几个小时来修改网络配置然后不断重试。
给出-Os的用法,避免再有人犯同样的错误,当你完成这一步后你会感觉你有点想撞墙的感觉。

同时在写本文的时候,i2c驱动也不能用gcc4.0来编译,我相信补丁很快就会放出来,事实上在2.6.11上有这个问题,但2.6.12已经修复了这个问题。


阅读(1362) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~