嵌入式Linux上使用Ramoops的代码应用

by toradex胡珊逢
对于嵌入式设备,尽管在部署前会经历大量的测试和验证,但在使用现场有时候仍不可避免会出现意外情况,如 kernel opps、panic。当出现类似情况时,系统日志往往无法及时写入 flash,重启后不能获得用于分析问题的关键信息。ramoops 可以应对此类问题。当发发生 kernel opps、panic时,它能够将相关日志保存到特定的内存区域,并在软重启后仍可以读取。文章将使用安装 linux bsp v3.0 的 apalis imx6 计算机模块进行说明。
首先使用 toradex easy installer 安装 linux bsp v3.0。然后下载对应的 linux 源码,分支为 toradex_4.14-2.3.x-imx。交叉编译工具是 gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf。
应用  apalis imx6 默认内核配置。
-----------------------------------------
$ make apalis_imx6_defconfig
-----------------------------------------
开启 ramoops 功能。
-----------------------------------------
$ make menuconfig
file systems → miscellaneous filesystems
  persistent store support                                                                                               
choose compression algorithm (zlib)  --->                                                                          
[*]     log kernel console messages                                                     
[*]     log user space messages      
    log panic/oops to a ram buffer
-----------------------------------------
为了便于触发 kernel panic 开启 sysrq 功能。
-----------------------------------------
kernel hacking
[*] magic sysrq key
0x1) enable magic sysrq key functions by default
[*]   enable magic sysrq key over serial  
-----------------------------------------
最后重新编译内核以及内核模块。
-----------------------------------------
$ make zimage loadaddr=10008000
$ make modules
-----------------------------------------
使用新的内核和模块重新启动 apalis imx6。ramoops 在内核配置里又称为 pstore,使用下面命令查看之前的内核内置是否生效。
-----------------------------------------
root@apalis-imx6:~# zcat /proc/config.gz |grep pstore
config_pstore=y
config_pstore_zlib_compress=y
# config_pstore_lzo_compress is not set
# config_pstore_lz4_compress is not set
config_pstore_console=y
config_pstore_pmsg=y
config_pstore_ram=y
root@apalis-imx6:~# zcat /proc/config.gz |grep sysrq
config_magic_sysrq=y
config_magic_sysrq_default_enable=0x1
config_magic_sysrq_serial=y
-----------------------------------------
此时,ramoops 还没有配置完成,需要在 device tree里创建对应的节点。在这之前先确定在内存中可以为 ramoops 预留的地址空间。在 linux 运行下面命令。
-----------------------------------------
root@apalis-imx6:~# cat /proc/iomem
00100000-00103fff : /soc/caam-sm@00100000
00120000-00128fff : 120000.hdmi_core
00130000-00133fff : galcore register region
……
02204000-02207fff : galcore register region
02400000-027fffff : 2400000.ipu
02800000-02bfffff : 2800000.ipu
10000000-4fffffff : system ram
10008000-10cfffff : kernel code
10e00000-10eeb3cf : kernel data
-----------------------------------------
ram 的物理地址空间为 0x10000000-0x4fffffff,选择在 kernel code 和 kernel data 之外的 0x30000000 作为 ramoops 的起始地址,大小为 1mb。
在 arch/arm/boot/dts/imx6q.dtsi 的 reserved-memory  节点里添加  ramoops。
重新编译 device tree。
-----------------------------------------
$ make imx6q-apalis-eval.dtb
-----------------------------------------
使用新的 device tree 启动后,可以看到以下信息。
-----------------------------------------
root@apalis-imx6:~# dmesg|grep ramoops
[    0.071682] pstore: registered ramoops as persistent store backend
[    0.071707] ramoops: attached 0x100000@0x30000000, ecc: 0/0
-----------------------------------------
下面命令分别设置系统在发生 kernel panic 时1 秒后自动重启,以及触发 kernel panic。
-----------------------------------------
root@apalis-imx6:~# echo 1 > /proc/sys/kernel/panic
root@apalis-imx6:~# echo c > /proc/sysrq-trigger
-----------------------------------------
在自动重启后,将 ramoops 挂载到 /home/root/pstore 目录,可以看到上次发生 kerne panic 时的日志。
-----------------------------------------
root@apalis-imx6:~# mkdir -p /home/root/pstore
root@apalis-imx6:~# mount -t pstore psotre /home/root/pstore
root@apalis-imx6:~# ls pstore/
console-ramoops-0  dmesg-ramoops-0    dmesg-ramoops-1
root@apalis-imx6:~/pstore# tail -n 5 console-ramoops-0
[  856.337055] ffa0:                                     00be5898 00000000 00000020 76ed4bb4
[  856.345259] ffc0: 00be5898 00000020 00000002 00000001 76ed71c0 00be6828 00000001 7ed702e0
[  856.353460] ffe0: 00000000 7ed70138 76dd382d 76d88cd0 000f0010 ffffffff
[  856.360101]  r9:00be6828 r8:10c5387d r7:10c5387d r6:ffffffff r5:000f0010 r4:76d88cd0
[  856.385215] rebooting in 1 seconds..
root@apalis-imx6:~/pstore# tail -n 5 dmesg-ramoops-0
[  856.200454]  r9:00000000 r8:00000000 r7:00000002 r6:00d00440 r5:a909bf00 r4:a909bf00
[  856.208233] [] (sys_write) from [] (ret_fast_syscall+0x0/0x54)
[  856.215828]  r9:a975a000 r8:80107f24 r7:00000004 r6:76f5bda0 r5:00d00440 r4:0000006c
[  856.223594] code: e5834000 f57ff04e ebf07aaa e3a03000 (e5c34000)
[  856.229847] ---[ end trace 583cc693cbfd2cb1 ]---
-----------------------------------------
由于 ramoops 是将日志保存在内存里,如果模块是冷启动,即电源复位,那么相关的内容也不再保留。
-----------------------------------------
root@apalis-imx6:~# mount -t pstore psotre /home/root/pstore
root@apalis-imx6:~# ls pstore/
root@apalis-imx6:~#
-----------------------------------------
参考
https://git.toradex.cn/cgit/linux-toradex.git/tree/documentation/admin-guide/ramoops.rst?h=toradex_4.14-2.3.x-imx
https://lwn.net/articles/501748/
总结
ramoops 可以使用较小的开销记录系统日志一般难以保存的 kernel panic 错误。由于存储于内存里面,因此在掉电后这些信息就不复存在。在 linux 中还有许多其他的调试方法,如kdb, kdump, tracing 等,它们的使用特点和复杂程度也各有不同,用户可以根据需求加以选择。


基于chiplet的设计更容易实现的工作正在进行中
如何评价我国国防科技工业军民融合的现状?
小米10即将发布起售价或许会在3000元以上
如何为Atary Lynx II更换LED背光
新荣耀未来的旗舰有望搭载骁龙888处理器?
嵌入式Linux上使用Ramoops的代码应用
超高温烧结块变形量检测(选用产品:ZLDS114)
破解中高端MCU难题!这家国产企业的制胜法宝是什么?
住友3M推出新型便携制造工序静电测量仪
保险丝选型
基于XC164CS和BTS7741G的中央门锁控制设计
占地400亩,华为上海巨型研发基地,正式启动!全球科创新核心!
了解EUV光刻技术在我国半导体芯片技术现状与差距
工控触摸平板的应用场合以及应用优势
LED板上芯片封装种类繁多,看海外大佬是如何进行LED芯片COB封装的?
互联网中OT与IT融合发展的需求分析
齐纳二极管原理
插座没插东西空开跳闸的几种情况
速腾聚创正式在港交所挂牌上市
Reno3 Pro解决了功耗难题,续航效果比华为Mate30还强