(转)Wince读核1-启动流程3

  ;       Zero out page tables & kernel data page
     ;初始化上面分配的物理内存KDataArea
    
            mov     r0, #0                          ; (r0-r3) = 0's to store
            mov     r1, #0
            mov     r2, #0
            mov     r3, #0
            mov     r4, r10                         ; (r4) = first address to clear
            add     r5, r10, #KDEnd-PTs             ; (r5) = last address + 1
     18      stmia   r4!, {r0-r3}
            stmia   r4!, {r0-r3}
            cmp     r4, r5
            blo     %B18
下面的代码是为在使能mmu前初始化内存映射表page table。前面说过ce目前的arm实现不仅利用了cpu的mmu功能,还使用了两种mmu映射方式:最高的1MB(0xFFF00000-0xFFFFFFFF),使用二级映射,并使用不同的page类型;而其余地址空间,只使用一级映射。所以内存映射表的初始化也分为两步。这两步没有什么先后顺序,ce是先初始化二级映射,为了叙述方便这里先解释一级映射。注意这里的一级映射意思是虚拟地址只通过一次内存映射表的转换就能映射到对应的物理地址,而不是二级映射中的第一级映射的意思。如果是后者,将使用“第一级映射”加以区分。
另外有必要首先对一级映射加以解释。参考一级映射的示意图,Translation table base保存一级映射的内存映射表的物理地址,在这里也就是PTs,这个地址是16k对齐的,保存在CP15的寄存器c2中。给定一个虚拟地址vaddr,右移20bit后再左移2bit,作为内存映射表pt的索引(之所以要再左移2bit,是因为PTs保存一个地址需要4个byte),此时pt+(vaddr>>20)<<2就是该虚拟地址对应的一级映射描述符的物理地址,而pt[(vaddr>>20)<<2]就是该虚拟地址对应的一级映射描述符,最后vaddr对应的物理地址就是pt[(vaddr>>20)<<2]&0xfff00000+vaddr&0x000fffff。由此可见这种映射方式,一个描述符对应1M的物理空间。而pt[(vaddr>>20)<<2]的值,也就是一级映射描述符,是在下面初始化的。
    ;       Fill in first level page table entries to create "un-mapped" regions
     ; from the contents of the MemoryMap array.
     ;
     ;       (r9) = ptr to KData page
     ;       (r10) = ptr to 1st level page table
     ;       (r11) = ptr to MemoryMap array
     ;内核只初始化高2g的内核空间,低2g的用户空间的内存是在用户空间的程序运行时分配的,这里不必初始化。
     ;r10之前保存了PTs的物理地址,也就是一级映射的内存映射表的物理地址,要跳过(2g/1M)*4=0x2000,才能指向内核空间的起始地址0x80000000。
            add     r10, r10, #0x2000               ; (r10) = ptr to 1st PTE for "unmapped space"
     ;高2g空间又分为两部分,分别是0x80000000-0x9fffffff的cached和writebuffer空间(C+B),和0xa00000000-0xbfffffff的非cached和writebuffer空间(非C+B)。
     ;这两部分指向同一个物理空间,之所以要分成两个虚拟空间是系统需要。C+B空间用来进行高速的存储设备的访问,
     ;一般这种情况下不需要实时更新或读取具体的物理存储设备,所以高速的CPU不必等待具体的物理储存设备数据的更新或读取,
     ;而是采用writebuffer在其后写入,或读取以前保存在cache的数据。
     ;而非C+B用来访问物理寄存器或需要实时反应的设备,一般的寄存器访问都需要这种方式。
     ;所以ce为了区分这两种情况,采用了两个独立的虚拟内存空间的方法,需要分别初始化内存映射表。
     ;r7保存这个初始化的次数。首先初始化C+B空间的内存映射表。
            mov     r7, #2                          ; (r7) = pass counter
    
     ;下面是构造一个一级映射描述符。参考一级映射示意图,对于一级映射要求描述符最后两个bit是二进制10,所以r0=0x02;
     ;r2之前被赋值为0x0c,即二进制1100,,意味着C和B被置位;
     ;参考文档2,0x400意味着通过该描述符访问对应的1M物理内存时,内核有读写权限,用户无访问权限;
     ;注意,这并不是意味着该内存地址用户是无法访问的,因为内核可以把该物理地址映射其它的用户可访问的虚拟地址。
            mov     r0, #0x02
            orr     r0, r0, r2                      ; (r0)=PTE for 0: 1MB (C+B as set by OEM)
            orr     r0, r0, #0x400                  ; set kernel r/w permission
     20      mov     r1, r11                         ; (r1) = ptr to MemoryMap array
    
     ;r2,r3和r4分别保存g_oalAddressTable某一项的虚拟地址,物理地址和映射的大小(M)。
     ;例如,对应上面的g_oalAddressTable,r2=0x80000000, r3=0xA0000000, r4=64。
     25      ldr     r2, [r1], #4                    ; (r2) = virtual address to map Bank at
            ldr     r3, [r1], #4                    ; (r3) = physical address to map from
            ldr     r4, [r1], #4                    ; (r4) = num MB to map
           
     ;最后一项全为0,由此可知是否遍历了该数组。
            cmp     r4, #0                          ; End of table?
            beq     %F29

http://hi.baidu.com/garnetttt/blog/item/7860349b7bfcccb6c8eaf47b.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值