1.6
OEMAddresstable只是用来初始化一级页表,就是所谓的段(section)描述,每个段是1MB,分为4096个段,总共4G——虚拟内存空间4G就是由此而来。
并且这个OEMAddresstable可以用在查表法中用来转换虚拟地址、物理地址(相互转换都可以)。
PTs(pointer to section)的相关定义如下:
; Define RAM space for the Page Tables:
;
PHYBASE EQU 0x30000000 ; physical start
PTs EQU 0x30010000 ; 1st level page table address (PHYBASE + 0x10000)
PTs保存在物理内存中的地址是0x30010000 ,上图的301行的0x2000是什么意义呢?我们知道没有缓存的虚拟地址起始地址是0x80000000,那这个虚拟地址对应的物理地址是多少呢?根据VA映射到PA的规则,见下图:
从0x80000000中取出[31:20]位,也即0x800来左移2位之后(0x2000,这个就是上面这个值的来由)加上translation base(在这里是PTs),也即上图add r10, r10, #0x2000这行语句的意义,执行这行语句之后r0=0x30012000,这就是计算了4G虚拟地址空间中从0x80000000地址开始的虚拟地址对应的物理起始地址是0x30012000,也就是section base address=0x30012000。
PTE:pointer to enter
接下来
我们知道r1指向g_oalAddressTable,假如g_oalAddressTable的定义如下:
g_oalAddressTable
[ {TRUE}
DCD 0x80000000, 0x30000000, 128 ; 128 MB DRAM BANK 6
…………………………
DCD 0x00000000, 0x00000000, 0 ; end of table
]
那么上面语句的307到309行就是实现 (r2)=0x80000000,(r3=0x30000000)和(r4=128)这些功能,而311行就是用于判断在建立一级页表是否完成,如果完成,也即cacheable地址0x80000000~0xa0000000这段虚拟内存映射的物理内存创建完毕,就跳到下面标号为40的地方开始执行;如果没有完成,会接下来执行。
ldr r5, =0x1FF00000
and r2, r2, r5 ; VA needs 512MB, 1MB aligned.
因为是对0x80000000~0xa0000000这段虚拟内存映射(512MB),并且是要求1MB对齐的,所以需要用0x1FF00000来保证。
ldr r5, =0xFFF00000
and r3, r3, r5 ; PA needs 4GB, 1MB aligned.
对PA物理地址进行4G对齐。
add r2, r10, r2, LSR #18
add r0, r0, r3 ; (r0) = PTE for next physical page
获取下一个物理页的入口地址。
35 str r0, [r2], #4
add r0, r0, #0x00100000 ; (r0) = PTE for next physical page
1M递增,因为1<<18=256K,而每一个pte描述4k页,所以最终描述256k*4k=1M地址空间
sub r4, r4, #1 ; Decrement number of MB left
cmp r4, #0
bne %b35 ; Map next MB
遍历到该region结束
bic r0, r0, #0xF0000000 ; Clear Section Base Address Field
bic r0, r0, #0x0FF00000 ; Clear Section Base Address Field
清空r0中的地址信息
b %b30 ; Get next element
继续创建oemaddrtab_cfg.inc描述的下一region
40 tst r0, #8
bic r0, r0, #0x0C ; clear cachable & bufferable bits in PTE
add r10, r10, #0x0800 ; (r10) = ptr to 1st PTE for "unmapped uncached space"
bne %b25 ; go setup PTEs for uncached space
sub r10, r10, #0x3000 ; (r10) = restore address of 1st level page table
; 1. Setup mmu to map (VA == 0) to (PA == 0x30000000).
; 1-1. cached area.
ldr r0, =PTs ; PTE entry for VA = 0
ldr r1, =0x3000040E ; cache/buffer/rw, PA base == 0x30000000
;ldr r1, =0x30000402 ; cache/buffer/rw, PA base == 0x30000000
str r1, [r0]
; 1-2. uncached area.
add r0, r0, #0x0800 ; PTE entry for VA = 0x0200.0000 , uncached
ldr r1, =0x30000402 ; uncache/unbuffer/rw, base == 0x30000000
str r1, [r0]
; Comment:
; The following loop is to direct map RAM VA == PA. i.e.
; VA == 0x30XXXXXX => PA == 0x30XXXXXX for S3C2400
; Fill in 8 entries to have a direct mapping for DRAM
;
ldr r10, =PTs ; restore address of 1st level page table
ldr r0, =PHYBASE
add r10, r10, #(0x3000 / 4) ; (r10) = ptr to 1st PTE for 0x30000000
add r0, r0, #0x1E ; 1MB cachable bufferable
orr r0, r0, #0x400 ; set kernel r/w permission
mov r1, #0
mov r3, #64
45 mov r2, r1 ; (r2) = virtual address to map Bank at
cmp r2, #0x20000000:SHR:BANK_SHIFT
add r2, r10, r2, LSL #BANK_SHIFT-18
strlo r0, [r2]
add r0, r0, #0x00100000 ; (r0) = PTE for next physical page
subs r3, r3, #1
add r1, r1, #1
bgt %b45
ldr r10, =PTs ; (r10) = restore address of 1st level page table
一级页表的映射关系建立完成之后,要把一级页表的基地址保存会r10中。
; The page tables and exception vectors are setup.
; Initialize the MMU and turn it on.
mov r1, #1
mcr p15, 0, r1, c3, c0, 0 ; setup access to domain 0
mcr p15, 0, r10, c2, c0, 0
mcr p15, 0, r0, c8, c7, 0 ; flush I+D TLBs
mrc p15,0,r1,c1,c0,0
orr r1, r1, #0x0071 ; Enable: MMU
orr r1, r1, #0x0004 ; Enable the cache
ldr r0, =VirtualStart
cmp r0, #0 ; make sure no stall on "mov pc,r0" below
mcr p15, 0, r1, c1, c0, 0
mov pc, r0 ; & jump to new virtual address
nop
; MMU & caches now enabled.
; (r10) = physcial address of 1st level page table
;
VirtualStart
mov sp, #0x80000000 ; have to be modefied. refer oemaddrtab_cfg.inc, DonGo
add sp, sp, #0x30000 ; arbitrary initial super-page stack pointer
注意0x80000000+0x30000=0x80030000,不能超过eboot/boot.bib中下面
MEMORY
; Name Start Size Type
; ------- -------- -------- ----
ARGS 80020800 00000800 RESERVED
RAM 80021000 0000B000 RAM
STACK 8002c000 0000A000 RESERVED
EBOOT 80038000 00040000 RAMIMAGE
BINFS 80080000 00021000 RESERVED
对stack中指定的值,也即0x8002c000+0x0000A000=0x80036000,其对应的物理地址是0x30036000,也即0x80000000+0x30000的值要在0x3002c000~0x30036000之间。
b main
到这里就跳转到eboot的main函数了。
ENTRY_END