uboot MMU
这里主要介绍的是ARM芯片。
整个Flow如下:
1 设置域的权限 mcr p15, 0, r5, c3, c0, 0
2 设置TTB register, mcr p15, 0, r1, c2, c0,
将mmu table的地址赋值给r1。
有时候这里需要你提前设置TTB的control register。mcr p15, 0, r0, c2, c0, 2
3 enable MMU
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x1
mcr p15, 0, r0, c1, c0, 0
4 enable i/d cache
Do not forgget this step.
参考samsung 6400代码:
enable_mmu: /* enable domain access */ ldr r5, =0x0000ffff mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ /* Set the TTB register */ ldr r0, _mmu_table_base ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE ldr r2, =0xfff00000 bic r0, r0, r2 orr r1, r0, r1 mcr p15, 0, r1, c2, c0, 0 /* Enable the MMU */ mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #1 /* Set CR_M to enable MMU */ /* Prepare to enable the MMU */ adr r1, skip_hw_init and r1, r1, #0x3fc ldr r2, _TEXT_BASE ldr r3, =0xfff00000 and r2, r2, r3 orr r2, r2, r1 b mmu_enable .align 5 /* Run in a single cache-line */ mmu_enable: mcr p15, 0, r0, c1, c0, 0 nop nop mov pc, r2 skip_hw_init: #endif
下面是ARM一个官网的文档参考:
@ Initialize MMU MOV r1,#0x0 MCR p15, 0, r1, c2, c0, 2 @ Write Translation Table Base Control Register LDR r1, ttb_address MCR p15, 0, r1, c2, c0, 0 @ Write Translation Table Base Register 0 @ In this simple example, we don't use TRE or Normal Memory Remap Register. @ Set all Domains to Client LDR r1, =0x55555555 MCR p15, 0, r1, c3, c0, 0 @ Write Domain Access Control Register @ Enable MMU MRC p15, 0, r1, c1, c0, 0 @ Read Control Register configuration data ORR r1, r1, #0x1 @ Bit 0 is the MMU enable MCR p15, 0, r1, c1, c0, 0 @ Write Control Register configuration data
MMU table的设置 :
可参考:
#ifdef CONFIG_ENABLE_MMU /* * MMU Table for SMDK6400 */ /* form a first-level section entry */ .macro FL_SECTION_ENTRY base,ap,d,c,b .word (\base << 20) | (\ap << 10) | \ (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1) .endm .section .mmudata, "a" .align 14 /* the following alignment creates the mmu table at address 0x4000. */ .globl mmu_table mmu_table: .set __base, 0 /* 1:1 mapping for debugging */ .rept 0xA00 FL_SECTION_ENTRY __base, 3, 0, 0, 0 .set __base, __base + 1 .endr /* access is not allowed. */ .rept 0xC00 - 0xA00 .word 0x00000000 .endr /* 128MB for SDRAM 0xC0000000 -> 0x50000000 */ .set __base, 0x500 .rept 0xC80 - 0xC00 FL_SECTION_ENTRY __base, 3, 0, 1, 1 .set __base, __base + 1 .endr /* access is not allowed. */ .rept 0x1000 - 0xc80 .word 0x00000000 .endr #endif
一般在不同的平台上需要做的修改如下:
1) 修改FL_SECTION_ENTRY 的定义
2) 根据不同的mapping做相应的调整
调试注意事项:
1 注意control register的设置
2 mmu table不要在bss段范围内