我有一个简单的裸机Raspberry Pi项目,我在其中尝试实现自旋锁。这是我的代码:
spinlock_lock:
push {r4, r5, lr}
mov r5, #0x1
1:
ldrex r4, [r0]
teq r4, #0
strexeq r4, r5, [r0]
teqeq r4, #0
bne 1b
pop {r4, r5, pc}
问题是
ldrex
导致数据中止。我传递的指针是页面对齐的,并且ARM在系统模式下运行。奇怪的是,将代码替换为使用非排他性加载/存储的版本即可。使用独家加载和存储时,我需要记住什么? 最佳答案
[为了清楚起见,忽略非MMU架构]
排他访问指令仅保证可在普通内存上使用。在ARMv7-A中,实现定义了它们将在强序内存还是在设备内存上工作-除非系统文档明确声明支持,否则将无法预测强序内存或设备内存的排他性。适用于此的ARMv6更加严格:
LDREX和STREX操作只能在支持“普通”内存属性的内存上执行。
当MMU关闭时,指令访问被视为普通访问,而数据访问被视为强顺序访问。因此,尝试在MMU关闭的情况下使用排他性很可能会失败-为了使用它们,我认为除了为正确的属性设置身份映射设置一些最小页面表外,别无选择。