ARM平台Linux内核init线程未处理信号致系统冻结问题咨询
ARM AM5728平台内核init阶段驱动异常导致系统冻结问题解答
问题根因
- initcall执行顺序与平台初始化依赖缺失
AM5728属于TI OMAP5系列架构,其L3互联总线错误路由、ARM异步异常(SError)上报初始化、故障处理钩子框架的完成节点在late_initcall之前。若你的驱动使用默认module_init(对应device_initcall级别),或是初始化顺序早于平台异常处理组件,你注册的hook_fault_code钩子尚未生效,甚至触发的异步外部中止根本无法被路由到ARM核心的异常处理入口,直接触发系统panic冻结。
模块加载场景无问题的原因是:模块加载发生在用户态init进程启动后,此时平台所有异常处理逻辑已初始化完成。 - 内核态与用户态异常处理逻辑差异
你提供的devmem2复现日志属于用户态地址访问异常,内核会自动将该类异常转换为SIGBUS信号发送给用户进程,不会影响内核稳定性。但驱动init线程属于内核态上下文,默认不会将异常转换为信号处理:如果对应的故障钩子没有明确标记该异常已处理,内核会直接进入oops/panic流程,表现为系统冻结。 - 现有fault钩子未适配内核态异常
参考pcie-keystone.c的ks_pcie_fault处理逻辑,原生实现默认仅处理用户态触发的外部中止,未适配内核态访问异常场景。你直接复用相同逻辑的话,内核态触发的异常不会被识别处理,最终还是会触发系统崩溃。
解决方案
- 调整驱动init调用级别,将驱动初始化接口从默认
module_init改为late_initcall,确保平台异常处理框架、L3错误路由、PCIe基础初始化全部完成后再执行你的驱动逻辑。 - 内核态访问可能触发外部中止的IO/配置空间地址时,添加异常修复表(extable)条目:可以直接使用内核提供的
memcpy_fromio_checked/memcpy_toio_checked接口,或手动在汇编访问逻辑中添加_ASM_EXTABLE定义,确保访问出错时能跳转到错误处理分支,不会直接触发异常。 - 修改你注册的fault钩子逻辑,新增内核态异常适配:判断异常触发上下文为内核态且故障码匹配时,返回
FAULT_CODE_HANDLED,同时将程序指针指向预先定义的fixup地址,让内核可以正常恢复执行。 - 确认内核配置项:开启
CONFIG_ARM_UNWIND、CONFIG_KALLSYMS方便调试,关闭CONFIG_PANIC_ON_OOPS避免异常直接触发重启,确认CONFIG_OMAP_L3_ERROR已开启,保证L3总线错误可以正常上报到ARM核心异常处理流程。
内容的提问来源于stack exchange,提问作者Vir91
相关产品推荐
相关产品推荐

