centos内核最好这样编译

 

我需要创建一个自定义的内核

英文版本由 RalphAngenendt 创建。现在由 AlanBartlett 及 AkemiYagi 维护。

 

Contents

  1. 编译前的准备
  2. 设置内核
  3. 内核的 ABI
  4. 更改内核的 spec 文件
  5. 编译新内核
  • 你确定吗?CentOS 被设计以一个完整的环境去运作。如果你替换一个最要的组件,它很可能会影响系统其它部份的运作。
  • 你绝对确定吗?说真的,99.9% 的用户已经不再需要重建自己的内核:你可能只是需要创建一个内核模块。如果是这样,你可参考「创建你自己的内核模块」。

  • 你所需的功能可否通过安装 ELRepo 计划的某个内核模块来提供?

  • 你所需的功能是否由现有内核的一个独立模块所提供?
  • 你所需的功能是否由 CentOSPlus 软件库内的 plus 内核所提供?

  • 最后警告……如果你损坏你的内核或者系统,你除了要承担一切后果,你亦要独个儿解决问题,及埋怨自己令系统不能引导。

为 CentOS 创建自定义的内核有两个方法:第一个是利用加了自定义选项的 CentOS 源代码;另一个是利用来自 Linux Kernel Archive的主流内核源代码。

这份教学文档涵盖如何利用你自己的选项或改动,配合 CentOS 的源代码来创建一个内核。它主要是针对 CentOS-5 而写成。请留意由 <!> 符号所标注、关于在其它版本 CentOS 上创建内核的备注。

(如果你希望创建一个主流的内核,切勿依照 How To Compile A Kernel 内的指引。这个网站不被认可,因为它不安全地教导以 root 创建内核,方法本身就有毛病。详细理由请参阅 Building Source RPM as non-root under CentOS。创建主流内核的一个良好参考指南是 Linux Kernel in a Nutshell 这本书。)

这些行动都只供你个人使用。开发小组并不支持自定义的内核,因为他们不能控制你的编译环境、编译选项等。如果你选择创建自定义的内核,当有安全性更新、新发行、或任何需要进行维护的情况出现,你要独力肩负起这个责任。

 

 

 

1. 编译前的准备

要成功地创建一个内核,你需要安装下列组件:

  • yum groupinstall "Development Tools" # 这样做会确定你拥有编译时所需的一切工具。

  • yum install ncurses-devel # 你必须这样才能让 make *config 这个指令正确地执行。

  • yum install qt-devel # 如果你打算用 make xconfig 而不是 make gconfigmake menuconfig,才需要这样做。

  • yum install hmaccalc zlib-devel binutils-devel elfutils-libelf-devel # 创建 CentOS-6 内核时需要它们。

  • 整个内核的源代码树。 请跟从「我需要内核代源码」第 2 部份内的指引。

当上述 yum 命令执行时,请留意有否组件被排除。假若 yum 配置文件内包含有保护内核及相关组件的 exclude 条目,它们也必须被删除。 <!> 请注意,为不想损失的内容创建最新及已测试的备份永远是个明智的做法。纵使 CentOS 计划普遍并不鼓励有这类 exclude 规则,要是你真的如上述所说有被排除的组件,请明白某些发行商不允许未经修改的内核在他们的环境上运行。有关这个主题的详细数据,请参阅 不健全的虚拟服务器这篇文章的第三节。

如果你想加入任何内核的修正,请于现在复制它们到 SOURCES 目录内。

 

2. 设置内核

<!> 如果你在创建一个 CentOS-6 内核,请在整份教学文档内用 2.6.32 取代 2.6.18

如果你不打算修改发行内核的配置文件,你可以忽略这部分。你只需进行最后一步:

[user@host] $ cp ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`/configs/* ~/rpmbuild/SOURCES

创建好编译用的目录后,现在是时候修改内核的设置。请进到 ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`/ 目录,然后将以下其中一个文件复制成为这个目录内的 .config 档。

你可选择从 ./configs/ 目录复制正确类型的配置文件:

  • 针对 CentOS-6:只需 base(不用定义类型

  • 针对 CentOS-5:base、xen、或(假如是 32 位系统)PAE

或者从 /boot 目录复制现有内核的配置文件。

请参考下面的样例:

 

[user@host]$ cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`

你可选用 —

 

[user@host]$ cp configs/kernel-2.6.18-`uname -m`[-type].config .config

— 或 —

 

[user@host]$ cp /boot/config-`uname -r` .config

首先执行 make oldconfig。现在你应该执行 make menuconfigmake gconfigmake xconfig 来自定义内核的设置。当你完成后,请记得保存你对设置的改动。

如果你安装了整个内核的源代码来创建一个内核模块,你应该在这里停手。请你现在便参考「创建你自己的内核模块」教学文档。

接着,在你将配置文件复制回 configs/ 目录前,请先将注释了的硬件平台(相等于 uname -i 指令的输出)的一行加在配置文件的顶部。这个在 32 位系统上是 i386,在 64 位系统上是 x86_64。这个字符串必需以 # 符号来注释,而且必需是文件的第一行。请留意 # 符号与硬件平台的描述中间必需有一个空格。

请在 .config 文件的顶部加入以下一行:

 

# i386

— 或 —

 

# x86_64

现在将 .config 档复制回 configs/ 目录内。这基本上与先前的复制指令刚刚相反:

 

[user@host]$ cp .config configs/kernel-2.6.18-`uname -m`-[类型].config

最后一步就是将 configs/ 目录内的所有内容复制到 ~/rpmbuild/SOURCES/ 目录内。

 

[user@host]$ cp configs/* ~/rpmbuild/SOURCES

 

3. 内核的 ABI

CentOS 内核的其中一个特色就是它的应用程序二进制接口(ABI)会在整个产品生效期内保持一样。ABI 维持不变的好处,就是外置的内核模块在创建时不必与内核版本挂钩 —— 因此它们不必在新内核发行时被重新创建。这是追踪 kABI 内核模块组件的基础 —— 它们可以提供更新的驱动程序及其它文件系统等支持。

为了维系 ABI 的一致性,原先的内核的 ABI 会被记录并存储在一个文件内。这个文件会在创建每个新内核时用来检查 kABI。如果修改或者设置后的新内核与已发布的 ABI 不一致,编译将会失败,并且会有信息表示 kABI 的一致性已被破坏。这时,内核创建者有两个选择:(一)重新设置新的内核,让它的 ABI 与原有的能互相吻合,因而可继续享受一致 ABI 所提供的好处;(二)在创建的过程中停止检查 kABI。在这两个选择之间,前者较为可取,但有时后者是唯一可行的方法。

要停止检查内核的 ABI,你只需在 rpmbuild 命令行上加入一个选项及它的参数:

 

--without kabichk

 

4. 更改内核的 spec 文件

这个部份所提及的行数只对应当前 CentOS-5 内核的 spec 文件。

现在你需要更改内核的 spec 文件。

 

[user@host]$ cd ~/rpmbuild/SPECS
[user@host SPECS]$ cp kernel.spec kernel.spec.distro
[user@host SPECS]$ vi kernel.spec

在第 74 行(CentOS-5)或第 18 行(CentOS-6),buildid 的定义本来是一个注释。需要取消对它的注释并对其进行赋值,以避免与你当前已安装的内核发生冲突。如下更改该行:

 

%define buildid .your_identifier

"%" 与 "define" 这个字之间不可以有空格。

<!> 以下一步只需在创建 CentOS-5 内核时执行。

由第 698 行起,有一段 25 行的代码需要被改为注释来创建自定义的 CentOS-5 内核:

 

#if a rhel kernel, apply the rhel config options
#%if 0%{?rhel}
#  for i in %{all_arch_configs}
#  do
#    mv $i $i.tmp
#    $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-generic $i.tmp > $i
#    rm $i.tmp
#  done
#%ifarch x86_64 noarch
# for i in kernel-%{kversion}-x86_64*.config
# do
# mv $i $i.tmp
# $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-x86_64-generic $i.tmp > $i
# rm $i.tmp
# done
#%endif
#%ifarch ppc64 noarch
#  #CONFIG_FB_MATROX is disabled for rhel generic but needed for ppc64 rhel
#  for i in kernel-%{kversion}-ppc64.config
#  do
#    mv $i $i.tmp
#    $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-ppc64-generic $i.tmp > $i
#    rm $i.tmp
#  done
#%endif
#%endif

最后假若你有任何补丁,你必需在两个地方对他们进行引用。首先,针对 CentOS-5,在第 426 行,也就是接近补丁声明的尾部,请以 40000 这数目开始加入你的声明,以免你的补丁与 RHEL/CentOS 的内核补丁产生冲突。例如:

 

Patch40000: my-custom-kernel.patch

针对 CentOS-6,请在含有 "# empty final patch file ..." 的第 604 行之前加入此行。

其次,针对 CentOS-5,请在 682 行之后加入此行,以应用你的补丁。你只需要加入你先前声明的补丁编号,然后 rpmbuild 便会自动地为你应用补丁。例如:

 

%patch40000 -p1

针对 CentOS-6,请在含有 "ApplyOptionalPatch ..." 的第 904 行之上,选择加入与 CentOS-5 相同的行采用下列格式:

 

ApplyOptionalPatch my-custom-kernel.patch

<!> 以下对 spec 档的改动只需在 CentOS-6 下应用。

  • 请把第 898 行:

 

cp $RPM_SOURCE_DIR/config-* .

改为

cp $RPM_SOURCE_DIR/kernel-*.config .
  • 删除第 902 行。它含有:

 

make -f %{SOURCE20} VERSION=%{version} configs

 

5. 编译新内核

开始编译:

 

[user@host SPECS]$ rpmbuild -bb --target=`uname -m` kernel.spec 2> build-err.log | tee build-out.log

针对 >= 2.6.18-53.el5 的内核,你可以通过 --with 及/或 --without 这些选项及相关的引数在 rpmbuild 指令内加入一些有用的选项。值得留意的选项包括:

 

--with baseonly
--with xenonly
--without up
--without xen
--without debug
--without debuginfo
--without fips
--without kabichk

举个例子,要创建基本内核组件,请使用:

 

--with baseonly --without debug --without debuginfo

单独创建 xen 内核组件,请使用:

 

--with xenonly --without debug --without debuginfo

单独创建 PAE 内核组件,请使用:

 

--without up --without xen --without debug --without debuginfo

当编译完成后,你的自定义内核的 rpm 文件可以在 ~/rpmbuild/RPMS/`uname -m`/ 目录内找到。切记要以 root 的身份,利用 rpm -ivh kernel-*.rpm 这个指令来安装这些文件。注:如果你创建了一个比当前已安装的版本还要旧的内核,你还需要在 rpm 指令里使用 --oldpackage 这个选项。

无论如何,切勿使用 rpm -Uvh 这个指令来安装你的内核,因为这样做会更新(覆盖)你当前已安装的版本。假如你自定义的内核有问题,你将不能回退到原先可以正常工作的版本。

Translation of revision 163

你可能感兴趣的:(centos,centos6.3,内核编译)