Platform: RK3288
OS: Android 6.0
Kernel: 3.10.92
背景:
最近遇到如下现象:
- 自动随机重启
- 板子连接adb和uart无响应
这两个问题都需要抓取上一次的kernel log来查找问题。
虽然我有在系统上做了重启后log的保存机制,但是由于是在用户空间使用脚本做的处理,
如果是kernel crash此类issue,就有可能无法保存到log文件中。
后来得知rk在rk3288 android6.0上有实现了类似机制,此代码也适用到其他Linux平台。
查看方法:
#cat /proc/last_kmsg
注意事项:
- 针对现象1如果怀疑是reset键引起,那么可以硬件上先屏蔽掉物理按键缩小问题范围。
- 针对现象2手动重启如按reset按键必须要保证ddr不掉电,可以直接外接电源到ddr上。
- 如果查看/proc/last_kmsg里的内容是乱码,那么说明ddr掉过电了。
源代码分析:
源代码路径:
kernel/arch/arm/mach-rockchip/last_log.c
原理:
从printk中的buf中copy一份到buf中,如果系统重启,由于ddr没掉电,因此buf中的数据没有丢失,然后将这个buf拷贝到另一个buf中,当用户读取/proc/last_kmsg或者/proc/last_log(前者的链接),输出另一个buf即可。
代码说明:
//LOG_BUF_SHIFT和LOG_BUF_LEN以及LOG_BUF_PAGE_ORDER和printk中的buf存放地址和大小保持一致。
#define LOG_BUF_SHIFT CONFIG_LOG_BUF_SHIFT
#define LOG_BUF_LEN (1 << LOG_BUF_SHIFT)
#define LOG_BUF_PAGE_ORDER (LOG_BUF_SHIFT - PAGE_SHIFT)
//保存上一次的log buf地址
static char *last_log_buf;
//保存当前log buf地址
static