You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)的状态寄存器操作存在本质差异:

    1. 原代码用32位int变量存储64位DAIF寄存器的值,执行mrs指令时会因位数不匹配触发非法指令;
    2. 32位ARM的CPSR寄存器中IRQ屏蔽位在第7位,而Aarch64的DAIF寄存器中IRQ屏蔽位(I位)在第2位,原代码的位偏移逻辑完全错误。
  • 修复步骤:

    1. 修正寄存器读取与变量类型:使用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;
      }
      
    2. 验证中断控制指令:Aarch64中msr daifset, #2用于屏蔽IRQ,msr daifclr, #2用于启用IRQ,这部分指令是正确的,无需修改,但要确保编译器以64位模式编译代码。
    3. 兼容性优化(可选):避免直接编写架构相关的汇编代码,改用标准系统调用或库函数控制中断,比如使用sigprocmask管理信号屏蔽,减少架构依赖。
  • 额外检查:确认使用的JETGPIO库是否适配64位Aarch64系统,若库内部存在类似32位汇编代码,需同步修改或更换为64位兼容版本。

内容的提问来源于stack exchange,提问作者Dominic Ng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:45:02