红联Linux门户
Linux帮助

大菜叶子:26.由编译2.6.32内核引发的问题kernel panic(2)

发布时间:2009-12-12 17:13:37来源:红联作者:一米短绳
[i=s] 本帖最后由 一米短绳 于 2009-12-13 14:29 编辑 [/i]

我没有嵌入式或者写系统代码的那方面的本事,仅仅是一些基础的C、一些基础的shell script、一些基础的makefile和一些算不上基础的英语,昨天又查了很多关于initrd/mkinitrd/内核机理(最直白的那种)的一些文章或者资料,甚至是“modprobe.conf" "depmod" 的有关模块的一些资料,网上的文章/精彩回帖/相关网站(甚至是英文),这下可真是“爽”的我----用猫戈歌的话----爽的我蛋疼……

@@感觉会不会是源码中的 install参数制作initrd.img文件的方法或者工具不是本机自带的呢?
产生这种想法原因很俗,因为我用mkinitrd如果没有预设的模块就不能制作initrd ,而源码中make install 可以跳过从而制作出initrd;
还有就是 man mkintird 没有关于跳过默认模块的参数----至少我没发现。
那么我出现kernelpanic到底是不是因为initrd制作的不合理的原因呢? 只要证明mkinitrd 不是 内核源码中make install 制作initrd的工具就行了!!
马上就要出现新大陆了~~ 可惜……
于是:
我又查看了源码包中的makefile关于install参数的代码,发现是调用本机上的installkernel程序,当时没仔细看具体的installkernel所在本机上的目录,因为都是变量代替的,不好找,但是编译内核这种事情只有root可以干,又是发行版的,必在/sbin下,尝试tab几下果然找到了。
file 它,果然又是个shell script,看了内容仅仅几十行,主要是最后的 调用/sbin/new-kernel-pkg 又是个脚本。
搜索查看它关于mkinitrd的代码,发现个额外参数,代码如下:[code]mkinitrd() {
[ -n "$verbose" ] && echo "creating initrd $initrdfile using $version"
/sbin/mkinitrd --allow-missing -f $initrdfile $version
rc=$?
if [ $rc != 0 ]; then
echo "mkinitrd failed" >&2
exit 1
fi
}
[/code]当时我就郁闷了,原来mkinitrd 还有额外的参数可以用,man里面只写了主要的参数而已。我马上去看了mkinitrd的代码,搜索allow-missing后,果然是个没有可用的参数,而且那些提示无法探测到模块的错误信息就是mkinitrd提供的没错!
mkinitrd 相关allow-missing的选项代码和无法探测(detect)提示的信息代码如下:[code] --image-version)
img_vers=yes
;;
--allow-missing)
allowmissing=yes
;;
--net-dev*)
[/code][code]if [ -n "$allowmissing" ]; then
error "WARNING: No module $modName found for kernel $kernel, continuing anyway"
return
fi

error "No module $modName found for kernel $kernel, aborting."
[/code]完了,结果居然证明源码中 make install 就是最终使用的发行版提供的制作initrd的自动脚本工具----我的是centos,也就是mkinitrd !!!!

============
蛋疼了~~ 这下真蛋疼了。
============

总结前面的分析,我得出:出现kernel panic 不是因为initrd.img 的制作不合格,就是出现在内核的本身!
当然,也就是说,肯定出现在我编译内核过程中的选项上面!
===========

冥思苦想,我在纸上设计了一个锁定范围的步骤方法,也不知道能不能找到关键的地方……

唉,这可真是一个人的战斗阿!


===============[code]哈,我刚开始遇到这个词 sycning(sycn) 是在正确开关linux一类的文章里,sycn是回写内存到硬盘防止关机没有保存的东西损失掉,
sync----> synchronize --->同步 的意思。
刚才man 了一下 sync 发现一个有趣的结果:
[root@minghuan ~]# man -f sync
sync (1) - flush file system buffers
sync (2) - commit buffer cache to disk
sync (3p) - schedule file system updates
sync (8) - synchronize data on disk with memory
[root@minghuan ~]#
从上面可以知道kernel可以调用sync ,换个通俗的说法就是kernel会用sync---->作用是commit buffer cache to disk
直白的意思是把buffer cache 交给 disk 。
===============
那么都知道开机过程大概是这样:
kernel ----->inird-------->实际root(这里root是根目录的意思)
其中initrd 的机理:
initrd-------->虚拟root(同上之意)-----> 调用里面的驱动模块清除障碍(比如SCSI硬盘的识别)--------->挂实际根同时交给kernel
-----------
kernel在此时必然有一步是sync(因为有出错信息为证),从man中可以看的出这个sync(在此时应该代表一个函数)的作用总之会写入disk。
可是却出错了,什么错呢?是 not syncing ----->总之是不能写入硬盘
=============
那么不能写入硬盘的原因是什么呢?用我现有的知识解释,无外乎两种可能:
1,硬盘是坏的,当然不能写入(或者是数据线坏了,总之就是三个字----不能用!)

2,硬盘是好的,kernel 无法识别
造成这种原因的过程只会发生在一个地方:就是上述kernel 和 initrd之间的过程。
==》》》而这种过程错误只有两个:
a) initrd 没有清楚障碍,具体的说是没有清楚硬盘的障碍,所以交给kernel实际的root后kernel也没办法sycn。
b) initrd已经清楚干净障碍了,交给kernel一个没有障碍的root(依然是根目录),可是kernel不接受!然后kernel没有接受根(这里可以理解为硬盘了),安顺序该执行sync,结果not syncing~~~
===============
这样看来,就明朗了。

对于我的当时的菜鸟级别失败的情况,所以我可以肯定是出在上面的 b)这一步,也就是说刚编译的那个新kernel本身的问题:因为它不接受initrd都收拾好了的root阿~~~

后来我知道原因了 正如上面的分析,现在新内核都采用新的sysfs的机制(我理解就是新的一种内存文件系统某个机制,具体是什么就不管了)
最后总结就是少选了一个选项,所以编译出的内核采用了新的sysfs机制当然不会接受旧机制的initrd收拾好的root了。
=========
虽然只是编译内核中的一个选项,可是我觉得一番折腾/分析下来对我的帮助还是挺大的。
当我最后确定是因为一个选项的缘故而kernelpanic时,并没有觉得真丢人啥的或者是小题大作啥的,因为我觉得好像真的缕顺了很多东西呢~~虽然都是直白的浅显的东西,并没有真的去明白什么内核代码……不过对于我,已经够用了吧……
========

以上说的不对的地方,请兄弟们不吝指点。 [/code]
文章评论

共有 21 条评论

  1. blue7590 于 2010-08-06 10:45:22发表:

    解决方法就是加入对旧版sysfs路径的支持,方法如下:
    1)、通过make menuconfig选中以下对应的选项
    General setup -->
    [*] enable deprecated sysfs features to support old userspace tools

  2. szlfeng 于 2009-12-14 20:15:01发表:

    谢谢分享

  3. atone 于 2009-12-14 18:10:55发表:

    向技术高的人看齐!

  4. atone 于 2009-12-14 18:10:15发表:

    向技术高的人看齐!

  5. shampoo 于 2009-12-13 15:41:59发表:

    【最后发现是因为编译内核时候其中的一个选项没有选对,所以才kernel panic。】

    呵呵,别脸红许多人都有这个经验,包括我自己。

  6. 一米短绳 于 2009-12-13 15:10:26发表:

    shmboo大哥,我正常版本也没问题的,
    我是那个什么……那个,我看书看到编译内核,然后就从kernel.org上面下载了最新的内核,然后开始自己的选择那些选项,然后编译这个32的内核,然后安装这个内核,然后开机想试试这个新内核就kernel panic
    =========
    然后,从开始出现kernel panic哪条讯息后,我就开始记录我的想法和具体的过程。
    =========
    最后发现是因为编译内核时候其中的一个选项没有选对,所以才kernel panic。
    =========

  7. shampoo 于 2009-12-13 14:44:29发表:

    怀疑LZ的panic是开机时,跑不到五行,
    就挂了,然后【panic】孤零零地站在那儿,是么?
    记忆中,kernel编程若犯了错,也会出现。

    但【正常版本】就没有碰过。呵呵。

  8. shampoo 于 2009-12-13 14:37:35发表:

    13# 一米短绳

    其实我不知LZ的问题是如何解决的,呵呵。有时候,因为用户停止了某个动作,然后问题就消失了。

    不过,【panic】是SUN/UNIX与Linux常出现的开机讯息,相信网络上你可以搜出一大把。

  9. shampoo 于 2009-12-13 14:33:13发表:

    自从有了reiser以后就不须sync了。
    sync是早期non-IBM UNIX,特别是SUN,的特色。
    reiser应该是向IBM/UNIX学习的。

    十年前的UNIX有三特:
    SUN特便宜,
    HP特快,
    IBM特安全。

    今天许多金融系统还是IBM,不论UNIX或mainframe。

  10. 一米短绳 于 2009-12-13 14:24:45发表:

    没有没有~~ 没有啥企图,就是觉得我第一次这么细心的分析一个问题,而且分析的步骤虽然粗糙但是最终找到了根源,感觉特别自豪---我女朋友也亲了我好几口

    这些东西,是先记在我博客上,然后才敢贴过来跟大家分享经验。
    其实写这么多几乎都是废话的字原因有二:
    1,第一次自己解决了一个linux上的遇到的问题,非常兴奋。
    2,下星期就进考试周了,今天是最后一天去“爽电脑”,该“背”期末考试的复习题了……

  11. 一米短绳 于 2009-12-13 14:16:02发表:

    哈,我刚开始遇到这个词 sycning(sycn) 是在正确开关linux一类的文章里,sycn是回写内存到硬盘防止关机没有保存的东西损失掉,
    sync----> synchronize --->同步 的意思。
    刚才man 了一下 sync 发现一个有趣的结果:[code][root@minghuan ~]# man -f sync
    sync (1) - flush file system buffers
    sync (2) - commit buffer cache to disk
    sync (3p) - schedule file system updates
    sync (8) - synchronize data on disk with memory
    [root@minghuan ~]#
    [/code]从上面可以知道kernel可以调用sync ,换个通俗的说法就是kernel会用sync---->作用是commit buffer cache to disk
    直白的意思是把buffer cache 交给 disk 。
    ===============
    那么都知道开机过程大概是这样:
    kernel ----->inird-------->实际root(这里root是根目录的意思)
    其中initrd 的机理:
    initrd-------->虚拟root(同上之意)-----> 调用里面的驱动模块清除障碍(比如SCSI硬盘的识别)--------->挂实际根同时交给kernel
    -----------
    kernel在此时必然有一步是sync(因为有出错信息为证),从man中可以看的出这个sync(在此时应该代表一个函数)的作用总之会写入disk。
    可是却出错了,什么错呢?是 not syncing ----->总之是不能写入硬盘
    =============
    那么不能写入硬盘的原因是什么呢?用我现有的知识解释,无外乎两种可能:
    1,硬盘是坏的,当然不能写入(或者是数据线坏了,总之就是三个字----不能用!)

    2,硬盘是好的,kernel 无法识别
    造成这种原因的过程只会发生在一个地方:就是上述kernel 和 initrd之间的过程。
    ==》》》而这种过程错误只有两个:
    a) initrd 没有清楚障碍,具体的说是没有清楚硬盘的障碍,所以交给kernel实际的root后kernel也没办法sycn。
    b) initrd已经清楚干净障碍了,交给kernel一个没有障碍的root(依然是根目录),可是kernel不接受!然后kernel没有接受根(这里可以理解为硬盘了),安顺序该执行sync,结果not syncing~~~
    ===============
    这样看来,就明朗了。

    对于我的当时的菜鸟级别失败的情况,所以我可以肯定是出在上面的 b)这一步,也就是说刚编译的那个新kernel本身的问题:因为它不接受initrd都收拾好了的root阿~~~

    后来我知道原因了 正如上面的分析,现在新内核都采用新的sysfs的机制(我理解就是新的一种内存文件系统某个机制,具体是什么就不管了)
    最后总结就是少选了一个选项,所以编译出的内核采用了新的sysfs机制当然不会接受旧机制的initrd收拾好的root了。
    =========
    虽然只是编译内核中的一个选项,可是我觉得一番折腾/分析下来对我的帮助还是挺大的。
    当我最后确定是因为一个选项的缘故而kernelpanic时,并没有觉得真丢人啥的或者是小题大作啥的,因为我觉得好像真的缕顺了很多东西呢~~虽然都是直白的浅显的东西,并没有真的去明白什么内核代码……不过对于我,已经够用了吧……
    ========

    以上说的不对的地方,请兄弟们不吝指点。 -----------一米短绳

  12. shampoo 于 2009-12-13 13:24:06发表:

    会把研究精神耗在这个议题,表示你有某种特定企图。
    所以自求多福啦!呵呵。

  13. shampoo 于 2009-12-13 13:22:04发表:

    引用:
    额。。。那个吃奶和奶嘴是您随便说的还是……另有深意阿……
    一米短绳 发表于 2009-12-13 12:49


    panic的意思,就是kernel这个程序因为缺少或找不到某些东东而跑不下去。
    绝大部分是用户的过错,kernel很少在开机时犯错。

  14. shampoo 于 2009-12-13 13:17:47发表:

    【not syncing 】
    硬盘不转吧!或是硬盘XXX了。

  15. 一米短绳 于 2009-12-13 12:49:23发表:

    额。。。那个吃奶和奶嘴是您随便说的还是……另有深意阿……

  16. 一米短绳 于 2009-12-13 12:46:18发表:

    [i=s] 本帖最后由 一米短绳 于 2009-12-13 12:48 编辑 [/i]

    那么,假如它告诉你原因是:not syncing
    那么导致这个发生这个的原因有很多种吧?
    它是要吃奶还是奶嘴?

    顺便,您看下这个:
    http://www.linuxdiyf.com/bbs/thread-168495-1-2.html

    能不吝提一些不深的建议吗?- -

    ========
    该考试了,下周就不能用电脑了,唉

  17. shampoo 于 2009-12-13 11:37:19发表:

    一般出现panic的时候,在旁边会显示信息,告诉你
    它要奶嘴或吃奶。

  18. 一米短绳 于 2009-12-13 11:31:28发表:

    额 我当时就是觉得刚编译的内核,切换却出现kernel panic ,就该是两种原因导致,一个是initrd一个是意编译好的kenel本身,因为我只对这两个做了改动阿~

    其实都是瞎分析的,也不怕丢人,就把经历想法啥的都写上来了。

  19. shampoo 于 2009-12-13 05:37:59发表:

    【总结前面的分析,我得出:出现kernel panic 不是因为initrd.img 的制作不合格,就是出现在内核的本身!】

    扯到哪边去啦!
    我的Linux或UNIX哪个时候要它痛苦,它就得哭!呵呵。

  20. 一米短绳 于 2009-12-13 02:42:51发表:

    屁,都是顺着来的,一点一点的熬。:0wpoi2

  21. Stanber 于 2009-12-13 00:08:44发表:

    楼上水平瞒高的嘛