Linux启动流程导读(arm为例)(3)

/*
  * Setup common bits before finally enabling the MMU.  Essentially
  * this is just loading the page table pointer and domain access
  * registers.
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags or dtb pointer
  *  r4  = page table pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
 #if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
     orr    r0, r0, #CR_A
 #else
     bic    r0, r0, #CR_A
 #endif
 #ifdef CONFIG_CPU_DCACHE_DISABLE
     bic    r0, r0, #CR_C
 #endif
 #ifdef CONFIG_CPU_BPREDICT_DISABLE
     bic    r0, r0, #CR_Z
 #endif
 #ifdef CONFIG_CPU_ICACHE_DISABLE
     bic    r0, r0, #CR_I
 #endif
     mov    r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
               domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
               domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
               domain_val(DOMAIN_IO, DOMAIN_CLIENT))
     mcr    p15, 0, r5, c3, c0, 0        @ load domain access register
     mcr    p15, 0, r4, c2, c0, 0        @ load page table pointer
     b    __turn_mmu_on
 ENDPROC(__enable_mmu)

==========

/*
  * Enable the MMU.  This completely changes the structure of the visible
  * memory space.  You will not be able to trace execution through this.
  * If you have an enquiry about this, *please* check the linux-arm-kernel
  * mailing list archives BEFORE sending another post to the list.
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags or dtb pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  *
  * other registers depend on the function called upon completion
  */
     .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, r13      //跳回r13,=__mmap_switched
     mov    pc, r3
 __enable_mmu_end:
 ENDPROC(__turn_mmu_on)

==========

#arch/arm/kernel/head-common.s

/*
  * The following fragment of code is executed with the MMU on in MMU mode,
  * and uses absolute addresses; this is not position independent.
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags/dtb pointer
  *  r9  = processor ID
  */
     __INIT
 __mmap_switched:
     adr    r3, __mmap_switched_data
 
     ldmia    r3!, {r4, r5, r6, r7}
     cmp    r4, r5                @ Copy data segment if needed
 1:    cmpne    r5, r6
     ldrne    fp, [r4], #4
     strne    fp, [r5], #4
     bne    1b
 
     mov    fp, #0                @ Clear BSS (and zero fp)
 1:    cmp    r6, r7
     strcc    fp, [r6],#4
     bcc    1b
 
  ARM(    ldmia    r3, {r4, r5, r6, r7, sp})
  THUMB(    ldmia    r3, {r4, r5, r6, r7}    )
  THUMB(    ldr    sp, [r3, #16]        )
     str    r9, [r4]            @ Save processor ID
     str    r1, [r5]            @ Save machine type
     str    r2, [r6]            @ Save atags pointer
     bic    r4, r0, #CR_A            @ Clear 'A' bit
     stmia    r7, {r0, r4}            @ Save control register values
     b    start_kernel
 ENDPROC(__mmap_switched)

===========


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/22665.html