kernel crash dump info 保存
Kernelcrash dump 1.??????在系统运行过程中,如果系统发生了crash,那么开发人员需要通过crash信息来进行debug. 并进一步定位问题。而crash信息存在于内核ring buffer中,系统重启后就丢失了,所以需要一种方法,可以在系统发生crash时,将crash info保存于非易失存储器中,那么下面就来介绍一种方法实现这种功能。 2.??????预备: a)????????当kernel crash发生时,crash dump info会被flush 到kernel ring buffer中,这个是kernel主动的行为。 b)????????当kernel crash发生时, 可以主动调用do_sysinfo(),将系统的一些内存与进程信息flush至kernel ring buffer,(即利用printk(),将获取的信息打印出来)。 c)????????当kernel crash 发生时,可以主动的将进程的调用栈信息flush到kernel ring buffer,这样很有利于调试和定位问题。 Notice: b,c 属于一个主动的行为,也可以不做。 3.kernel ring buffer? ?????? Kernel为系统打印kmalloc了一块内存,一般大小为128K,即将所有的printk的打印信息输出这个buffer,在console,可能通过dmesg来查看这个ring buffer的所有内容,可以用dmesg –c将这个ring buffer全部清空。 ???????? 执行dmesg命令,你可以看到,系统从启动到现在完整的log信息。一般来说128k,足够保存所有的log信息,如果你在内存中打印很多信息,那么也有可能比较的信息会被覆盖掉。 4.下面写了一个框架来保存ring buffer信息。(存储设备:nor flash,其他类弄的设备都很类似) static int apanic(struct notifier_block *this,unsigned long event,void *ptr) { ... ... /* * 打印系统内存相关信息 */ do_sysinfo(&si); printk(si); ... /*其他相的打印的信息......*/ ... /* * 打印线程调用栈信息 */ show_state_filter(0); /* * 最后一步,也是最重要的一步,保存所有信息到flash */ /* Return log buffer address */ start = log_buf_addr_get(); /* Return log buffer size */ len = log_buf_len_get(); /*这个是最简单的一种方法,直接把ring buffer拷贝到flash * 如果想要实现更好的,那么可以调用syslog_print_all(),即 * 自己kmalloc一个buffer,所翻译之后的内容写入到flash.具体 * 自行分析printk运行机制。 */ mtd->_write(mtd,off,len,&wlen,start); } static void mtd_panic_notify_remove(struct mtd_info *mtd) { /*这里并没有什么特别的操作,如果分配的特别的资源,那么需要进行释放*/ } static void mtd_panic_notify_add(struct mtd_info *mtd) { if (strcmp(mtd->name,"crash")) return; 获取crash 分区的mtd信息。 /* * 这里可以做一些实始化的操作,比如erase crash 分区。识别并 * 标志这个分区。等等,所有设计及功能,都可以来设计。 */ } /*panic notifier callback*/ static struct notifier_block panic_blk = { .notifier_call = apanic,}; /*mtd notifier callback*/ static struct mtd_notifier mtd_panic_notifier = { .add = mtd_panic_notify_add,.remove = mtd_panic_notify_remove,}; int __init apanic_init(void) { /* * 注册mtd 通知链回调,目的为了获取保存kernel crash info的分区信息。 * 比如分区名为"crash" * (kernel 创建一个分区,就会调用mtd_notifier.add回调。 * 删除一个分区,就会调用mtd_notifier.remove回调) */ register_mtd_user(&mtd_panic_notifier); /* * 注册panic 回调。目的是为了在发生panic时,可以做一些想做的操作。 * 比如保存信息到flash,做一些恢复操作。。。 * panic_blk是一个回调函数,所有操作可以在这个函数里做。 */ atomic_notifier_chain_register(&panic_notifier_list,&panic_blk); return 0; } Notice: ?echo c > /proc/sysrq-trigger //这个命令可以让kernel crash (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |