http://code.google.com/p/innosoc/wiki/KernelBootCrashDebug

注:

如在i386_start_kernel中加入:early_printk("in i386_start_kernel\n"); console可以立即看到,不用等到console_init后

kernel启动控制台还不可用时发生crash的调试方法

在调试linux kernel时,如果crash发生在控制台还不可用时,那将没有任何信息能够被打印,那分析原因就变成了一摸黑。有以下方法有助于帮助分析:

1, early printk

在kernel配置选项中启用CONFIG_EARLY_PRINTK=y, 那将可借助early_printk()函数打印信息,用early_printk在kernel启动的代码中加入一些打印点,可以帮助定位kernel boot到哪一位置。

early_printk的配置选项位于Kernel hacking, 还必须开启了CONFIG_DEBUG_LL=y,才能启用early printk.

Kernel hacking ---->
    [*] Kernel low-level debugging functions
    [*]     Early printk

这一功能,需要你的arch实现底层的uart发送函数, 即include/mach/debug-macro.S中的addruart, senduart, waituart, busyuart等函数。

2, dump log_buf内存

printk函数打印的信息首先都是存在log_buf这块内存的,即使console还没enable,printk函数也一样可以被调用,因此当kernel crash时,可以通过仿真器查看log_buf 这段内存,它里面存的就是通过printk打印的信息,如果没有仿真器,也可以重启bootloader,在bootloader里通过dump mem来查看。

log_buf这段内存的地址如何确定?通过System.map文件搜索log_buf,你就会找到log_buf的地址,如:

c0535bd8 b printk_buf
c0535fd8 b printk_time
c0535fdc b __log_buf
c0539fdc b cpu_online_bits
c0539fe0 b cpu_active_bits
c0539fe4 b cpu_present_bits
c0539fe8 b cpu_possible_bits
c0539fec B sys_tz
c053a000 b softirq_vec

这里我们看到log_buf
的内存地址在c0535fdc,这是个虚拟地址,根据kernel地址映射规律,从MEM_PHY_START到MEM_PHY_END,都会一一映射到
0xc0000000: (0xc0000000 + MEM_PHY_SIZE),因此假设我们内存的物理地址起始是0x0,那么这里log_buf的实际物理地址为0x00535fdc。

在确认完log_buf的内存地址之后,就可以用仿真器也好,bootloader也好,去查看printk打印的内容了。

kernel启动console_init之前console不可用时发生crash的调试方法的更多相关文章

  1. 使用MethodSwizzle导致按home app进入后台或者app间切换发生crash的解决方法

    参考文章: 1.http://blog.csdn.net/alincexiaohao/article/details/45913857 2.http://www.cocoachina.com/ios/ ...

  2. arm linux kernel启动之start_kernel

    了解完kernel启动以前的汇编之后我们来看看正式的c语言启动代码,也就是我们的start_kernel函数了.start_kernel相当大,里面每一个调用到的函数都足够我们伤脑筋了,我这里只是浅尝 ...

  3. andriod and linux kernel启动流程

    虽然这里的Arm Linux kernel前面加上了Android,但实际上还是和普遍Arm linux kernel启动的过程一样的,这里只是结合一下Android的Makefile,讲一下boot ...

  4. LINUX KERNEL启动参数

    LINUX KERNEL启动参数 在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时 ...

  5. Linux kernel启动选项(参数)(转)

    Linux kernel启动选项(参数)  转载链接https://www.cnblogs.com/linuxbo/p/4286227.html 在Linux中,给kernel传递参数以控制其行为总共 ...

  6. Linux kernel启动选项(参数)

    在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB ...

  7. linux内核可以接受的参数 | Linux kernel启动参数 | 通过grub给内核传递参数

    在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB ...

  8. Kernel启动时 驱动是如何加载的module_init,加载的次序如何;略见本文

    Init.h中有相关initcall的启动次序,在system.map中可看出具体的__initcall指针的前后次序 #define pure_initcall(fn) __define_initc ...

  9. linux kernel启动流程

    linux kernel启动是从./init/main.c中开始的,其大概流程是: 1. 调用start_kernel()函数: 2. start_kernel()调用rest_init()函数: 3 ...

随机推荐

  1. 【笔记】InnoDB内存分配

    原文:http://www.mysqlperformanceblog.com/2006/05/30/innodb-memory-usage/ 有很多问题是有关InnoDB如何分配内存的.这里我试图解释 ...

  2. [转载]jQuery诞生记-原理与机制

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=3520 一.看似偶然的 ...

  3. JS中数组排序

    法一:升序原理:循环嵌套即双向遍历,在从前往后的遍历过程中,如果前一个位子大于后一个位子,把前一个位子的值付给后一个位子, 在从后往前遍历过程中如果前一个值大于后一个的值,把前面的值付给后面,过程中把 ...

  4. javascript创建对象的几种方式

    javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用.主要为下面几种:1.对象字面量的方式 person={firstname ...

  5. [deviceone开发]-do_Camera的简单示例

    一.简介 do_Camera组件是通过拍照裁剪来生成图片的组件,这个示例直观的展示组件基本的使用方式 二.效果图 三.相关下载 https://github.com/do-project/code4d ...

  6. JavaScript基础18——js的Array对象

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Hybrid框架UI重构之路:四、分而治之

    上文回顾:Hybird框架UI重构之路:三.工欲善其事,必先利其器 上一篇文章有说到less.grunt这两个工具,是为了css.js分模块使用的.UI框架提供给使用者的时候,是一个大的xxx.js. ...

  8. android键盘弹出头部上移处理

    <ScrollView android:id="@+id/top_bar" android:layout_width="fill_parent" andr ...

  9. 转 用C API 操作MySQL数据库

    用C API 操作MySQL数据库 参考MYSQL的帮助文档整理 这里归纳了C API可使用的函数,并在下一节详细介绍了它们.请参见25.2.3节,“C API函数描述”. 函数 描述 mysql_a ...

  10. 如何自定义ViewGroup

    依照惯例,先从一个例子说起. 很简单,3张扑克牌叠在一起显示.这个布局效果该如何实现呢?有的同学该说了,这很简单啊,用RelativeLayout或FrameLayout,然后为每一个扑克牌设置mar ...