[Linux] 内核编译升级失败了以后的处理方案

Mar 24th, 2010

转载本站文章请注明,转载自:扶凯[http://www.php-oa.com]

本文链接: http://www.php-oa.com/2010/03/24/linux-boot-fail.html

相信有无数的人,有编译内核失败的记录, 99% 的原因就是和文件系统,硬件驱动有关,比如没有找到 SCSI 卡.但对这些问题大家都无从下手,都是乱测试.
因为我管理公司所有的服务器的内核定制,优化和升级。下面我要教大家一些技巧,来帮助大家少失败些.来编译一个自己可以用的全新的内核。

内核常识

我们先要了解一点.一个内核有哪些东西.

比如我们:

rpm -ql kernel

可以见到如下的信息

/boot/System.map-2.6.24.4
/boot/config-2.6.24.4
/boot/vmlinuz-2.6.24.4
/lib/modules
/lib/modules/2.6.24.4
/lib/modules/2.6.24.4/build
/lib/modules/2.6.24.4/kernel

见到没,其实没有什么东西,主要就上面几个在 boot 下的文件 ,和在 /lib/modules 下的模块文件.
System.map 内核符号映射表,顾名思义就是将内核中的符号(也就是内核中的函数)和它的地址能联系起来的一个列表。
config     内核编译的配置文件,make oldconfig 就需要使用这个文件.
vmlinuz   这就是真实的可引导的、压缩的内核。

好了,由上面我们知道,这个和系统其它东西没有关系了,所以删除一个内核也就是删除这几文件.

大家可以参考一下前些日子我写的 [Linux]编译一个 RHEL 定制的内核 rpm 包 .

 

Initrd 的了解和检查

我今天要讲的是最影响启动的东西 initrd .大家会想,这是什么,内核中都没有,其它这个是内核包安装完后根据每个不同的硬件生成的.硬件不一样这个不一样.下面这个是很官方的介绍:
initrd是“initial ramdisk”的简写。initrd一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态。图中的initrd- 2.4.7-10.img主要是用于加载ext3等文件系统及scsi设备的驱动。

比如,使用的是scsi硬盘,而内核vmlinuz中并没有这个scsi硬件的驱动,那么在装入scsi模块之前,内核不能加载根文件系统,但scsi模块存储在根文件系统的/lib/modules下。为了解决这个问题,可以引导一个能够读实际内核的initrd内核并用initrd修正scsi引导问题。initrd-2.4.7-10.img是用gzip压缩的文件,initrd实现加载一些模块和安装文件系统等功能。

所以我们现在知道了,如果是一个奇怪的硬件,但是不能正常使用,就是 initrd 默认没有加载,要不就是内核没有加进去.

 

 下面根据导致失败的原因进行一下分类处理

新内核启动失败后: 在原有老系统中使用 modprobe 和 lsmod 来确认需要加载的模块

我们知道了 initrd  影响启动,那我们要怎么样来确认是不是加载全了硬件啦. initrd 很大程度上是靠 lsmod 出来的模块,还有 /etc/modprobe 的指示来做的.当然 也可以用 lspci 之类来确认.
如下

cat /etc/modprobe.conf
alias scsi_hostadapter mptbase
alias scsi_hostadapter1 mptscsi
alias scsi_hostadapter2 mptspi
alias scsi_hostadapter3 mptsas
alias scsi_hostadapter4 mptscsih
alias scsi_hostadapter5 ata_piix

 

# lsmod
Module                  Size  Used by
iptable_filter          7300  1
ip_tables              18132  1 iptable_filter
xt_tcpudp               7680  1
x_tables               19204  2 ip_tables,xt_tcpudp
ipv6                  245092  32

我们发现,这台机器有一些别的机器上没有的硬件,就是 mpt 的相关内容.如果在上面重新编译内核,没有加载这几个模块,就一定会启动失败.

使用原因老系统中可以正常启动的 initrd 来确认新内核需要加载的模块

好了.上面还是我们看得见的,要是我们看不见,但启动失败怎么办
我们可以解开 initrd.img 来看原始加载那些模块.

cd /boot/
mkdir tmp
cp initrd*****.img tmp
cd /tmp
zcat intrd**img | cpio -id
cat  init

好了,我们主要注意下面这些内容

echo "Loading scsi_mod.ko module"
insmod /lib/scsi_mod.ko
echo "Loading sd_mod.ko module"
insmod /lib/sd_mod.ko
echo "Loading mptbase.ko module"
insmod /lib/mptbase.ko
echo "Loading mptscsi.ko module"
insmod /lib/mptscsi.ko
echo "Loading mptspi.ko module"
insmod /lib/mptspi.ko
echo "Loading mptsas.ko module"
insmod /lib/mptsas.ko
echo "Loading mptscsih.ko module"
insmod /lib/mptscsih.ko
echo "Loading jbd.ko module"
insmod /lib/jbd.ko
echo "Loading ext3.ko module"
insmod /lib/ext3.ko

根据上面这些,和你原来的,看看你是不是没有这些信息中提到的模块.没有,就快点加上吧,用这些方法处理后,99% 是能启动的,在不能启动我也帮不到你了

 

重新修改 initrd 的内核

gzip -cd initrd-2.6.34.2.img | cpio -imd --quiet
find . | cpio -co | gzip -9 > /tmp/initrd-2.6.34.2.img

 

编译内核你可以知道的东西

为新核心重命名
我们在编译内核之前, 可以先修改Makefile中的版本信息,打开/usr/src/Linux/Makefile。在开始部分有一个变量EXTRAVERSION可以自行定义。修改这个变量,比如改成 “EXTRAVERSION=-ChinaCache”后,编译出的核心版本号就会显示成2.6.24-ChinaCache。
但实际上, 从2.6.8的版本起可在内核版本号后面添加个性化字符串. 所以也就没有必要修改Makefile了: ()  Local version – append to kernel release
如果你即修改了Makefile中的EXTRAVERSION, 又在配置时定义了local version. 那么local version所定义的字符串将位于末尾, 紧跟在EXTRAVERSION的值之后.

 

depmod
功能:分析可加载模块的依赖性,生成modules.dep文件和映射文件。
用法:depmod [-b basedir] [-e] [-F System.map] [-n] [-v] [version] [-A]
        depmod [-e] [-F System.map] [-n] [-v] [version] [filename...]
描述:
    Linux内核模块可以为其它模块提供提供服务(在代码中使用EXPORT_SYMBOL),这种服务被称作"symbols"。若第二个模块使用了这个symbol,则该模块很明显依赖于第一个模块。这些依赖关系是非常繁杂的。

    depmod读取在/lib/modules/version 目录下的所有模块,并检查每个模块导出的symbol和需要的symbol,然后创建一个依赖关系列表。默认地,该列表写入到/lib/moudules /version目录下的modules.dep文件中。若命令中的filename有指定的话,则仅检查这些指定的模块(不是很有用)。

    若命令中提供了version参数,则会使用version所指定的目录生成依赖,而不是当前内核的版本(uname -r 返回的)。
 

mkinitrd 命令的使用
功能:建立要载入ramdisk的映像文件。
用法:mkinitrd [-fv][--omit-scsi-modules][--version][--preload=<模块名称>][--with=& lt;模块名称>][映像文件][Kernel 版本]

描述:mkinitrd可建立映像文件,以供Linux开机时载入ramdisk。

参数:
   -f    若指定的映像问家名称与现有文件重复,则覆盖现有的文件。
-v  执行时显示详细的信息。
   –omit-scsi-modules    不要载入SCSI模块。
   –preload=<模块名称>    指定要载入的模块。
   –with=<模块名称>    指定要载入的模块。
   –version    显示版本信息。

–builtin=<module> :跳过该模块,让 mkinitrd 认为该模块已经是 builtin 的了,就不会再查找该模块了。

-f :覆盖现有文件

–fstab <file> :使用 <file> 来判断来自动判断 / 设备的文件系统类型。默认是 /etc/fstab

–nocompress :不使用 gzip -9 压缩。

–omit-lvm-modules :跳过 lvm 模块,即使 /etc/fstab 指出它们需要

–omit-raid-modules :跳过 software-raid 模块

例如 : mkinitrd /boot/initrd-2.6.24.img 2.6.24

 

加速编译过程
可以使用 $ make -j . 其中n = 2 * cpu的个数. 对于一般的单CPU系统, 通常用 make -j2一般这个选项可以将速度提高10%左右.
make -j8  #编译
make modules_install && make install  #安装,好了一个内核编译完成,下面是一些细节方面.

 

kernel 2.6.34 启动报错 could not find filesystem ‘/dev/root’

从http://patchwork.kernel.org/patch/37444/ 这个网页,从里面找到了Solution,问题出在了CONFIG_SYSFS_DEPRECATED_V2这个选项上了.
解决办法如下编辑内核源码包里面的.config文件.
CONFIG_SYSFS_DEPRECATED_V2=y #默认该选项为not set,被注释掉的.
然后再编译一遍内核就都OK了.
 

Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪 ViVi 365Key 网摘 天极网摘 和讯网摘 博拉网 POCO 网摘 饭否 QQ 书签 Digbuzz 我挖网 Mister Wong
  1. zhangll
    Mar 24th, 2010 at 12:47
    Reply | Quote | #1

    RHEL下编译新内核无论成功或失败都会有一个新的grub启动项,就算失败了,原先的老内核项依然可以进去,然后重新编译

  2. admin
    Mar 25th, 2010 at 05:33
    Reply | Quote | #2

    我的文章明明写的是失败后的处理方法,我的目的是编译成功。。。,编译成功不是指用老内核启动成功。。。

  3. zhangll
    Mar 25th, 2010 at 05:36
    Reply | Quote | #3

    我知道你是编译成功,看我最后一句啊,老兄,我是说就算失败了仍然用老内核进去重新编译。Sorry,我表达不清楚

  4. admin
    Mar 25th, 2010 at 07:05
    Reply | Quote | #4

    ;-) 嗯,请教一下,你有没有好的技巧推荐?

  5. zhangll
    Mar 25th, 2010 at 09:11
    Reply | Quote | #5

    技巧倒没有,来你这学习的,呵呵,编译2.6的内核在RHEL4上遇到过Unable to open an initial console的错误

    当时是把/etc/dev/permissions.d/50-udev.permissions(默认属组的权限)中的console devices 改成console:root:tty:0660
    重启后还是没能进去,可能是因为udev负责启动新设备,但在udev还没启动之前需要/dev/console,/dev/null和/dev/zero三个设备节点,解决办法就是用linux rescue模式下

    umount /mnt/sysimage/dev
    chroot /mnt/sysimage

    cd dev
    /sbin/makedev console
    /sbin/makedev zero
    /sbin/makedev null

    重启机器后可以正常进入了,也许是合,呵呵~

  6. admin
    Mar 25th, 2010 at 09:38
    Reply | Quote | #6

    这个现象到是想当少见。也很奇怪。

  7. zhangll
    Mar 25th, 2010 at 10:03
    Reply | Quote | #7

    你这的文章都不错,能做链接吗?你的我加上了

  8. admin
    Mar 25th, 2010 at 14:52
    Reply | Quote | #8

    非常荣幸,我正想联系你和你讲这个事啦。

  9. TomBoston
    Apr 6th, 2010 at 05:39
    Reply | Quote | #9

    牛X啊,再顶一下