打印
[嵌入式Linux]

实战案例 | 基于ramoops的kernel panic故障定位技巧

[复制链接]
1501|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gztwdz4379 于 2025-6-6 09:03 编辑

前言:
对于嵌入式产品的开发使用,尽管会经历大量的测试和验证,但在大批量生产中,硬件物料的适配一致性,应用软件的异常消息队列等因素,使得现场使用中存在极小概率发生意外状况,出现如 kernel opps、panic等死机现象。这时系统日志无法及时写入 flash,重启后没有存到任何关键信息,工程师也崩溃了。下文则基于眺望电子T113-i核心板产品为例,介绍如何在Linux系统上搭建并验证ramoops, 以便在系统崩溃或异常时进行故障排查。

一、ramoops简介

ramoops 是一个 oops/panic 日志记录器,它在系统崩溃之前将其日志写入 RAM。它的工作原理是将 oops panic 记录在循环缓冲区中。ramoops 需要具有持久 RAM 的系统,以便该区域的内容在重启后仍然存在。



二、ramoops搭建


2.1 环境说明

  • 平台:T113-I Tina
  • SDKtalowe-T113-I-Tina-sdk_2025_03_10.tar.gz
  • Kernel版本:5.4.61
  • DRAM类型:DDR3
  • 查看系统内存
[root@T113-I:/]# cat /proc/iomem
可以看到SRAM地址为0x40000000~0x5FFFFFFF,共512M,可以选择kernel code和kernel data以外的地址用作ramoops空间。

2.2 内核配置修改

ramoops在内核里面叫pstore ram,源码路径为:
    kernel/linux-5.4/fs/pstore/ram_core.c
    kernel/linux-5.4/fs/pstore/ram.c
<font size="2">CONFIG_PSTORE_RAM=y            # 下面的根据自己需求
CONFIG_PSTORE_CONSOLE=y    # 保存控制台日志(上一次的)
CONFIG_PSTORE_PMSG=y          # 用户信息存储,可以往/dev/pmsg0节点写入</font>
  设备树配置
<font size="2">reserved-memory {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;
    ramoops@5f000000 {
        compatible = "ramoops";</font>

使用参数解析:
  • reg = <0 0x5f000000 0 0x100000>;0x5f000000开始,划分0x100000内存(也就是1M),用于ramoops
  • record-size = <0x40000>;   分配使用256K来存储oops/panic信息,文件名称为dmesg-ramoops-0
  • console-size = <0x4000>;分配使用16K来存储上一次的内核信息,文件名称为console-ramoops-0
  • pmsg-size = <0x4000>;分配使用16K来存储用户上一次向/dev/pmsg0节点写入的信息,文件名称为pmsg-ramoops-0
  • no-map;必须添加,亦或者修改kernel的内存初始化,将这部分空间预留出来

其他参数:
  • ecc-size = <value>;使用ecc纠错机制,纠错字节数为valuevalue1时,使用16字节来纠错,其他值会直接使用使用ecc会消耗更多内存消耗的内存,消耗的内存与cnt有关,如下面注2cnt3,则会消耗3*ecc_value

注1:size为2的幂向下取整
注2:如果内存划分不规范,可能record的实际大小由(mem_size - console_size - pmsg_size) / record_size决定,如上面例子(0x100000 - 0x4000 - 0x4000)/0x40000,结果向下取整为3,所以record的大小为(0x100000 - 0x4000 - 0x4000)/ 3 ,结果向下取整为330k

2.3 系统加载确认
2.3.1 驱动加载查看
将如上修改后的固件镜像烧写到T113-i核心板,进入系统后,使用以下指令查看ramoops内存分配是否成功,如下图显示:成功从0x5f000000开始分配了0x100000(既1M),未启用ECC纠错码(设备树添加ecc-size属性可以开启)
<font size="2">[root@T113-I:/]# dmesg | grep ramoops</font>

<font size="2">[root@T113-I:/]# cat /proc/iomem</font>

  • 5f000000~5f052aa9:330K,用作存储上一次oops/panic信息
  • 5f052aaa~5f0a5553:330K,用作存储上一次oops/panic信息
  • 5f0a5554~5f0f7ffd:330K,用作存储上一次oops/panic信息
  • 5f0f7ffe~5f0fbffd:16K,用作存储上一次系统的内核信息
  • 5f0fbffe~5f0ffffd:16K,用于存储上一次用户自定义信息(向/dev/pmsg0写入的信息)
注3:建议record按照实际大小分配一份即可,因为ramoops使用一个计数器来记录多个转储,但计数器在重启时重置(即,重启后的新转储将覆盖旧转储),所以每次都会将dmesg-ramoops-0覆盖。

2.3.2 查看ramoops起始地址(mem_address)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/mem_address
[root@T113-I:/]# printf "0x%x\n" $(cat /sys/module/ramoops/parameters/mem_address)</font>
2.3.3 查看ramoops分配大小(mem_size)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/mem_size
[root@T113-I:/]# printf "0x%x\n" $(cat /sys/module/ramoops/parameters/mem_size)</font>
2.3.4 查看设备树record-size设置(record_size)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/record_size
[root@T113-I:/]# printf "0x%x\n" $(cat /sys/module/ramoops/parameters/record_size)</font>

既256K
2.3.5 查看设备树console-size设置(console_size)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/console_size
[root@T113-I:/]# printf "0x%x\n" $(cat /sys/module/ramoops/parameters/console_size)</font>

既16K
2.3.6 查看设备树pmsg-size设置(pmsg_size)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/pmsg_size
[root@T113-I:/]# printf "0x%x\n" $(cat /sys/module/ramoops/parameters/pmsg_size)</font>

既16K
2.3.7 查看是否开启ecc纠错(ecc)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/ecc</font>

  • 0:未开启
  • 非0:开启,使用该值的字节进行纠错

2.3.8 查看存储哪些的内核信息类型(dump_oops)
<font size="2">[root@T113-I:/]# cat /sys/module/ramoops/parameters/dump_oops</font>

  • 1:存储panic和oops
  • 2:跳过oops存储,只存储panic
  • 其他:请查看kernel/linux-5.4/include/linux/kmsg_dump.h和ramoops的ramoops_pstore_write函数
三、ramoops机制验证

3.1 触发panic测试


<span style="font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; white-space: pre; color: rgb(51, 51, 51); font-size: 14px; font-weight: 400; letter-spacing: 0.544px;">[root@T113-I:</span><span class="code-snippet__regexp" style="font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; white-space: pre; font-size: 14px; font-weight: 400; letter-spacing: 0.544px; -webkit-tap-highlight-color: transparent; outline: 0px; max-width: 1000%; color: rgb(202, 125, 55); box-sizing: border-box !important;">/]# echo c > /pr</span><span style="font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; white-space: pre; color: rgb(51, 51, 51); font-size: 14px; font-weight: 400; letter-spacing: 0.544px;">oc/sysrq-trigger                         </span><span class="code-snippet__comment" style="font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; white-space: pre; font-size: 14px; font-weight: 400; letter-spacing: 0.544px; -webkit-tap-highlight-color: transparent; outline: 0px; max-width: 1000%; color: rgb(175, 175, 175); font-style: italic; box-sizing: border-box !important;"># 触发panic</span>
重启后,挂载pstore系统查看日志
<font size="2">[root@T113-I:/]# mount -t pstore pstore /sys/fs/pstore/
[root@T113-I:/]# ls /sys/fs/pstore/
[root@T113-I:/]# tail -n 20 /sys/fs/pstore/dmesg-ramoops-0 #防止信息太多,只看之后20行</font>

如下图,可以看到前面的系统时间与内容和崩溃时打印的一模一样,同时前面多了日志等级标记
同时,console-ramoops-0也会有以上信息,这里只看最后10行方便对比
<font size="2">[root@T113-I:/]# tail -n 10 /sys/fs/pstore/dmesg-ramoops-0
[root@T113-I:/]# tail -n 10 /sys/fs/pstore/console-ramoops-0</font>

3.2 ramoops文件对比
       由上一小节panic的测试可以看到console-ramoops-0的日志内容和dmesg-ramoops-0的日志内容一模一样,两者的区别是console-ramoops-0为reboot前的内核所有信息,dmesg-ramoops-0为上一次触发panic/oops时内核的所有信息
       在上小节测试完成后,执行reboot,系统重新启动后可以看到信息不一致,console为上一次内核信息
<font size="2">[root@T113-I:/]# mount -t pstore pstore /sys/fs/pstore/
[root@T113-I:/]# tail -n 10 /sys/fs/pstore/dmesg-ramoops-0
[root@T113-I:/]# tail -n 10 /sys/fs/pstore/console-ramoops-0</font>

3.3 用户自定义pmsg-ramoops
写入信息
<font size="2">[root@T113-I:/]# echo 123 > /dev/pmsg0
[root@T113-I:/]# echo 456 > /dev/pmsg0
[root@T113-I:/]# reboot
[root@T113-I:/]# mount -t pstore pstore /sys/fs/pstore/
[root@T113-I:/]# cat /sys/fs/pstore/pmsg-ramoops-0</font>




四、小结

以上则是基于ramoops在全志T113-i平台上的简单使用技巧,若您也有linux系统方面的问题或想了解更多相关技术知识或产品信息,请关注眺望电子公众号并联系我们,我们将竭诚为您服务!



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

5

帖子

0

粉丝