(轉)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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章