MMU相关指令学习(二)(主要是页表设置指令)

作者:wogoyixikexie@gliet

    本来打算在《MMU相关指令学习(一)(主要是页表设置指令)》搞定MMU指令问题的,但是这个实在是太长太多,太复杂了,现在就新开一文,就地解决!——刚好是第一百篇原创,值得纪念。

————————————————————————————————

Assembly code
; ——在OAL的startup.s有如下:
;
add     r0, pc, #g_oalAddressTable - (. + 8)
;
        bl      KernelStart
;
——以前真的没有仔细看过这些汇编,看过才能知道这个wince的流程到底是怎么回事。
;
这相当于一到OAL阶段就要重新初始化页表,MMU,cache使能控制等 其实是一级、二级页表都在这里设置的
;
在C:/WINCE500/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/armtrap.s有KernelStart,现在好好分析一下。
;
----------------------------------------------------------------------------------------
;
KernelStart - kernel main entry point
;
;
       The OEM layer will setup any platform or CPU specific configuration that is
;
required for the kernel to have access to ROM and DRAM and jump here to start up
;
the system. Any processor specific cache or MMU initialization should be completed.
;
The MMU and caches should not enabled.
;
;
       This routine will initialize the first-level page table based up the contents of
;
the MemoryMap array and enable the MMU and caches.
;
;
NOTE: Until the MMU is enabled, kernel symbolic addresses are not valid and must be
;
       translated via the MemoryMap array to find the correct physical address.
;
;
       Entry   (r0) = pointer to MemoryMap array in physical memory
;
       Exit    returns if MemoryMap is invalid
;
-------------------------------------------------------------------------------
        LEAF_ENTRY KernelStart
; add     r0, pc, #g_oalAddressTable - (. + 8)
        mov      r11, r0                         ; (r11) = &MemoryMap (save pointer)

       
; figure out the virtual address of OEMAddressTable
        mov      r1, r11                         ; (r1) = &MemoryMap (2nd argument to VaFromPa)
        bl      VaFromPa
       
mov      r6, r0                          ; (r6) = VA of MemoryMap

       
; convert base of PTs to Physical address
        ldr     r4, =PTs                        ; (r4) = virtual address of FirstPT
        mov      r0, r4                          ; (r0) = virtual address of FirstPT
        mov      r1, r11                         ; (r1) = &MemoryMap (2nd argument to PaFromVa)
        bl      PaFromVa

       
mov      r10, r0                         ; (r10) = ptr to FirstPT (physical)

;        Zero out page tables & kernel data page

       
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


;        Setup 2nd level page table to map the high memory area which contains the
;
first level page table, 2nd level page tables, kernel data page, etc.

       
add      r4, r10, #HighPT-PTs            ; (r4) = ptr to high page table
        orr     r0, r10, #0x051                 ; (r0) = PTE for 64K, kr/w kr/w r/o r/o page, uncached unbuffered
        str      r0, [r4, #0xD0* 4 ]               ; store the entry into 8 consecutive slots
        str      r0, [r4, #0xD1* 4 ]
       
str      r0, [r4, #0xD2* 4 ]
       
str      r0, [r4, #0xD3* 4 ]
       
add      r8, r10, #ExceptionVectors-PTs  ; (r8) = ptr to vector page
        bl      OEMARMCacheMode                 ; places C and B bit values in r0 as set by OEM
        mov      r2, r0
        orr     r0, r8, #0x002                 
; construct the PTE
        orr     r0, r0, r2
       
str      r0, [r4, #0xF0* 4 ]               ; store entry for exception vectors
        orr     r0, r0, #0x500                  ; (r0) = PTE for 4k r/o r/o kr/w kr/w C+B page
        str      r0, [r4, #0xF4* 4 ]               ; store entry for abort stack
        str      r0, [r4, #0xF6* 4 ]               ; store entry for FIQ stack  (access permissions overlap for abort and FIQ stacks, same 1k)
        orr     r0, r8, #0x042
        orr     r0, r0, r2                     
; (r0)= PTE for 4K r/o kr/w r/o r/o (C+B as set by OEM)
        str      r0, [r4, #0xF2* 4 ]               ; store entry for interrupt stack
        add      r9, r10, #KPage-PTs             ; (r9) = ptr to kdata page
        orr     r0, r9, #0x002
        orr     r0, r0, r2                     
; (r0)=PTE for 4K (C+B as set by OEM)
        orr     r0, r0, #0x250                  ; (r0) = set perms kr/w kr/w kr/w+ur/o r/o
        str      r0, [r4, #0xFC* 4 ]               ; store entry for kernel data page
        orr     r0, r4, #0x001                  ; (r0) = 1st level PTE for high memory section
        add      r1, r10, #0x4000
       
str      r0, [r1, #- 4 ]                   ; store PTE in last slot of 1st level table
  IF {FALSE}
       
mov      r0, r4
       
mov      r1, # 256                         ; dump 256 words
        CALL     WriteHex
  ENDIF

;        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

       
add      r10, r10, #0x2000               ; (r10) = ptr to 1st PTE for "unmapped space"
        mov      r7, # 2                           ; (r7) = pass counter

       
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


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

       
cmp      r4, # 0                           ; End of table?
        beq     %F29

        ldr     r5, =0x1FF00000
       
and      r2, r2, r5                      ; VA needs 512MB, 1MB aligned.

        ldr     r5, =0xFFF00000
       
and      r3, r3, r5                      ; PA needs 4GB, 1MB aligned.

       
add      r2, r10, r2, LSR # 18
       
add      r0, r0, r3                      ; (r0) = PTE for next physical page

28       str      r0, [r2], # 4
       
add      r0, r0, #0x00100000             ; (r0) = PTE for next physical page

       
sub      r4, r4, # 1                       ; Decrement number of MB left
        cmp      r4, # 0
        bne     %B28                           
; Map next MB

        bic     r0, r0, #0xF0000000            
; Clear Section Base Address Field
        bic     r0, r0, #0x0FF00000             ; Clear Section Base Address Field
        b       %B25                            ; Get next element


29
        bic     r0, r0, #0x0C                  
; clear cachable & bufferable bits in PTE
        add      r10, r10, #0x0800               ; (r10) = ptr to 1st PTE for "unmapped uncached space"
        subs    r7, r7, # 1                       ; decrement pass counter
        bne     %B20                            ; go setup PTEs for uncached space if we're not done
        sub      r10, r10, #0x3000               ; (r10) = restore address of 1st level page table
  IF {FALSE}
       
mov      r0, r10
       
mov      r1, # 4096                        ; dump 4096 words
        CALL     WriteHex
  ENDIF
———————————————————————————————————————
上面的代码已经很多注释,已经非常明了了,我就不多废话了。
 
——————————
MMU,cache,TTB设置
——————————
现在,大体的方法明白了 
——————————
一些重要的汇编宏定义

  1. MACRO
  2.         mtc15   $cpureg, $cp15reg
  3.         mcr     p15,0,$cpureg,$cp15reg,c0,0
  4.         MEND
  5.         MACRO
  6.         mfc15   $cpureg, $cp15reg
  7.         mrc     p15,0,$cpureg,$cp15reg,c0,0
  8. MEND
——————————————————————
Assembly code
    
    
    
    
; The page tables and exception vectors are setup. Initialize the MMU and turn it on. ; 页表和异常向量表建立之后,初始化MMU并打开 mov r1, # 1 mtc15 r1, c3 ; Setup access to domain 0 and clear other ; domains including 15 for PSL calls (see above) mtc15 r10, c2 ; ;mtc15 是宏定义 把TTB(L1转换基地址放到C2) mov r0, # 0 mcr p15, 0 , r0, c8, c7, 0 ; Flush the I&D TLBs mfc15 r1, c1 ; mfc15 宏定义 读出C1的值到r1 orr r1, r1, #0x007F ; changed to read-mod-write for ARM920 Enable: MMU, Align, DCache, WriteBuffer orr r1, r1, #0x3200 ; vector adjust, ICache, ROM protection ldr r0, VirtualStart ; 这个很关键在代码中有 VirtualStart DCD VStart cmp r0, # 0 ; make sure no stall on "mov pc,r0" below mtc15 r1, c1 ; enable the MMU & Caches mov pc, r0 ; & jump to new virtual address 跳到VStart运行 nop



总结:填写好二级页表,把二级页表的首地址存放到一级页表的表项最后最后;根据OEMAddresstable初始化L1页表;把L1的转换表的基地址放到协处理器的c1的寄存器。启动MMU等功能即可。
——现在基本没有什么疑问了,完成博客,今天晚上回去结贴。——目前对于一些domain、AP的设置等还是不是很明白。不过都是一个样,看看数据手册即可。阿门!大功告成。
如果还有疑问,请看CSDN论坛帖子: http://topic.csdn.net/u/20081231/10/bbde79c2-2884-48e3-9718-90d7fcc1afa8.html?seed=1947589160
这个讲的较详细。哈哈,最难的都理解了。我对ARM越来越有信心。
http://www.cnblogs.com/we-hjb/archive/2008/10/12/1309596.html 
——这篇博客也讲得比较好,值得参考。
转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协,原文地址:http://blog.csdn.net/gooogleman——如有错误,希望能够留言指出;如果你有更加好的方法,也请在博客后面留言,我会感激你的批评和分享。

 

你可能感兴趣的:(exception,assembly,table,Access,permissions,initialization)