在阅读了有关ARM linux内核启动过程的代码几天之后,除了函数__turn_mmu_on:
中的几个棘手部分之外,我理解了其中的大多数部分
.align 5
__turn_mmu_on:
mov r0, r0
mcr p15, 0, r0, c1, c0, 0 @ write control reg
mrc p15, 0, r3, c0, c0, 0 @ read id reg
mov r3, r3
mov r3, r3
mov pc, r13
ENDPROC(__turn_mmu_on)
最后一条指令mov pc, r13
将转移到__mmap_switched
,如下所示:
__mmap_switched:
adr r3, __switch_data + 4
....
r3
中覆盖寄存器adr r3, __switch_data + 4
?答案 0 :(得分:3)
对齐可能不是必需的,但可能用于确保整个函数适合缓存行,因此最后几条指令将从缓存中执行,而不必是从内存中取出(即使函数 仍然在MMU上的同一地址,因为它的身份映射)。
要追踪MRC
指令的来源并不容易,但我认为我是found it:
Date: 2004-04-04 04:35 +200
To: linux-arm-patches
Subject: [Linux-arm-patches] 1204.1: XSCALE processor stalls when enabling MMU
--- kernel-source-2.5.21-rmk/arch/arm/kernel/head.S Sun Jun 9 07:26:29 2002
+++ kernel-2.5.21-was/arch/arm/kernel/head.S Fri Jul 12 20:41:42 2002
@@ -118,9 +118,7 @@ __turn_mmu_on:
orr r0, r0, #2 @ ...........A.
#endif
mcr p15, 0, r0, c1, c0
- mov r0, r0
- mov r0, r0
- mov r0, r0
+ cpwait r10
mov pc, lr
[...]
+/*
+ * cpwait - wait for coprocessor operation to finish
+ * this is the canonical way to wait for cp updates
+ * on PXA2x0 as proposed by Intel
+ */
+ .macro cpwait reg
+ mrc p15, 0, \reg, c2, c0, 0 @ arbitrary cp reg read
+ mov r0, r0 @ nop
+ sub pc, pc, #4 @ nop
+ .endm
随后讨论这个补丁的优点ended in the current approach:
...
然而,我们可以更接近Xscale推荐的序列 知道事情如何在其他CPU上工作,并知道我们正在做什么 这里。如果我们在mcr之后插入以下指令,那么这个 应该解决你的问题。mrc p15, 0, r0, c1, c0
由于ARM对保证同一寄存器的回读 体系结构手册返回那里写的值(如果它 不是,CPU不是ARM兼容的实现),这意味着我们 可以保证对寄存器的写入生效。使用 “mov r0,r0”指令的含义与CPWAIT宏中的相同。 mov pc,lr相当于“sub pc,pc,#4”(它们是定义的 是指令的 class ,所以只添加一个 指示应保证Xscale按预期工作 ...
最初的补丁来自Lothar Wassmann,最终的代码可能是Russel King。