SDB:内核编译教程 (kernel 2.6.x)

跳转至: 导航, 搜索
Icon-obsolete.png 這篇文章現在已經過期了!
原因:{{{1}}}
請參考這篇文章的 討論 頁,以獲得進一步資訊。
Icon-cleanup.png 此頁面需要清理 因為他不遵循我們的 維基規範
如果您想要貢獻,請務必要熟悉這些規範。如果您有任何問題,別猶豫,快 聯絡我們, 我們十分樂意能幫助您! :-)

本文档简要介绍内核,并叙述 openSUSE 下编译 2.6.x 内核的步骤以及注意事项。

声明

1. 官方不建议自行编译内核,尤其不会编译软件的新手请勿轻易尝试。编译内核出现的一切后果和损失自行承担,文档作者 Thruth 不负任何责任。

2. 重在理解,不要背操作步骤。

3. 生命诚可贵。焦虑症、心脏病、冠心病、脑血栓、高血压等高危突发疾病患者请勿轻易尝试。如果非要编译内核不可,请先行准备好相关救护措施,全程应由医护人员陪同。

4. 心智不成熟者编译不成功请勿发帖诬蔑 Linux kernel 和发行版。

注意: 本文档不适用于 2.4.x 系列内核,仅仅适用于 2.6.x 系列内核。


基础知识

什么是内核

内核是 Linux 系统的核心,提供硬件抽象层、磁盘及文件系统控制、多任务并发管理等底层功能的系统部件。

什么是补丁

Linux 内核是由 Kernel 小组 (http://www.kernel.org) 维护的,他们在首页提供最新稳定版的内核源代码下载地址。这是原始的纯净内核代码。

如上所述,出于种种原因,一般要对原始内核进行修改。而修改源代码的工作是由打补丁实现的,每个内核补丁都实现一个特定的功能。补丁下载的地址比较分散,自行搜索比较有效。

对打上补丁的内核源代码再行编译,得到计算机可以使用识别的二进制文件,就是我们日常使用的(成品)内核。

为什么要重新编译内核

openSUSE 为了提高系统的硬件兼容性和稳定性,对内核源代码做了众多修改,编译时也使用了保守的优化参数。这样得到的内核体积大,运行速度较慢,但是稳定性和兼容性极好。

一般编译 openSUSE 内核有以下3条原因:

1.提高内核兼容性或增加功能。尽管 openSUSE 官方打了很多补丁,但是可能依旧不能满足用户需要。用户可能要自行打上特定的补丁或更新内核版本才能支持新硬件或添加对某软件的支持。

2.系统提速。上面提到官方内核性能上是有所保留的,重新按照自己的硬件配置编译内核,并使用合适的优化参数是系统提速最有效的方式。

3.心理需求。像文档作者 Thruth 这种有更新强迫症的人总是希望使用最新版本的内核,也会重复性的编译内核。

若升级不成功,如何恢复官方内核

通过安装光盘启动到你安装的 SUSE Linux,开 yast 刷新 kernel 以及相关包。


编译步骤

需求

编译内核需要安装必要的编译用软件

binutils gcc make module-init-tools udev ......

下载内核源代码及补丁

对 openSUSE 用户来说,获得内核源代码以及补丁有 5 种途径,请根据自身需求选择:

使用官方 kernel-source 包

不管是安装盘里面自带的还是 YaST -> 软件 -> 在线更新 得到的 kernel-source 软件包都是官方提供的打过补丁的内核源代码。

注意: 此包最好与系统中 kernel-default 包版本一致

优点: 可直接使用,安全稳定,几乎不会出错

缺点: 版本不会是最新的,且已经打过补丁,性能提升空间不大

使用说明: 直接安装使用

使用官方 kernel-source 的 src.rpm 包

在官方安装源或更新源的镜像网站上总会有 SRC 目录,包含各种软件源代码,在里面可以找到 kernel-source 的 src.rpm。

例: 在 SUSE 10.1 官方更新源的一个镜像 http://ftp.novell.co.jp/pub/suse/suse/update/10.1/ 下 rpm/src 目录可以找到文件 kernel-source-2.6.16.21-0.13.src.rpm

注意: 解压后需要自行挑选补丁,移动目录。如果对内核版本没有要求,推荐使用这种途径获得内核源代码和补丁。

优点: 内核以及补丁版本一致,打补丁操作基本不会失败,自行补丁会使性能提升明显

缺点: 版本非最新,需解压多次,且要求对整个软硬件系统有一定的了解

使用方法: 使用图形程序 file-roller 或 rpm2cpio 命令解压到某个目录,需要用到的文件及注释如下:

config.tar.bz2					# 按照系统架构分类的 config 内核配置文件
linux-版本.tar.bz2				# 原始内核源代码
novell-kmp.tar.bz2				# Novell 专有内核模块补丁
patches.addon.tar.bz2			# 附加补丁
patches.arch.tar.bz2				# 特定系统架构和硬件需要的一些补丁
patches.drivers.tar.bz2			# 支持某特定硬件需要的补丁
patches.fixes.tar.bz2				# 修正某些特定内核问题的补丁
patches.kernel.org.tar.bz2			# kernel.org 官方提供的版本增量升级补丁(随光盘自带的 sec.rpm 可能没有这个文件)
patches.suse.tar.bz2				# SUSE 专用补丁
patches.uml.tar.bz2				# 针对 UML 的补丁
patches.xen.tar.bz2				# XEN 虚拟机需要的补丁

将原始内核代码解压移动到 /usr/src/ 目录,以上面提到的 kernel-source-2.6.16.21-0.13.src.rpm 为例

$ tar jxf linux-2.6.16.tar.bz2
$ su
# mv linux-2.6.16 /usr/src/
使用非官方安装源 suser-jengelh 的 kernel-source 包

此安装源在 http://ftp-1.gwdg.de/pub/linux/misc/suser-jengelh/SUSE-10.1/

注意: 版本较官方高,有多个版本,且包含非稳定版的内核。除非万不得已,否则不要使用。

优点: 没有

缺点: 系统架构不全,大多数情况下只有 32 位版。部分补丁以及配置文件不能跟进新版本,从而极容易出现各种疑难问题

使用方法: 如果不怕死,直接安装使用

使用非官方安装源 suser-jengelh 之 kernel-source 的 src.rpm 包

此安装源在 http://ftp-1.gwdg.de/pub/linux/misc/suser-jengelh/SUSE-10.1/ , src 目录下有众多 kernel-source.版本号.src.rpm

注意: 版本较官方高,有多个版本,且包含非稳定版的内核。除非万不得已,否则不要使用。

优点: 没有

缺点: 部分补丁以及配置文件不能跟进新版本,从而极容易出现各种疑难问题

使用方法: 如果不怕死,按照官方 kernelsource src.rpm 包使用方法使用

自行下载原始内核代码及补丁

原始的内核源代码在 http://www.kernel.org 下载,补丁自行搜索下载或解压使用最新官方 src.rpm 中带的补丁。

注意: 使用这种途径需要你对自己的硬件以及 Linux 系统都有相当的了解。折腾的时候小心点,一般没问题。

优点: 灵活,版本新,性能提高明显

缺点: 可能找不到适合最新版本的某些补丁,要求对整个软硬件系统有相当的了解

使用方法: 将下载的 Linux 源代码压缩包解压移动到 /usr/src/ 目录,这里以官方目前最新稳定版内核为例:

$wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2
$tar jxf linux-2.6.18.tar.bz2
$su
#mv linux-2.6.18 /usr/src/

给内核源代码打补丁

上一步已经将原始的内核源代码放入 /usr/src/linux-版本号 的目录中。在上面使用的例子中,使用官方 src.rpm 的源代码应该在 /usr/src/linux-2.6.16 目录;而自行下载原始内核源码的在 /usr/src/linux-2.6.18 目录。

内核源码升级可能使某个补丁失效,所以并不是一个补丁可以"补"所有版本内核的。如果补丁无法在新内核上使用,有两种情况,一是内核已经被收入内核不必再"补",或者补丁已经对新版内核代码失效。不管如何,如果出现错误请搜索或根据原补丁自行制作新补丁。

选择需要的补丁

这是考验你对系统了解的时候,地球上硬件和补丁众多,具体什么系统和硬件选择什么补丁并不在本文档讨论范围中。但选择需要补丁的标准很简单,首先是硬件需要,其次是功能需要,最后是心理需要。没必要把找到的所有补丁全部打上,极端一点说,补丁越多,系统越慢。

硬件需要是根据你的硬件来选择补丁,小部分硬件使用原始内核会出现功能不同程度的紊乱或衰弱,也有的并不影响正常使用,只不过在日志中不断报错;此时可以用补丁修复这种情况。

在 kernel-source 的 src.rpm 中有大量的补丁存在,解压 patches 开头的几个 bz2 压缩文件。先 root 权限 lsmod 看看已经加载哪些模块,再找找那些补丁文件名中有没有带其中某个模块名称。如果有,再核对系统架构以及其他信息。不必每个文件名都仔细看,大体浏览下有印象就可以。如果你是 Acer 的笔记本那么文件名中带 ibm asus 的基本与你无关;同理,如果你是 32 位的系统,文件名中带 x86_64 ia64 ppc 的补丁对你也没有意义;如果你使用 AMD CPU 和芯片组那就不必看名称带 intel 字样的补丁。实在拿不准是否需要该补丁,可以点开看看文件开头的注释信息。

切记,如果你对自己的硬件只有大概的了解,可以先不打或少打几个你认为是必要的硬件方面补丁,出现问题再根据日志的提示,搜索看是不是需要某个补丁,然后打上补丁重新编译。

功能需要是某些软件需要补丁实现自己的功能,为了使这些软件正常运行而不得不打补丁,比如下面要提到的 Bootsplash 补丁。如果你对这些也不了解,也可以等出了问题再搜索看看。

心理需要是对某些补丁出于各种原因产生感情依赖,不打该补丁会导致用户进入恶劣心境。为避免严重的不可预知的后果,此时应该打相应补丁避免此类情况发生。

常见补丁系
  • MM 系补丁。由 2.6 维护者 Andrew Morton 整理的一系列补丁,有很多对内核部件的升级和硬件兼容补丁。非常重要且常用。
  • AC 系补丁。一套由 Redhat 的 Alan Cox 维护的补丁集。一般是增加硬件支持的补丁。
  • CK 系补丁。一套由 Con Kolivas 维护的补丁集。含大量性能优化补丁,针对桌面和服务器各有一套。如果你想给系统提速,可以挑选使用其中部分补丁,全部使用可能导致死机。
SUSE 常用补丁
  • Apparmor 补丁。配合 Novell Apparmor 软件,作为 SUSE 特有安全模块。
  • Bootsplash 补丁。开机进入系统时的动画。
  • flush-o-fat 补丁。写入 FAT 格式硬盘加 -o 提速参数,不加此补丁可能无法自动挂载 FAT 格式移动硬盘。

打补丁的顺序和方法

顺序

打补丁有顺序,一般是先打官方提供的增量升级补丁,其次是硬件需要的补丁,之后是功能需要补丁。心理需求补丁的优先级在所有补丁之上,甚至远远高于内核源代码本身。

使用 src.rpm 才需要增量升级补丁,作用是将增量升级原有内核源码至新版本;自行下载的原始内核可以是最新的,不必走这一步。

单个补丁文件

单个补丁文件可能有如下后缀 .diff .patch 或者没有后缀,本质上都是纯文本文件,可用文本编辑器打开修改。补丁方法如下:

#cd /usr/src/linux-版本号
#patch -p1 -i /路径/补丁文件名

例如,我对自行下载的纯净内核打单文件补丁 bootsplash ,实现开机进入 X 前的动画,下载到适合最新版本内核的补丁,文件是 /home/truth/new/patches/bootsplash-2.6.18.diff

#cd /usr/src/linux-2.6.18
#patch -p1 -i ~truth/new/patches/bootsplash-2.6.18.diff
gz/bz2 格式的补丁

并不是所有 gz/bz2 压缩文件都可以用下面方式打上补丁。这类文件必须仅仅包含一个以上单文件补丁,不应含其它杂质;所以用本方法应先打开 gz/bz2 压缩包检查是否符合条件。这种补丁方法本质上就是按照压缩包内文件名升序排列的顺序挨个打上单文件补丁。使用命令为:

#cd /usr/src/linux-版本号
gz 压缩包:  #zcat 路径/文件名.gz | patch -p1
bz2 压缩包:  #bzcat 路径/文件名.bz2 | patch -p1

这里用上面提到的使用官方 src.rpm 的源码作为例子,内核增量补丁是从 src.rpm 解压出来的 patches.kernel.org.tar.bz2 在 /home/truth/new/patches/ 目录

#cd /usr/src/linux-2.6.16
#bzcat ~truth/new/patches/patches.kernel.org.tar.bz2 | patch -p1

有些压缩包中的补丁对所在路径有要求,一般将它们放到 /usr/src/ 目录即可。关于 patch 命令更多用法请 info patch ,本文不作深究。

补丁打完,我们开始进入配置内核阶段。

配置编译内核

配置内核

配置内核就是在源码目录下生成一个 .config 文件,里面定义内核编译时需要的参数。配置文件直接决定了最终内核支持何种硬件、功能以及运行速度。配置内核比打补丁更需要对系统以及各种硬件的了解。

好在 openSUSE 安装后已经默认将内核配置文件存在 /boot/config-版本号-default ,如果你的系统是 SUSE Linux 10.1 并进行过一次官方内核更新,那这个文件就是 /boot/config-2.6.16.21-0.13-default 。我们可以将这个文件复制到内核源代码目录下,在此基础上修改进行优化。当然,如果你完全有把握自己配置内核的能力,大可不必走这一步,手动配置上千选项即可。

如果源码按照原来的配置编译中途失败了,先在源码目录执行如下两句分别清除已编译部分和原配置文件:

#make clean
#make mrproper

将默认配置复制到内核源码目录:

#cd /usr/src/linux-版本号
#cp /boot/config-版本号-default .config

开始配置,有多种通过图形配置内核的选择:

#make xconfig
#make gconfig
#make menuconfig

其中有些需要安装图形界面相应开发包,如 xorg-x11-devel ,推荐使用 make xconfig。

此时会自动加载 .config 配置文件中所有选项,之后弹出图形配置界面。

常用内核优化配置

各种硬件对应内核设置繁多,一般来说 SUSE 默认的配置没有问题。如果你是编译新版本内核,增加新硬件支持,请手动开启该硬件支持选项。这里仅仅提最常用的优化内核的选项,建议日常桌面应用的用户采用。

Processor type and features -> Processor falimy 选择你 CPU 所属的分类

Processor type and features -> Preemption Model 选择 Preemptible Kernel(Low-Latency Desktop)

Processor type and features -> Machine check support 如果是 Intel 用户则去掉 AMD 前面的钩,反之 AMD 用户则去掉 Intel 前面的钩

Processor type and features -> Memory model 如果是 Intel/VIA/其他非 AMD CPU 用户,去掉 K8 GART IOMMU support 前面的钩

Processor type and features -> Time Frequency 选择 1000Hz

Power management options -> CPU Frequency scaling 不支持 CPU 频率调整的老 CPU 直接去掉 CPU Frequency scaling 的钩,并跳过下面两条

Power management options -> CPU Frequency scaling -> AMD Opteron/Athlon64 PowerNow! 非 AMD CPU 用户去掉这一项前的钩

Power management options -> CPU Frequency scaling -> Intel Enhanced SpeedStep 非 Intel CPU 用户去掉这一项前的钩

配置完毕,保存关闭。

编译内核

设置完毕,进入编译阶段。如果补丁和配置正确,下面几步不会出错,按顺序执行,等待完成即可。一般是第三步编译模块时间最长。若期间出错,回到上面配置内核清理并重新配置。

#make bzImage
#make modules
#make modules_install
#make install 

收尾工作

至此,内核已经编译安装完成了,已经在 grub 开始菜单最下面添加了一个启动项。重启可以尝试新内核登录了。还有一些小问题需要解决。 将 /usr/src/linux 指向刚编译内核的源码目录

#rm /usr/src/linux
#ln -s /usr/src/linux-版本号 /usr/src/linux

之后重启,用 uname -r 检查内核版本。自然,记住还要重新安装显卡驱动。


清理工作

如果你的内核经过一段时间测试可以稳定正常工作,那么可以做一些清理工作,释放磁盘空间。

清理旧文件

回到内核源码目录

#make clean

删除 /lib/modules 下其他内核版本号对应的目录,即旧版本内核模块文件 删除 /boot 下其他内核版本号对应的文件

清理 grub 启动列表

你可能不希望失效的原来内核仍然留在开机选单上,那么

#mv /boot/grub/menu.lst.old /boot/grub/menu.lst
#rm /boot/*.old && rm /boot/grub*.old
#rm /boot/vmlinuz && rm /boot/initrd
#ln -s vmlinuz-新版本号-default vmlinuz
#ln -s initrd-新版本号-default initrd

更新 kernel-headers

自行编译内核以后,linux-kernel-header 并不能自动更新,是 RPM 软件管理系统控制的。一般来说,此包会维持在官方内核版本。 所以我们需要手动更新,便于以后新内核下的模块编译工作。

rm -rf /usr/include/linux
cp -r /usr/src/linux-2.6...(新编译内核的版本号,请根据自己情况补全)/include/linux /usr/include