这里在实践角度上对日常内核编译更新过程进行讲述。
预备内容
下载内核
内核源代码能够在下面的 kernel.org
FTP站点找到。有许多的站点分散在世界各地。
- ftp.uk.kernel.org
- ftp.us.kernel.org
- ftp.de.kernel.org
你还可以在主站点 www.kernel.org
上面找到这些站点的更多的信息。
假设这里下载的内核是: linux-2.6.31.6.tar.bz2
编译内核
解压
$cp linux-2.6.31.6.tar.bz2 /home/quietheart/kernelSrc/
$cd $_
$tar -xjvf linux-2.6.31.6.tar.bz2
这样在 /home/quietheart/kernelSrc/
下面会生成一个 linux-2.6.31.6/
目录。目录里面的 README
最好看看。
配置内核
cp /boot/config-`uname -r` ./.config
这里,使用当前工作内核的配置文件做为新内核配置文件的基础。另外注意,使用 make xxx_config
,配置内核之前,应该先把 ./config
文件移走(备份)。
编译
具体按照后面的过程进行相应的编译,即可对当前使用系统内核及模块更新。
编译过程实践
在源代码里面运行配置命令(失败)
$make O=/home/quietheart/kernelSrc/build/ menuconfig
提示缺少 ncurses-devel
:
'make menuconfig' requires the ncurses libraries.
安装缺失的库
$sudo apt-get install libncurses5-dev
ncurses
不仅仅封装了底层终端功能,而且提供了一个相当稳固的工作框架(Framework)可以在字符模式下产生美观的界面。
再次运行配置命令
$make O=/home/quietheart/kernelSrc/build/ menuconfig
这样生成的内容都在指定的目录 /home/quietheart/kernelSrc/build
中。
开始配置,配置的时候可以在选项上面按 ?
查看该选项的相关帮助信息,另外从 README
中知道需要注意的是:
- 一些不需要的驱动会使内核变得更大,并且在一些时候会导致问题:例如寻找一个不存在的控制卡可能会让你的其他的控制卡产生问题。
- 编译内核的时候
Processor type
被设置为比386更高,这会导致内核在386的处理器上面无法工作。 - 一个内核如果在编译的时候具有math-emulation(和数学相关的特性),将会在coprocessor存在的时候仍然使用coprocessor:这时候math emulation将不会被使用到。
- 这样内核会有一点大,但是将会工作在不同的机器上,这些机器可以有
math coprocessor
也可以没有。 -
kernel hacking
配置细节一般会导致内核更大更慢,甚至会导致内核不稳定,这些通过配置一些函数来主动地打断不好的代码来寻找内核的问题(kmalloc()
)。
所以,对于一些 development
, experimental
, 或者 debugging
特性的问题,你应该回答 n
.
编译内核
$make O=/home/quietheart/kernelSrc/build/
这里,我稍微计时了一下,从下午7:32到8:41.一个多小时。进入 build
目录查看,发现有一个 vmlinux
100多兆很大,上网查查看,原来内核镜像是 build
中的 arch/i386/boot/bzImage
,在我的机器上,这只是一个链接,指向位置是: ../../x86/boot/bzImage
,另外还有一个重要的文件就是 build
下的 System.map
.
安装模块
我原来的机器的下面一个 /lib/modules/2.6.28-11-generic
,据说要把它备个份:
#cd /lib/modules/
#mkdir bak
#cd bak && tar -czvf 2.6.28-11-generic.tgz ../
这样在 bak
目录下面生成一个备份。文件100多兆,备份压缩的25M。
然后试试直接安装模块,如果采用的相同名字则应该先删掉 /lib/modules/2.6.28-11-generic
,不过先试试看,这一步比较危险:
#cd /home/quietheart/kernelSrc/linux-2.6.31.6
#make O=/home/quietheart/kernelSrc/build/ modules_install install
这一步在 /lib/modules/
生成了 2.6.31.6myTestLocalVersion
目录(580多兆),原来的目录还存在;
另外在 /boot
生成了 System.map-2.6.31.6myTestLocalVersion
, vmlinuz-2.6.31.6myTestLocalVersion
, config-2.6.31.6myTestLocalVersion
三个文件。
这里前两个文件是编译的时候生成的,应该是 arch/i386/boot/bzImage
和 /build/System.map
(奇怪 bzImage
大小稍小), myTestLocalVersion
是配置的时候指定的一个后缀。
设置启动内核
=/boot/grub/menu.lst=增加如下行:
#myownKernel
title Ubuntu 9.04, kernel 2.6.31-6-generic
#uuid 84511622-f2f2-4ca1-bacc-27addb2f1e39
kernel /vmlinuz-2.6.31.6myTestLocalVersion root=UUID=79f02483-c01a-4752-9de9-6fb4b276e991 ro quiet splash
initrd /initrd.img-2.6.28-11-generic
quiet
这里发现一个小技巧:vim中在数字上面按 [Ctrl]a
可以增加数字值。这样文件系统不用改变,启动的时候选择这个选项就会自动自己编译的内核了。奇怪的是 initrd /initrd.img-2.6.28-11-generic
这里竟然能够成功。据说需要使用 /sbin/mkinitrd
相关命令的,可惜没有这个命令。
其他尝试
下面尝试将 arch/i386/boot/bzImage
替换 vmlinuz-2.6.31.6myTestLocalVersion
:
#cp build/arch/x86/boot/bzImage /boot/vmlinuz-2.6.31.6-generic
然后增加如下行:
title Ubuntu 9.04, kernel 2.6.31-6-generic2
#uuid 84511622-f2f2-4ca1-bacc-27addb2f1e39
kernel /vmlinuz-2.6.31.6-generic root=UUID=79f02483-c01a-4752-9de9-6fb4b276e991 ro quiet splash
initrd /initrd.img-2.6.28-11-generic
quiet
这样也能够启动内核。
其它
参考资料:
http://www.arm.linux.org.uk/docs/kerncomp.php
http://linux.chinaunix.net/docs/2006-11-21/3260.shtml