linux kernel启动失败,如何分析问题所在?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux kernel启动失败,如何分析问题所在?相关的知识,希望对你有一定的参考价值。

## Booting kernel from Legacy Image at 30008000 ...
Image Name: Linux-2.6.32.63
Created: 2014-08-23 13:47:24 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2436056 Bytes = 2.3 MiB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK

Starting kernel ...

undefined instruction
pc : [<30008028>] lr : [<33f9c768>]
sp : 33f3fdf0 ip : 00000000 fp : 30000100
r10: 000007cf r9 : 33eed584 r8 : 33f3ffe0
r7 : 30008000 r6 : 33faaae0 r5 : 00000000 r4 : 33f3ffc4
r3 : 00000000 r2 : 30000100 r1 : 000007cf r0 : 300001d0
Flags: nzCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

参考技术A kernel可是linux内核,这个出问题了估计会比较麻烦。
undefined instruction

未定义的指令。追问

调整uImage生成的配置参数搞定的,把entry point的地址调整为load address加上偏移量0x40。搞不明白为什么,别的开发板不加偏移量也可以呢?linux是2.6.32,uboot是2010.06.

本回答被提问者和网友采纳

linux kernel启动跟踪

说明,本文为我学习孟宁老师的linux内核课的一点总结,同时作为上课的作业。

作者:唐建,《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、准备工作:将编译linux内核,并将调试信息也编译进去。

    使用在linux 根目录执行make menuconfig命令进入配置界面;向下找到kernel hacking 选项并进入;

    然后找到“compile-time checks and compiler options”选项并进入;然后向下找到“compile the kernel with debug info”通过空格键选择,然后保存退出。然后make 编译

技术分享图片技术分享图片技术分享图片

二、启动调试信息

我们这里创建了一个简单的文件系统rootfs,过程就不细讲。

进入代码根目录,通过qemu 来模式具体的机器:qemu -kernel arch/x86/boot/bzImage -initrd ./rootfs.img -s -S

    -s 为后面gdb 调试做准备

    -S 然后系统启动后挂起,便于我们调试。

如下图,启动后就停止了

技术分享图片

启动gdb开始跟踪:需要另起一个shell 窗口。

先file vmlinux 加载系统的符号表,然后让gdb 和启动的linux 建立连接target remote:1234。

 技术分享图片

三、开始跟踪linux 内核的启动过程

  1、linux 内核都是从start_kernel 函数开始启动的,于是我们先将断点打在start_kernel这里。

技术分享图片技术分享图片

可以看到当我们c执行后,就断到start_kernel这里了。下面我们结合代码来分析。

技术分享图片技术分享图片

技术分享图片

如上图,init_task 是第一个内核进程 pid=0(就是后续的IDLE进程,后面我们再详述)的结构体的初始化,0号进程就是start_kernel,这里是将

这个进程的信息写入进程结构体中。start_kernel这个函数是linux内核的起点,他主要完成系统启动前的初始化工作,这里只标注我认识的(不好意思)

技术分享图片技术分享图片技术分享图片

2、init进程启动

这里我们着重看star_kernel函数最后的调用rest_init(),我们可以认为这时候初始化完成了。断点断住它

 技术分享图片

这个rest_init 这个函数代码如下,他主要通过kernel_thread(调用do_fork)创建了两个进程init、kthread。

技术分享图片

init——进程入口kernel_init()。大家看下kernel_init这个函数的启动流程,其实他就是,挨个找各个目录中的init程序来采用shell的形式进行启动,直到找到为止,

所以这里实际上就启动了系统第二个进程,我们通常看到的init进程。

这里代码没有获取pid,所以我们没法打印出来,但是可以知道这个pid应该是1,因为pid是递增的。——有人会问,这里实际上是两个

技术分享图片技术分享图片

再看下下面这个是我的linux系统的文件结构和进程列表,大家应该看到了吧我sbin下面有init,所以我的1号进程为/sbin/init.

技术分享图片

 3、kthread进程启动。

如下图,紧接着创建了kthreadd进程。kthreadd这个进程函数里面是一个死循环。这是第三个进程,所以可以推测pid为2

技术分享图片技术分享图片

 如下图,当创建完进程到下一步时,我们看到pid为2

 技术分享图片

4、idle 进程

好了,现在创建好了1、2号进程,我们再说回0号进程。我们前面说了start_kernel就是0号,我们继续往下看他是怎么变回0号进程的。

技术分享图片技术分享图片技术分享图片

如上图,最终调用到cpu_idle_loop后是一个死循环。

总结:linux系统的起点是start_kernel,同时他也是第一个进程idle的入口函数。然后这个进程创建了init = 1进程和kthreadd = 2两个进程。

       重点是idle进程,这个进程不是通过do_fork出来的,他是制造出来的。后续其他进程都是有1进程fork出来的

 

以上是关于linux kernel启动失败,如何分析问题所在?的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动

win8硬盘安装linux重启出现:kernel panic not syncing:attempted to kill init

arm-linux内核start_kernel之前启动分析-开启MMU,走进新时代

powerpc-linux内核start_kernel之前启动分析-开门见山

20135239 益西拉姆 linux内核分析 跟踪分析Linux内核的启动过程

Linux内核分析:Linux内核启动流程分析