免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3597 | 回复: 2
打印 上一主题 下一主题

__turn_mmu_on疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-07 15:57 |只看该作者 |倒序浏览
在阅读arch/arm/kernel/head.S/head-common.s的反汇编代码时.  对_turn_mmu_on部分始终搞不明白. 请大侠指点一下. 感激不尽.


分析所得, 从__create_page_tables返回之后, r0 = 0x30007000.
在__enable_mmu的时候, 也只是或了个2, 也就是置了Abit,  然后跳到下面
__turn_mmu_on, 这里r0 = 0x30007002,  然后写cr1,  网上说这个位置就mmu enable了,  怎么理解呢.  cp15 cr1的Mbit没见在哪置了1啊.
源代码里面的几个宏似乎也与Mbit无关. 怎么回事呢?

__enable_mmu:
#ifdef CONFIG_ALIGNMENT_TRAP
        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)


板子是mini2440的.

/**

        Image的入口, 起始地址是0x30008000
*/

00000000 <stext>:
   0:   e321f0d3        msr     CPSR_c, #211            /**写CPSR, 0xd3, 1101 0011, mode = 10011, supervisor模式. */
   4:   ee109f10        mrc     15, 0, r9, cr0, cr0, {0}        /**返回设备号.*/
   8:   eb000056        bl      168 <__lookup_processor_type>   /**直接跳转到下面查询处理器类型.*/
   c:   e1b0a005        movs    sl, r5  /**如果异常返回0, 也就是eq置位, 跳转到__error.*/
  10:   0a000052        beq     160 <__error>
  14:   eb00006c        bl      1cc <__lookup_machine_type>     /**查询机器类型.*/
  18:   e1b08005        movs    r8, r5
  1c:   0a00004f        beq     160 <__error>
  20:   eb00007b        bl      214 <__vet_atags>               /**检查atags.*/
  24:   eb000013        bl      78 <__create_page_tables>       /**创建页表.*/
  28:   e59fd0c0        ldr     sp, [pc, #192]  /**栈指针=__mmap_switched*/
  2c:   e28fe000        add     lr, pc, #0      /**返回地址是下面的__enable_mmu*/
  30:   e28af010        add     pc, sl, #16     /**跳到__lookup_machine_type, 又回来跳到__enable_mmu?*/




00000034 <__enable_mmu>:
  34:   e3800002        orr     r0, r0, #2      /**从__create_page_tables返回时, r0 = 0x30007000, 或, r0 = 0x30007002.*/
  38:   e3a0501f        mov     r5, #31         /**r5 = 0x1F.*/
  3c:   ee035f10        mcr     15, 0, r5, cr3, cr0, {0}        /**将r5写入cp15-r3寄存器, enable域访问控制.*/
  40:   ee024f10        mcr     15, 0, r4, cr2, cr0, {0}        /**r4 = 0x30004000, 写入页表基址.*/
  44:   ea000005        b       60 <__turn_mmu_on>              /**跳到下面使能mmu?*/
  48:   e1a00000        nop                     ; (mov r0, r0)
  4c:   e1a00000        nop                     ; (mov r0, r0)
  50:   e1a00000        nop                     ; (mov r0, r0)
  54:   e1a00000        nop                     ; (mov r0, r0)
  58:   e1a00000        nop                     ; (mov r0, r0)
  5c:   e1a00000        nop                     ; (mov r0, r0)

00000060 <__turn_mmu_on>:
  60:   e1a00000        nop                     ; (mov r0, r0)
  64:   ee010f10        mcr     15, 0, r0, cr1, cr0, {0}        /**r0这里等于0x30007002, control register*/
  68:   ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
  6c:   e1a03003        mov     r3, r3
  70:   e1a0300d        mov     r3, sp
  74:   e1a0f003        mov     pc, r3



00000078 <__create_page_tables>:
  78:   e59f4068        ldr     r4, [pc, #104]  /**指向下面e8的位置, r4 = 0x30004000, 也就是物理地址偏移16K的位置.*/
  7c:   e1a00004        mov     r0, r4          /**r0 = r4*/
  80:   e3a03000        mov     r3, #0          /**r3清零.*/
  84:   e2806901        add     r6, r0, #16384  /**r6 = 0x30008000*/

  88:   e4803004        str     r3, [r0], #4    /**清空0x30004000.*/
  8c:   e4803004        str     r3, [r0], #4    /**清空0x30004004.*/
  90:   e4803004        str     r3, [r0], #4    /**清空0x30004008.*/
  94:   e4803004        str     r3, [r0], #4    /**清空0x3000400C.*/
  98:   e1300006        teq     r0, r6          /**循环, 全部清空, 至到0x30008000*/
  9c:   1afffff9        bne     88 <__create_page_tables+0x10>

  a0:   e59a7008        ldr     r7, [sl, #8]    /**此时的sl为__lookup_processor_type返回r5的值, 也就是下面1b8这个位置.
                                                        结果r7= .text.head*/
  a4:   e1a0600f        mov     r6, pc          /**r6 = 下面的ac:, 0x300080AC*/
  a8:   e1a06a26        lsr     r6, r6, #20     /**右移20位, r6 = 0x300. */
  ac:   e1873a06        orr     r3, r7, r6, lsl #20     /**将r6的值向左移20位, 再与r7或, 结果保存在r3中. 也就是0x30000000和
                                                        .text.head(0xC0000000 + 0x00008000)或, 结果是r3 = 0xF0008000*/
  b0:   e7843106        str     r3, [r4, r6, lsl #2]    /**r6再左移两位, 表达式变成str r3, [r4, 0], 也就将0xF0008000写入0x30004000中.*/
  b4:   e2840a03        add     r0, r4, #12288          /**r0 = 0x30004000 + 0x3000 = 0x30007000*/
  b8:   e5a03000        str     r3, [r0]!               /**将0xF0008000写入0x30007000地址, r0自增4.*/
  bc:   e59f6028        ldr     r6, [pc, #40]           /**r6 = 0xFFFFFFFF*/
  c0:   e2800004        add     r0, r0, #4              /**r0 +=4, r0 = 0x30007008*/
  c4:   e0846926        add     r6, r4, r6, lsr #18     /**将r6, 右移18位, 等于0x00003FFF, 再加等于r4(0x30004000), 结果r6 = 0x30007FFF.*/

  c8:   e1500006        cmp     r0, r6                  /**下面会跳上来.*/
  cc:   e2833601        add     r3, r3, #1048576        /**r3 = 0xF0008000 + 0x10000 = 0xF0108000, 也就是1M.*/
  d0:   94803004        strls   r3, [r0], #4            /**如果r3 <= r0, 则写入, 也就是将0xF0108000+=1M写入0x30007008~0x30007FFF.*/
  d4:   9afffffb        bls     c8 <__create_page_tables+0x50>


  d8:   e2840a03        add     r0, r4, #12288          /**r0 = 0x30007000*/
  dc:   e3876203        orr     r6, r7, #805306368      /**r7 = .text.head = 0xC0008000, r6 = r7|0x30000000 = 0xF0008000*/
  e0:   e5806000        str     r6, [r0]                /**又将0xF0008000写入0x30007000?, 0x30007004没写?*/
  e4:   e1a0f00e        mov     pc, lr                  /**函数返回.*/
  e8:   30004000        andcc   r4, r0, r0
  ec:   ffffffff        undefined instruction 0xffffffff
                        ec: R_ARM_ABS32 _end

000000f0 <__switch_data>:
        ...
                        f0: R_ARM_ABS32 __mmap_switched
                        f4: R_ARM_ABS32 __data_loc
                        f8: R_ARM_ABS32 _data
                        fc: R_ARM_ABS32 __bss_start
                        100: R_ARM_ABS32        _end
                        104: R_ARM_ABS32        processor_id
                        108: R_ARM_ABS32        __machine_arch_type
                        10c: R_ARM_ABS32        __atags_pointer
                        110: R_ARM_ABS32        cr_alignment
114:   00001ff8        strdeq  r1, [r0], -r8
                        114: R_ARM_ABS32        init_thread_union

论坛徽章:
0
2 [报告]
发表于 2011-11-09 09:28 |只看该作者
呼唤高手.

论坛徽章:
0
3 [报告]
发表于 2014-08-25 20:33 |只看该作者
是在__v6_setup中设置的,有一段代码如下:
adr r5,v6_crval @将v6_crval的实际运行地址加载到r5处
ldmia r5,{r5,r6}@将r5地址处的两个字内容保存到r5和r6处,根据v6_crval定义可知,值为clear和mmuset,mmmuset的最后一个比特值为1,也就是CR_M=1
orr r0,r0,r6        @在此处将设置r0的bit0为1。随后在__turn_mmu_on中将MMU的值写入CP15的C1寄存器,真正使能MMU。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP