Truth 发表于 2006-9-3 00:28:45

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

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

作者: [email protected]

声明:         1. 官方不建议自行编译内核,尤其不会编译软件的新手请勿轻易尝试。编译内核出现的一切后果和损失自行承担,文档作者 Thruth 不负任何责任。
        2. 重在理解,不要背操作步骤。
        3. 生命诚可贵。焦虑症、心脏病、冠心病、脑血栓、高血压等高危突发疾病患者请勿轻易尝试。如果非要编译内核不可,请先行准备好相关救护措施,全程应由医护人员陪同。
        4. 心智不成熟者编译不成功请勿发帖诬蔑 Linux kernel 和发行版。

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

简述

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

什么是内核

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

什么是补丁

Linux 内核是由 Kernel 小组 (http://www.kernel.org) 维护的,他们在首页提供最新稳定版的内核源代码下载地址。这是原始的纯净内核代码。
如上所述,出于种种原因,一般要对原始内核进行修改。而修改源代码的工作是由打补丁实现的,每个内核补丁都实现一个特定的功能。补丁下载的地址比较分散,自行搜索比较有效。
对打上补丁的内核源代码再行编译,得到计算机可以使用识别的二进制文件,就是我们日常使用的(成品)内核。

为什么要重新编译内核

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

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

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

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

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

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

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

编译步骤

安装必要的编译用软件

gcc
make
..........
(完整中)

下载内核源代码及补丁

哪里获得内核源码

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

1.使用官方 kernel-source 包

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

注意: 此包最好与系统中 kernel-default 包版本一致
优点: 可直接使用,安全稳定,几乎不会出错
缺点: 版本不会是最新的,且已经打过补丁,性能提升空间不大
使用说明: 直接安装使用

2.使用官方 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/

3. 使用非官方安装源 suser-jengelh 的 kernel-source 包
此安装源在 http://ftp-1.gwdg.de/pub/linux/misc/suser-jengelh/SUSE-10.1/

注意: 版本较官方高,有多个版本,且包含非稳定版的内核。除非万不得已,否则不要使用。
优点: 没有
缺点: 系统架构不全,大多数情况下只有 32 位版。部分补丁以及配置文件不能跟进新版本,从而极容易出现各种疑难问题
使用方法: 如果不怕死,直接安装使用

4. 使用非官方安装源 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 包使用方法使用

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

注意: 使用这种途径需要你对自己的硬件以及 Linux 系统都有相当的了解。折腾的时候小心点,一般没问题。
优点: 灵活,版本新,性能提高明显
缺点: 可能找不到适合最新版本的某些补丁,要求对整个软硬件系统有相当的了解
使用方法: 将下载的 Linux 源代码压缩包解压移动到 /usr/src/ 目录,这里以官方目前最新稳定版内核为例:

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

给内核源代码打补丁

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

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

选择需要的补丁

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

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

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

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

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

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

打补丁的顺序

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

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

单个补丁文件

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

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

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

#cd /usr/src/linux-2.6.17.11
#patch -p1 -i ~truth/new/patches/bootsplash-2.6.17.11.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 menuconfig

前者需要安装图形界面相应开发包,如 xorg-x11-devel ,后者界面简陋。推荐使用前者。
此时会自动加载 .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 用户去掉这一项前的钩

配置完毕,保存关闭。

设置编译优化参数

这里的参数是编译器编译时需要的环境变量,设置合适将有利于最终系统的运行速度,而用太激进的优化参数会使系统稳定性降低。这4个变量分别是 CHOST, CFLAGS, CXXFLAGS, MAKEOPTS 用 export 命令声明。需要在一个终端(或同一个标签)挨个声明,顺序无所谓,之后在同一个终端(或同一个标签)继续进行内核编译。

CHOST

32 位系统
#export CHOST="i686-pc-linux-gnu"
64 位系统
#export CHOST="x86_64-pc-linux-gnu"

CFLAGS 和 CXXFLAGS

推荐到页面 http://gentoo-wiki.com/Safe_Cflags#Intel_Processors 找到自己 CPU 的安全 CFLAG 和 CXXFLAG 值,这里以 Prescott 核心的 Pentium 4 为例:

#export CFLAGS="-march=prescott -O2 -pipe -fomit-frame-pointer"
#export CXXFLAGS="${CFLAGS}"

MAKEOPTS

这个选项可以加快编译速度,一般j后面的值为 CPU 数目加一。对于大多数单 CPU 用户:

#export MAKEOPTS="-j2"

编译内核

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

#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/vmlinuz
#rm /boot/initrd
#ln -s vmlinuz-新版本号-default vmlinuz
#ln -s initrd-新版本号-default initrd



本文档配套文档:
openSUSE 升级内核指南 (未发布)
openSUSE 提速指南 (未发布)

cnhnln 发表于 2006-9-3 16:22:24

>>设置编译优化参数
内核会unset系统的cflags,而且较新内核在config时可以设置Os参数。如果一定需要改的话,就要改内核的makefile了

cnhnln 发表于 2006-9-3 16:28:36

编译内核所需软件及版本可以在内核的Documentation/Changes文件里找到
例如2.6.17

oGnu C                  3.2                     # gcc --version
oGnu make               3.79.1                  # make --version
obinutils               2.12                  # ld -v
outil-linux             2.10o                   # fdformat --version
omodule-init-tools      0.9.10                  # depmod -V
oe2fsprogs            1.29                  # tune2fs
ojfsutils               1.1.3                   # fsck.jfs -V
oreiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
oxfsprogs               2.6.0                   # xfs_db -V
opcmciautils            004
opcmcia-cs            3.1.21                  # cardmgr -V
oquota-tools            3.09                  # quota -V
oPPP                  2.4.0                   # pppd --version
oisdn4k-utils         3.1pre1               # isdnctrl 2>&1|grep version
onfs-utils            1.0.5                   # showmount --version
oprocps               3.2.0                   # ps --version
ooprofile               0.9                     # oprofiled --version
oudev                   071                     # udevinfo -V

cnhnln 发表于 2006-9-3 16:37:02

配置内核可用命令除了make config以外还有一些其他的,例如2.6.17的

        "make menuconfig"Text based color menus, radiolists & dialogs.
        "make xconfig"   X windows (Qt) based configuration tool.
        "make gconfig"   X windows (Gtk) based configuration tool.
        "make oldconfig"   Default all questions based on the contents of
                           your existing ./.config file and asking about
                           new config symbols.
        "make silentoldconfig"
                           Like above, but avoids cluttering the screen
                           with questions already answered.
        "make defconfig"   Create a ./.config file by using the default
                           symbol values from arch/$ARCH/defconfig.
        "make allyesconfig"
                           Create a ./.config file by setting symbol
                           values to 'y' as much as possible.
        "make allmodconfig"
                           Create a ./.config file by setting symbol
                           values to 'm' as much as possible.
        "make allnoconfig" Create a ./.config file by setting symbol
                           values to 'n' as much as possible.
        "make randconfig"Create a ./.config file by setting symbol
                           values to random values.

可以在内核的README文件里找到

cnhnln 发表于 2006-9-3 16:40:30

2.6的内核运行make就像当于运行了 #make bzImage 和 #make modules 两个命令。所以只需要
#make
#make modules_install
#make install
即可

cnhnln 发表于 2006-9-3 16:42:36

清理内核内核除了#make clean ,还可用#make distclean ,它会清理的更彻底。但是官方文档推荐用#make mrproper

cnhnln 发表于 2006-9-3 16:48:16

有一个专用于优化性能的ck补丁 http://members.optusnet.com.au/ckolivas/kernel/ 。但是一般的发行版都会集成其中一部分,例如楼主提到的Processor type and features -> Time Frequency 。而且kernel.org的官方内核也会逐渐加入部分功能。所以有可能在打ck补丁的时候会遇到一些fail

cnhnln 发表于 2006-9-3 16:52:25

声明的3、4很搞笑 :mrgreen:

cnhnln 发表于 2006-9-3 16:54:48

编译内核所需软件及版本可以在内核的Documentation/Changes文件里找到
例如2.6.17

oGnu C                  3.2                     # gcc --version
oGnu make               3.79.1                  # make --version
obinutils               2.12                  # ld -v
outil-linux             2.10o                   # fdformat --version
omodule-init-tools      0.9.10                  # depmod -V
oe2fsprogs            1.29                  # tune2fs
ojfsutils               1.1.3                   # fsck.jfs -V
oreiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
oxfsprogs               2.6.0                   # xfs_db -V
opcmciautils            004
opcmcia-cs            3.1.21                  # cardmgr -V
oquota-tools            3.09                  # quota -V
oPPP                  2.4.0                   # pppd --version
oisdn4k-utils         3.1pre1               # isdnctrl 2>&1|grep version
onfs-utils            1.0.5                   # showmount --version
oprocps               3.2.0                   # ps --version
ooprofile               0.9                     # oprofiled --version
oudev                   071                     # udevinfo -V

并非全部必须,例如文件系统那一块,如果不使用jfs\xfs...的话,就不需要jfsutils之类

Truth 发表于 2006-9-4 14:45:51

谢楼上贴,会补充一些进去

至于 CFLAGS 的问题是我不知道,以为跟 gentoo 似的设置了 make.conf 就能用了

ck 的 patch 全打上容易出问题
反倒是 mm 系的补丁来的实用安全,当然臃肿一些

Truth 发表于 2006-9-4 15:41:23

请问如果修改 Makefile 的话是不是
对应CFLAGS和CXXFLAGS光设置HOSTCFLAGS和HOSTCXXFLAGS就行了
CFLAGS_KERNEL再弄上?

cnhnln 发表于 2006-9-4 16:58:21

HOSTCFLAGS和HOSTCXXFLAGS是为交叉编译准备的,对于本机编译没有作用
建议改CFLAGS,改CFLAGS CFLAGS_KERNEL CFLAGS_MODULE应该也是可以的
另外还可以改arch/i386/makefile(如果你的cpu是x86架构的),64位的cpu就要改x86_64下的了
最后,优化不要太过分。虽然可能在编译时通过,但在使用某些功能时会导致出错。我以前就遇到过在2.6上(2.6的初期)用O3导致vesafb出问题,但是2.4没问题

Truth 发表于 2006-9-10 02:10:20

把优化部分删除了

用Gentoo safe Cflags优化以后跑起来很慢。。。。。。。。。。
呵呵
谢谢楼上

cnhnln 发表于 2006-9-10 18:54:32

有没有用lmbench之类的软件测试过阿?
页: [1]
查看完整版本: openSUSE 内核编译教程 (kernel 2.6.x)