Jetson Nano 64位系统SIGILL非法指令问题求助
Jetson Nano 2GB 64位系统下gdb调试触发SIGILL非法指令错误
使用Jetson Nano 2GB开发板,在64位Aarch64架构系统下通过gdb调试时触发SIGILL非法指令错误,报错位置为Sx1278.cpp第92行的汇编指令:
92 __asm__ __volatile__("mrs %[res], daif": [res] "=r" (res)::); (gdb) Program received signal SIGILL, Illegal instruction. INTERRUPTS_ENABLED () at Sx1278.cpp:92
引发问题的汇编代码如下:
__inline__ int INTERRUPTS_ENABLED(void) { int res; __asm__ __volatile__("mrs %[res], daif": [res] "=r" (res)::); return ((res >> 7) & 1) == 0; } __inline__ void ENABLE_INTERRUPTS(void) { if (!INTERRUPTS_ENABLED()) { __asm__ __volatile__("msr daifset, #2"); } } __inline__ void DISABLE_INTERRUPTS(void) { if (INTERRUPTS_ENABLED()) { __asm__ __volatile__("msr daifclr, #2"); } }
代码基于LoRa4Raspi修改,使用JETGPIO库控制GPIO引脚实现Sx1278(LoRa)模块通信,在32位Raspbian系统中可正常运行,但切换到64位Aarch64系统后出现此问题,怀疑问题出在INTERRUPTS_ENABLED函数,寻求诊断和修复建议。
诊断与修复建议
问题根源:32位ARM(ARMv7)与64位Aarch64(ARMv8)的状态寄存器操作存在本质差异:
- 原代码用32位
int变量存储64位DAIF寄存器的值,执行mrs指令时会因位数不匹配触发非法指令; - 32位ARM的CPSR寄存器中IRQ屏蔽位在第7位,而Aarch64的DAIF寄存器中IRQ屏蔽位(I位)在第2位,原代码的位偏移逻辑完全错误。
- 原代码用32位
修复步骤:
- 修正寄存器读取与变量类型:使用64位类型存储DAIF寄存器值,并调整位判断逻辑:
#include <stdint.h> __inline__ int INTERRUPTS_ENABLED(void) { uint64_t res; __asm__ __volatile__("mrs %[res], daif": [res] "=r" (res)::); // DAIF的I位(第2位)为1表示IRQ被屏蔽,返回0;反之返回1表示中断启用 return ((res >> 2) & 1) == 0; } - 验证中断控制指令:Aarch64中
msr daifset, #2用于屏蔽IRQ,msr daifclr, #2用于启用IRQ,这部分指令是正确的,无需修改,但要确保编译器以64位模式编译代码。 - 兼容性优化(可选):避免直接编写架构相关的汇编代码,改用标准系统调用或库函数控制中断,比如使用
sigprocmask管理信号屏蔽,减少架构依赖。
- 修正寄存器读取与变量类型:使用64位类型存储DAIF寄存器值,并调整位判断逻辑:
额外检查:确认使用的JETGPIO库是否适配64位Aarch64系统,若库内部存在类似32位汇编代码,需同步修改或更换为64位兼容版本。
内容的提问来源于stack exchange,提问作者Dominic Ng
相关产品推荐
相关产品推荐

