local_irq_disable的定义有两处,和跟踪调试有关,由CONFIG_TRACE_IRQFLAGS_SUPPORT宏开关加以区分,当关闭这个宏的时候我怀疑2.6的内核定义是颠倒的,翻看最新的4.14.15的内核发现果然是定义颠倒了。不过我们主要关注的是宏开关打开后的定义。
local_irq_disable宏定义在include/linux/irqflags.h文件中。
#define local_irq_disable() \
do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)
而raw_local_irq_disable宏定义在include/asm-arm/irqflags.h文件中,跟arm版本有关,由__LINUX_ARM_ARCH__加以区分。
#if __LINUX_ARM_ARCH__ >= 6
#define raw_local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc")
#else
#define raw_local_irq_disable() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
"mrs %0, cpsr @ local_irq_disable\n" \
" orr %0, %0, #128\n" \
" msr cpsr_c, %0" \
: "=r" (temp) \
: \
: "memory", "cc"); \
}
#endif
看来使用的指令不一样,不过都是操作cpsr寄存器的I标志位。