如何解决调试内核 ECC 清理 ARM v7 Cyclone V SOC
我是一名硬件工程师,负责使用 Altera intel 的 Cyclone V SX SOC FPGA 开发新硬件。
我刚刚完成了我的 DDR3-800 内存时序验证(是的,它是一个旧芯片)。
我试图通过将数据位短接到地来证明 ECC 内存正常工作,这是验证硬件和软件处理位错误的常见做法。
然而,当我将 D1 短接至地时,内核恐慌了。
这是“decode_stacktrace.sh”解码输出的顶部
(注意:最上面一行来自我添加到 Altera_EDAC 驱动程序中的一个 printk)
[ 1299.870164] EDAC: [226 Correctable errors @ 0x000E33C4]
[ 1299.876892] EDAC MC0: 184 CE soc:sdramedac on mc#0csrow#0channel#0 (csrow:0 channel:0 page:0x6a3 offset:0xb9c grain:8 syndrome:0x0)
[ 1299.891822] Unable to handle kernel paging request at virtual address c06a3b9c
[ 1299.899021] pgd = b6c6b929
[ 1299.901724] [c06a3b9c] *pgd=0061940e(bad)
[ 1299.905736] Internal error: Oops: 80d [#1] SMP ARM
[ 1299.910515] Modules linked in:
[ 1299.913567] cpu: 0 PID: 0 Comm: swapper/0 Not tainted 5.11.0-wtec #5
[ 1299.919903] Hardware name: Altera SOCFPGA
[ 1299.923900] PC is at edac_raw_mc_handle_error (./arch/arm/include/asm/edac.h:26 drivers/edac/edac_mc.c:816 drivers/edac/edac_mc.c:938 drivers/edac/edac_mc.c:1010)
[ 1299.929301] LR is at __kmap_local_page_prot (mm/highmem.c:542)
[ 1299.934344] pc : lr : psr: 000f0193
[ 1299.940587] sp : c0e01b70 ip : c0e01b58 fp : c0e01bd4
[ 1299.945792] r10: 00000000 r9 : c0e01c10 r8 : ef7f9000
[ 1299.950998] r7 : 00000000 r6 : 000006a3 r5 : 00000b9c r4 : 00000008
[ 1299.957500] r3 : c06a3b9c r2 : c06a3ba4 r1 : ebfb755f r0 : c06a3000
[ 1299.964003] Flags: nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
[ 1299.971201] Control: 10c5387d Table: 02b0004a DAC: 00000051
[ 1299.976924] Process swapper/0 (pid: 0,stack limit = 0x10d9740f)
[ 1299.982911] Stack: (0xc0e01b70 to 0xc0e02000)
我通过查看 linux 内核源代码对此进行了跟踪。这是我认为正在发生的事情:
- 我将 D1 短接到地。
- ECC 启动并修复该位,触发中断。
- 在这种情况下,我对 D1 信号的轻刷会导致 226 个可纠正错误。
- Altera ECC 驱动程序处理中断、收集信息并将所述信息返回给 ECC 管理器。
- ECC 管理器尝试使用位于“edac.h”中的一些内联程序集来清理受影响的内存,如下所示:
static inline void edac_atomic_scrub(void *va,u32 size)
{
#if __LINUX_ARM_ARCH__ >= 6
unsigned int *virt_addr = va;
unsigned int temp,temp2;
unsigned int i;
for (i = 0; i < size / sizeof(*virt_addr); i++,virt_addr++) {
/* Very carefully read and write to memory atomically
* so we are interrupt,DMA and SMP safe.
*/
__asm__ __volatile__("\n"
"1: ldrex %0,[%2]\n"
" strex %1,%0,[%2]\n"
" teq %1,#0\n"
" bne 1b\n"
: "=&r"(temp),"=&r"(temp2)
: "r"(virt_addr)
: "cc");
}
#endif
}
#endif
更新:我已经确定第一个地址会导致 oops 并且即使有很多错误,我捕获的示例的大小(在上面的之后)只有 8 长。
这段代码太不符合我的要求了。我希望有经验的人可以成为我的老师,告诉我如何去做。
此时我唯一的选择是尝试查看内核如何将硬件的物理地址重新映射到虚拟内存中。我想这就是问题所在。
任何帮助将不胜感激。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。