linux-kernel - 重启后如何检测内核 panic

标签 linux-kernel embedded coredump panic

我在嵌入式设备上意外重启。由于 ioctl 调用,我目前能够检测到硬件看门狗问题。现在我希望能够检测到内核 panic 是否是重启的原因。我找到了一些关于 crashkernel 和 crashdump 的文章,但我无法使其正常工作。而且我不想存储内核崩溃日志。只是能够知道内核 panic 是否发生。

我目前的想法是写在mmc上的保留空间。我目前正在使用预留空间来处理双重分配系统。这是个好主意吗?是否可以在内核崩溃期间在 mmc 中写入?我不确定,但似乎我可以使用某种内核 panic Hook 来在此事件上运行例程。

没有标准的方法可以检查启动时是否发生内核 panic ?

最佳答案

感谢@0andriy How to detect a kernel panic after reboot 的评论,我能够检测和调试内核崩溃

在内核 defconfig 中启用 ramoops:

+CONFIG_PSTORE=y
+CONFIG_PSTORE_ZLIB_COMPRESS=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_RAM=y

在你的内核板init中添加代码来声明ramoops内存空间,你 也可以使用设备树,甚至可以使用内核 procline 中的参数 这是一个使用代码方法的示例,在我的用例中它位于 arch/arm/mach-imx/mach-imx6ul.c

--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -21,6 +21,24 @@
 #include "cpuidle.h"
 #include "hardware.h"

+#include <linux/pstore_ram.h>
+#include <linux/memblock.h>
+
+static struct ramoops_platform_data ramoops_data = {
+       .mem_address = 0xXXXXXXXX, // Depending of the hardware
+       .mem_size = 0x00005000, // 5 Mb
+       .record_size = 0x00002000, // 1 Mb
+       .dump_oops = 1,
+};
+
+static struct platform_device ramoops_dev = {
+       .name = "ramoops",
+       .dev = {
+               .platform_data = &ramoops_data,
+       },
+};
+
+
 static void __init imx6ul_enet_clk_init(void)
 {
        struct regmap *gpr;
@@ -170,6 +188,14 @@ static inline void imx6ul_enet_init(void)
 static void __init imx6ul_init_machine(void)
 {
        struct device *parent;
+       int ret;
+
+       ret = platform_device_register(&ramoops_dev);
+       if (ret) {
+               printk(KERN_ERR "unable to register platform device\n");
+               return;
+       }
+       memblock_reserve(ramoops_data.mem_address, ramoops_data.mem_size);

        parent = imx_soc_device_init();
        if (parent == NULL)

然后在启动时我只需要检查 ramoops 的内容来检查是否有可用的内核崩溃日志。我可以使用 ramoops 内存空间:

mount -t pstore -o kmsg_bytes=1000 - /sys/fs/pstore

关于linux-kernel - 重启后如何检测内核 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47749955/

相关文章:

network-programming - 多线程应用程序中的直接内存访问 (DMA) 调度

android - 如何下载适用于 Nexus 9 的安卓 Lollipop 源代码?

linux - 用于删除的 Dentry 缓存

embedded - 在 x86 嵌入式设备上安装 Windows CE

linux - YOCTO 更改内核版本并选择驱动程序

c - 为什么 WiringPiISR 在被触发时不阻塞主例程?

c++ - 在stm32上解释来自触摸屏 Controller (ADS7843)的原始数据

linux - 核心转储到管道失败

c++ - 随机错误核心转储: `./a.out'中的错误:free():下一个大小无效(快速):0x00000000010e8d70 ***已中止(核心转储)

c - 段错误(Core Dumped)--结构和指针--C语言