对于基于 MIPS 的嵌入式设备,我们正在经历内核恐慌。如何在 MTD 分区中记录内核恐慌跟踪?我们必须只将跟踪写入 MTD 还是可以通过 NFS 写入?任何人都可以解释如何在远程框恐慌之后获得有用的内核跟踪。
2 回答
您可以在内核中打开 mtdoops 模块并将内核恐慌跟踪记录到 mtd 分区。我认为我们不能通过 NFS 编写恐慌跟踪。但是,您可能想探索有关 ramoops 的信息。
以下是配置内核以将内核 oops 捕获到 mtd 闪存的步骤。在内核恐慌之后捕获堆栈跟踪对于调试内核问题特别是在现场发生的问题非常宝贵。在 mtdoops 模块初始化期间,mtd 分区变成一个循环缓冲区并预先擦除。
内核标志CONFIG_MTD_OOPS将内核配置为将 oops 堆栈跟踪写入 MTD 分区。此 MTD 开发分区信息可以在 mtdoops 模块中进行硬编码,也可以动态指定。该组件可以作为内核的一部分构建,也可以作为单独的模块构建。在构建内核之前,您需要确保您的 mtd 设备已经注册了一个 panic_write 处理程序。请记住,普通的 mtd 写入处理程序是不够的,因为我们必须在内核崩溃后写入 mtd 内存。如果 mtd 设备没有自己的紧急写入处理程序,请运行此补丁。
当作为内核的一部分构建时,CONFIG_MTD_OOPS=y,mtdoops 模块需要使用闪存分区信息 (mtddev) 进行修补。
--- ./drivers/mtd/mtdoops.c.orig 2014-11-17 12:06:59.000000000 +0000 +++ ./drivers/mtd/mtdoops.c 2014-11-17 12:07:36.000000000 +0000 @@ -44,7 +44,7 @@ MODULE_PARM_DESC(record_size, "record size for MTD OOPS pages in bytes (default 4096)"); -static char mtddev[80]; +static char mtddev[80]="/dev/oops"; module_param_string(mtddev, mtddev, 80, 0400); MODULE_PARM_DESC(mtddev, "name or index number of the MTD device to use");
在将其构建为模块时,CONFIG_MTD_OOPS=m,闪存分区信息在模块安装期间动态提供(insmod)。
insmod mtdoops.ko mtddev=/dev/oops
除了启用 MTP OOPS 标志外,请配置 CONFIG_MAGIC_SYSRQ,以引发恐慌并测试此功能。
- 现在,我们需要创建一个 MTD 分区(/dev/Oops)来存储恐慌痕迹。MTD 可以通过修改在arch///.c的内核源代码中定义的内存布局和分区信息来进行分区。此外,您需要注意作为内核命令行一部分传递的分区信息将覆盖board.c更改。
{ .name = "loader", .size = 0x000E0000, .offset = MTDPART_OFS_APPEND }, { .name = "kernel", .size = 0x002A0000, .offset = MTDPART_OFS_APPEND }, { .name = "oops", .size = 0x000E0000, .offset = MTDPART_OFS_APPEND }, { .name = "all", .size = MTDPART_SIZ_FULL, .offset = 0x00000000 },
- 构建内核,mtdoops.ko 将作为根文件系统的一部分构建。安装文件系统并确保已创建分区。
cat /proc/mtd dev: size erasesize name mtd0: 000e0000 00020000 "loader" mtd1: 002a0000 00020000 "kernel" mtd3: 000e0000 00020000 "Oops" mtd5: 08000000 00020000 "all"
- 现在,使用 Magic SysRq 键触发恐慌并观察 Oops 分区中的内核恐慌日志。
非常感谢详细的步骤。一切似乎都很好,除了设备名称。当我将设备名称指定为“/dev/oops”时,mtdoops 未连接到引导消息中的任何设备。经过一番调试,我发现设备名称应该只是“oops”或“Partition number”即(如果您的oops 分区是mtd9,只需将“9”作为分区号)。更改后,它开始工作。我可以使用 sp-oops-extract 查看日志。