Linux kernel 为什么在打开mmu时读取id寄存器?

Linux kernel 为什么在打开mmu时读取id寄存器?,linux-kernel,arm,Linux Kernel,Arm,在阅读了几天有关ARM linux内核引导过程的代码后,我了解了其中的大部分,除了函数中的几个棘手部分:\uuu打开mmu: .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

在阅读了几天有关ARM linux内核引导过程的代码后,我了解了其中的大部分,除了函数中的几个棘手部分:\uuu打开mmu:

        .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
将分支到
\uu mmap\u switched
,如下所示:

    __mmap_switched:
        adr r3, __switch_data + 4
        ....
  • 为什么需要在32字节(缓存线的大小)边界对齐它
  • 由于寄存器
    r3
    在指令
    adr r3、\uu开关\u数据+4
    中被简单覆盖,读取ID寄存器的值(其值甚至未被使用)的目的是什么
对齐可能不是必需的,但可能用于确保整个函数适合缓存线,因此最后几条指令将从缓存中执行,而不必从内存中提取(即使函数应保持在启用MMU的同一地址,因为它的标识已映射)

追踪
MRC
指令的起源并不容易,但我认为我:

接下来将讨论此修补程序的优点:


但是,我们可以通过 了解其他CPU上的工作方式,了解我们正在做什么 在这里如果我们在mcr后插入以下指令,则 应该能解决你的问题

mrc p15, 0, r0, c1, c0
因为同一寄存器的读回是由ARM保证的 架构手册,以返回写入其中的值(如果 不,CPU不是ARM兼容的实现),这意味着我们 可以保证对寄存器的写入已生效。用途 “mov r0,r0”指令的类型与CPWAIT宏中的相同。 mov pc,lr相当于“子pc,pc,#4”(定义如下 是同一类指令),因此只需添加一个 说明应保证Xscale按预期工作。


原始补丁来自Lothar Wassmann,最终代码可能是Russel King编写的。

谢谢,链接为+1:-)
mrc p15, 0, r0, c1, c0