很多朋友一听到说编译内核,就觉得很高深莫测,非常头大。其实,通常其它操作系统的内核编译是比较繁琐的。然而,由于Debian强大的dpkg软件包管理系统,使得内核的升级、编译也变得容易很多。如果下面的步骤都注意并执行了,编译内核不是很复杂的事情,我在基于debian的ubuntu系统上第一次编译就成功了。编译过程如下,与各位分享:
修改ubuntu 6.10上的/bin/sh
在ubuntu6.10上,/bin/sh默认是链接到/bin/dash的,当你从源代码编译软件的时候,dash可能会导致一些错误,至少我遇到过 类似问题,因此,我把/bin/sh的连接改为了/bin/bash。(估计中国绝大部分使用者都是用的bash吧)
如果你使用的就是6.10,那么应该这样做:
$ rm -f /bin/sh
$ ln -s /bin/bash /bin/sh
安装相关的软件,包括
a、Ubuntu Dapper Drake 6.06 LTS 首选“软件”,自己想办法安装吧
b、build-essential,里面有gcc,make等东西要用到。
c. kernel-package,里面有make-kpkg要用。
d. qt库,主要是为了用make xconfig图形界面配置,你要安装libqt3-headers,libqt3-mt-dev等
e. libncurses5-dev,主要是用make menuconfig,我就用这个。
f. gtk库,用于make gconfig。安装gtk2.0,相关lib。
下载源码
到www.kernel.org下载当前最新版的源代码。下载的分类有p,f等区别,要下f类型的连接,不要下补丁。下好的源代码应该有40多M。然后解压缩源代码。
# tar xjvfLinux-2.6.20.tar.bz2 -C /usr/src/Linux-2.6.20
# cd /usr/src/Linux-2.6.20
补丁
如果需要给内核源代码打补丁,首先下载相对应的补丁,在这里我们以patch.bz2代替。将其放到/usr/src目录下,然后用下来的命令来使其生效:
# bzip2 -dc /usr/src/patch.bz2 | patch -p1 –dry-run
# bzip2 -dc /usr/src/patch.bz2 | patch -p1
注意!此时,你应该一直处于/usr/src/Linux-2.6.20目录下。
第一个命令仅仅是试验性质的,它并不会对你的源代码产生什么变动。如果没有产生什么错误信息,你才能用第二个命令来对源代码产生真正的修补动作,如果第一条指令就出错了,请别继续执行下去,看看错误出在哪里。
同样,你也可以向你的内核提供预补丁,例如,一旦你发现有一个自己需要的特性在2.6.19 rc4中提供,但这个版本的内核并没有发行所有的完整源代码,只有patch-2.6.19-rc4.bz2是可选的。于是,你就可以提供这个patch 到2.6.18的内核中,但不是2.6.8.1,或者2.6.8.2。
创建链接
创建一个指向新内核代码的符号
sudo ln -s /usr/src/Linux-2.6.16ck12Linux
然后进入这个目录:
cd /usr/src/Linux
清理
运行命令
make mrproper
来清一下包。
配置
可以用现有的配置文件作为新内核配置文件的基础,先复制已经存在的配置文件到/usr/src/Linux目录中
cp /boot/config-`uname -r` ./.config
然后运行
sudo make menuconfig
或者
sudo make xconfig
如果希望自己配置,那么就在这里面详细选。对选项如何选择不熟悉的,请参考这篇文章。看不懂中文?参考这里。
下面补充一些内容,只说几个这篇文章中没有提到的。
Bus options (PCI, PCMCIA, EISA, MCA, ISA)
PCI support
PCI Express support 老式机器没有PCI-E设备的可以选N
ISA support 较新的新机器没有ISA设备,可以选N
MCA support 一般选N
NatSemi SCx200 support 一般选N
PCI Hotplug Support
Support for PCI Hotplug (EXPERIMENTAL) 如果没有PCI热插拔设备,选N
这里的选项都要全部编译进内核,而不是以模块形式存在。
Device Drivers
Block devices
Packet writing on CD/DVD media
Enable write caching (EXPERIMENTAL) 如果你有刻录机,想启用写缓存功能,选Y
ATA/ATAPI/MFM/RLL support
Include IDE/ATA-2 DISK support 如果你的/boot是放在IDE硬盘上,那么这里一定要选Y,选M都不行。否则启动时会出现“waiting for root file system”的提示而停滞不前。
SCSI device support 如果有SATA硬盘,就选Y
SCSI disk support 如果你的/boot放在SATA硬盘上,一定要选Y。
Character devices
I2C support 一般可以选Y或者M
Graphics support 不建议把显卡驱动编译进内核。,选M,编译成模块方便日后升级驱动。
File systems
CD-ROM/DVD Filesystems
ISO 9660 CDROM file system support 一般选Y
DOS/FAT/NT Filesystems
VFAT (Windows-95) fs support 有FAT32分区就选Y吧
NTFS file system support 有NTFS分区就选Y吧
NTFS write support 如果想对 NTFS分区进行写操作,选Y
Native Language Support
Simplified Chinese charset (CP936, GB2312) 选Y或者M使读取FAT分区不会遇到中文乱码现象
必须将启动盘的文件系统编译进内核,默认是编译成模块,这样无法启动系统。最好是把硬盘上所有用到的分区文件系统全部编译进内核。
然后再谈几个常见的问题解决方法:
1、编译内核失败,不能进入系统,提示如下:
audit(1129243020.326:0):initialized
kernel panic – not syncing: VFS:Unable to mount root fs on unknown-block(0,0)
或是:
VFS:Cannot open root device “hdxy” or unknow-block(0,0)
Please append a correct “root=” boot option
kernel panic-not syncing: VFS:Unable to mount root fs on unknow-block(0,0)
解决方法:把
08.05.11、<*> RAM disk support
09.27.07、<*> Compressed ROM file system support (cramfs) 这两项都要选上!!!!!!否则,呵呵!
2、不能挂载ISO文件。
解决方法:把
08.05.06、<*> Loopback device support
08.05.07、<*> Cryptoloop Support 这两项都要选上便可!
3、用SATA硬盘,原来内核中硬盘的设备号是/dev/sda,编译新内核后的硬盘设备号由/dev/sda变成/dev/hde,硬盘声音很吵。
解决方法:把
08.07、SCSI device support —>
08.07.01、<*> SCSI device support
# 08.07.02、 legacy /proc/scsi/ support
08.07.03、<*> SCSI disk support 这些选项都选上便可!
4、用上新版本内核后,无法安装显示卡的NVIDIA-Linux-x86-1.0-7676-pkg1.run驱动,系统提示如下:
<ccid_nobr>
<ccid_code>Unable to load the kernel modules “nvidia.ko ”, This is most likely because the kernel modules was built using the wrong kernel source files. Please make sure you have installed the kernel source files for your kernel; on Red Hat Linux system, for example, be sure you have the kernel source “rpm” installed. If you know the correct kernel source files are installed, you may specify the kernel source path with the “–kernel-source-path” commandline option.
解决方法:
重新配置内核,将内核中
08.21、Graphics support —> 这个选项里面与Nvidia相关的选项全部去掉后,竟然能够正确安装显卡驱动!具体情况如系统提示,不能引导内核模块,或是模块冲突,导致这种故障。
设置完,保存即可。
构建内核
接下来,就开始构建内核了。首先清理一下东西:
$ sudo make-kpkg clean
然后
$sudo make-kpkg -initrd –revision=lk_517 kernel_image kernel_headers modules_image
lk_517是可以自己换得,表示镜像的名字,必须要以数字结尾。最后是生成镜像包和头文件包。你也可以用binary代替,它融合了image.headers.doc.source,是最完整的包。
make-kpkg是一个可以自动替换”make dep;make clean;make bzImage;make modules”命令序列的脚本。而最其最常用的两个参数就是–append-to-version与–revision。
– append-to-version这个选项可以让我们来指定一个额外的内核版本,这个可以成为内核名的一问分。我们可以使用数字,”+”,”,”, 但是不要使用下划线。要避免设置–append-to-version为如”-686″,”-K7″,”-sparc”等值,因为这些值常为 Debian的预编译内核所使用。
内核模块位于/lib/modules子目录下。每一个内核有他自己的子目录。每次当我们以一个新的名字来安装一个新的内核时,这个包安装程序就会在/lib/modules目录下创建一个新的子目录来保存他自己的模块。这就意味着每一次我们使用– append-to-version的一个新的值来编译一个内核时,我们就可以保证这个内核有一个新的名字,而他的模块也不会与其他的内核模块相冲突。
注意:如果我们使用相同的名字来安装一个内核时,安装程序就会覆盖掉已安装的内核及其模块。–revision只会影响Debian软件包本身的名字而不是内核的名字。与–append-to-version相似,我们只可以使用数,”+ “,”.”,不要使用下划线”_”。如果我们并没有为–revision指定一个值,make-kpkg就会使用”10.00.Custom”.使用不同的–revision的值就可以避免相同名字的内核之间的冲突。
在内核构建成功之后,你能在/usr/src目录下看见三个.deb文件。其中包括Linux-image-2.6.20- custom_2.6.20-custom-10.00.Custom_i386.deb (包含真实内核) andLinux-headers-2.6.20-custom_2.6.20-custom-10.00.Custom_i386.deb (包含那些编译附加内核模块所需要的文件)。
kernel-image文件的名字格式如下:
kernel-image-(kernel-version)(–append-to-version)_(–revision)_(architecture).deb
我用这种办法安装:
sudo dpkg -i xxx.deb
你甚至可以将这两个deb包转移到其他的ubuntu系统中,并用相同的办法安装它们。这意味着,你不再需要再一次编译它们了。
完成
好了,现在,你可以检查一下你的menu.lst文件,多了两个与新内核有关的部分。现在,重新启动计算机,shutdown -r。如果一切顺利的话,重新启动之后,你使用的就是新的内核了。你可以通过 ” uname -r”命令来看看目前的内核版本。
这下就算彻底完成了。重新启动计算机,在GRUB中选择新内核启动。如果启动失败,当你看见屏幕上出现 “Press ESC to enter the menu…1″这行字的时候,按下ESC,此时会进入grub的启动菜单,好,选择你的旧版内核,启动系统。现在,你不得不重新编译一次内核,使其能够正常使用。编译之前别忘了,从menu.lst中去除之前的两个不能正常工作的内核区域。