kdump_mmc
简介
当内存发生panic的时候,需要把panic的内容以日志的方式记录下来。目前有几种方式,kdump,mtdoops,crashlog(openwrt特有),以及pstore。
kdump主要用在x86系统上,因为它使用大量的内存和硬盘信息。
mtdoops和crashlog主要用于嵌入式系统。记录文本日志。
mtdoops
mtdoop功能在发生oops时,把msg区写入特定的mt分区。写入过程,不支持文件系统。直接二进制文本写。 它需要由mtd驱动的支持,就是mtd驱动支持mtd_panic_write。也就是原子式写入。不能被中断。一般flash不支持。 在mtdoops.c文件,并在标准内核的drivers/mtd/mtdcore中。
1 | mtd_panic_write |
在初始化过程中,需要指定写入哪个分区,对应的分区名/号,可以写入的size是多少。使用kmsg_dump_register注册一个cxt->dump.dump绑定的回调函数 (eg:mmcoops_do_dump),此函数主要是读取kmsg区的内容,直接调用mtd->write的驱动进行写操作。
crashlog
在linux内核启动的时候,保留一块64K的内存,用于记录panic日志,crashlog发生在oop时候,把msg写入之前分配好的MEM区域,并加上magic,再重启后,check magic ok,则把上次日志放入到/sys/kernel/debug/crashlog。
pstore
pstore最初是用于系统发生oops或panic时,自动保存内核log buffer中的日志。不过在当前内核版本中,其已经支持了更多的功能,如保存console日志、ftrace消息和用户空间日志。同时,它还支持将这些消息保存在不同的存储设备中,如内存、块设备或mtd设备。 为了提高灵活性和可扩展性,pstore将以上功能分别抽象为前端和后端,其中像dmesg、console等为pstore提供数据的模块称为前端,而内存设备、块设备等用于存储数据的模块称为后端,pstore core则分别为它们提供相关的注册接口。
通过模块化的设计,实现了前端和后端的解耦,因此若某些模块需要利用pstore保存信息,就可以方便地向pstore添加新的前端。而若需要将pstore数据保存到新的存储设备上,也可以通过向其添加后端设备的方式完成。
除此之外,pstore还设计了一套pstore文件系统,用于查询和操作上一次重启时已经保存的pstore数据。当该文件系统被挂载时,保存在backend中的数据将被读取到pstore fs中,并以文件的形式显示。
源码在/fs/pstore/ram_core.c
1 | fs/pstore/ |
oops/panic日志位于 pstore 目录下的dmesg-ramoops-x文件中,根据缓冲区大小可以有多个文件,x从0开始。
函数调用序列日志位于 pstore 目录下的ftrace-ramoops文件中。
使用方法
内核配置
1 | CONFIG_PSTORE=y |
设备树配置
1 | ramoops_mem: ramoops_mem { |
bootargs分区配置
1 | 方案1: |
挂载pstore文件系统
1 | mount -t pstore pstore /sys/fs/pstore |
summary
以上几种方案都使用到了kmsg_dump的注册机制。 注册很简单,就是把一个全局变量结构挂到一个全局list中。 kmsg_dump是oops时进入kmsg_dump的入口。由panic,die,oops_exit等函数调用。它会一一调用回调函数。 每一个回调函数都会用到kmsg_dump_get_buffer。它先是计算dump还有多少空间,然后把kmsg中最后的一部分写进去。