从Src rpm 编译 自己修改的内核

我需要创建一个自设的内核

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

  • 你肯定吗?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 gconfig 或 make 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-5:base、xen、PAE 如果是 32 位元结构;CentOS-4:base、smp、xenU、hugemen 如果是 32 位元结构、largesmp 如果是 64 位元结构),或者复制现有内核在 /boot/config-`uname -r` 的配置文件。

你可选择从 ./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 gconfig 或 make 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 161

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Have you read the introduction to the CentOS wiki Custom Kernel article?

I should really say that you are on your own, as there is no support for kernels not built from the CentOS sources. However . . .

Please try the following:

(1) Set up your own rpm build environment / tree using your own ID. Do not use the /usr/src/directory structure or root's ID. See: Setup an RPM Build Environment.
(2) Extract the sources from the tarball in an appropriate location.
(3) Extract the patches from the tarball in an appropriate location.
(4) Patch the sources.
(5) Copy the configuration file of the CentOS kernel that you are currently running to the top directory of the source tree. i.e. cd ~/linux-2.6.31.6; cp /boot/config-$(uname -r) .config
(6) Execute "make oldconfig" and accept the defaults to all the new questions.
(7) Execute "make menuconfig" and configure as you wish.
(8) Change directory to ~/linux-2.6.31.6/scripts/package/ and append the following lines to the mkspec file

echo "%post"
echo "if [ \`uname -i\` == \"x86_64\" -o \`uname -i\` == \"i386\" ]; then"
echo "  if [ -f /etc/sysconfig/kernel ]; then"
echo "    /bin/sed -i -e 's/^DEFAULTKERNEL=kernel-smp$/DEFAULTKERNEL=kernel/' /etc/sysconfig/kernel || exit \$?"
echo "  fi"
echo "fi"
echo "/sbin/new-kernel-pkg --package kernel --mkinitrd --depmod --install "$KERNELRELEASE" || exit \$?"
echo ""


echo "%preun"
echo "/sbin/new-kernel-pkg --rminitrd --rmmoddep --remove "$KERNELRELEASE" || exit \$?"
echo ""

 

(9) Change directory to ~/linux-2.6.31.6/ and build the kernel as an rpm package --


make CONFIG_DEBUG_SECTION_MISMATCH=y binrpm-pkg 2> make-err.log | tee make-out.log

(10) Assuming a successful build (check the log files), you will then find your new  kernel-2.6.31.6-1.*.rpm package in your  ~/rpmbuild/RPMS/{i386|x86_64}/ directory.
(11) (Optionally) Sign the package. (i.e.  rpm --addsign kernel-2.6.31.6-1.*.rpm).
(12) Install the package --  rpm -ivh kernel-2.6.31.6-1.*.rpm
(13) Reboot, specifying the new kernel -- to  single user mode, for the initial test.
(14) If the initial test proves to be satisfactory . . .   . . . just exit the single-user shell to go to your normal multi-user run-level and continue to test. If the initial test fails . . .   . . . you're on your own.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值