1:經過上一節的分析,如果采用SECTION虛擬地址映射的話;
程序員只需要做的事情:
(1) 建立轉換表,Tanslation Table;
(2) 將TTB(轉換表基地址Tanslation Table Base)寫入協處理器CP15的C2寄存器,這里要注意轉換表
基地址為16K對齊的(因為4096*32bit=16K)所以TTB的bit0-bit13為0。
(3) 使能MMU,將CP15的C1寄存器0bit寫1;
(4) 設置域的訪問權限;設置C3寄存器;
CPU/MMU做的事情:
(1) CPU核心看到和用到的只是虛擬地址VA,至于VA如果去對應物理地址PA,CPU核心不理會,MVA是除CPU核心
外的其他部分看到的虛擬地址,VA與MVA的變化關系,如果VA<32M,需要使用進程標識號PID(通過讀CP15的C13獲得)
來轉換為MVA
if (VA < 32M) then
MVA = VA | (PID << 25)
else
MVA = VA
(2) MMU做的事情,將MVA的bit20-bit31與TTB的bit14-bit31組合,通過這個值來查找轉換表中的物理地址所在位置,
找到物理地址所在內存位置,即把所在位置的bit20-bit31與MVA的bit19-bit0,這個地址即為PA(物理地址)。
2:uboot中代碼分析
s5pv210虛擬地址物理地址映射關系為:
虛擬地址:---------------------------------------------物理地址----------------------------寫入權限
0x0000_0000--0x0FFF_FFFF 0x0000_0000--0x1000_0000 不可寫入
0x1000_0000--0x1FFF_FFFF 無效
0x2000_0000--0x5FFF_FFFF 0x2000_0000--0x5FFF_FFFF WT、WB
0x6000_0000--0x7FFF_FFFF 無效
0x8000_0000--0xaFFF_FFFF 0x8000_0000--0xAFFF_FFFF 不可寫入
0xb000_0000--0xbFFF_FFFF 0xb000_0000--0xbFFF_FFFF 不可寫入
0xc000_0000--0xcFFF_FFFF 0x2000_0000--0x2FFF_FFFF WT、WB
0xD00 - 0xC80 無效
0x1000 - 0xD00 0x1000 - 0xD00 不可寫入
#if defined(CONFIG_ENABLE_MMU)
_mmu_table_base:
.word mmu_table
#endif
#if defined(CONFIG_ENABLE_MMU)
enable_mmu:
/* enable domain access */
ldr r5, =0x0000ffff //設置域權限:設置16個域權限位可讀可寫,在寫入C3寄存器
mcr p15, 0, r5, c3, c0, 0 @load domain access register
/* Set the TTB register */
ldr r0, _mmu_table_base //把內存_mmu_table_base中的值寫入到r0中,從最上面三行代碼可以看出_mmu_table_base中的值為mmu_table
ldr r1, =CFG_PHY_UBOOT_BASE //mmu_table定義在lowlevel_init函數中,mmu_table即為在SRAM中的向量表的地址,BL1中把整個uboot的代碼
ldr r2, =0xfff00000 //復制到0x23e0_0000內存處,所以在內存中的向量表的地址為:0x23e0_0000+mmu_table的值
bic r0, r0, r2 //清mmu_table的高12bit,在位或0x23e0_0000,即把內存中的向量表的地址計算出來賦值給r1了,
orr r1, r0, r1 //然后把r1寫入到寄存器c2中,則完成了TTB的設置。
mcr p15, 0, r1, c2, c0, 0
/* Enable the MMU */
mmu_on:
mrc p15, 0, r0, c1, c0, 0 //使能mmu,c3的M位置1,即使能mmu
orr r0, r0, #1
mcr p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif
/*這段代碼的位于lowlevel_init中,作用就是建立TTB*/
.globl lowlevel_init
lowlevel_init:
#ifdef CONFIG_MCP_SINGLE
/*
* MMU Table for SMDKC110
* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed
* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF
* 0xC000_0000 -- 0xC7FF_FFFF => A:0x3000_0000 -- 0x37FF_FFFF
* 0xC800_0000 -- 0xDFFF_FFFF => Not Allowed
* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF
*/
/* 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 //開始設置MMU table base。
// Access for iRAM
.rept 0x100 //TTB中一共有4096個字節,我們假設這是一個數組 unsigned int TTB[1096]
FL_SECTION_ENTRY __base,3,0,0,0 //rept 0x100 意思是循環256次,即 TTB[0] = FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1 //TTB[1] = FL_SECTION_ENTRY __base+1,3,0,0,0 ----------最后TTB[0x100] = FL_SECTION_ENTRY __base+99,3,0,0,0
.endr //對應映射關系為:虛擬地址:0x0-0x100M----------物理地址0x0-0x100
//這段內存的讀寫權限設置在(c << 3) | (b << 2) C位WT模式直寫模式, B位WB模式,write back 先寫入cache在寫入內存
// Not Allowed
.rept 0x200 - 0x100 //0x200M-0x100M 內容為0,最低兩位為0,表示無效;
.word 0x00000000
.endr
.set __base,0x200 //TTB[0x200]-TTB[0x600 -1]對應的內容為:0x200-0x599
// should be accessed //對應映射關系為:虛擬地址:0x200-0x600M----------物理地址0x200-0x600
.rept 0x600 - 0x200 //權限位WT、WB
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
.rept 0x800 - 0x600 //同樣0x600-0x800物理地址是無效的
.word 0x00000000
.endr
.set __base,0x800 //虛擬地址:0x800-0xB00M----------物理地址0x800-0xB00
// should be accessed //不可寫入
.rept 0xb00 - 0x800
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
/* .rept 0xc00 - 0xb00
.word 0x00000000
.endr */
.set __base,0xB00 //虛擬地址:0xB00-0xC00M----------物理地址0xB00-0xC00
.rept 0xc00 - 0xb00 //不可寫入
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
// 0xC000_0000鏄犲皠鍒?x2000_0000
//.set __base,0x300
.set __base,0x200 //虛擬地址:0xC00-0xD00M----------物理地址0x200-0x300
// 256MB for SDRAM with cacheable //WT、WB
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1 //虛擬地址0xc000_0000----0xcFFF_FFFF對應的物理地址是0x2000_0000-----0x2FFF_FFFF
.set __base,__base+1
.endr
// access is not allowed.
@.rept 0xD00 - 0xC80
@.word 0x00000000
@.endr
.set __base,0xD00
// 1:1 mapping for debugging with non-cacheable
.rept 0x1000 - 0xD00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
C設置TTB代碼:
//16K對齊
#define MMU_TABLE_ADDR 0x00100000
#define TTB_VALUE_CONFIG(base, b, c, d, e)
(((base) << 20) | ((b) << 10) | ((c) << 5) | ((d) << 3) | ((e) << 2) | (1 << 1))
(ap << 10) |
(d << 5) | (1<<4) | (c << 3) | (b << 2) | (1<<1)
unsigned int *p_mmu_table = (unsigned int*)MMU_TABLE_ADDR;
void ttb_set(void)
{
int i = 0x0;
int base = 0x0;
for (i=0x0; i<0x100; i++) {
*p_mmu_table = TTB_VALUE_CONFIG(base, 3, 0, 1, 1);
p_mmu_table++;
base++; //base 0x0-0x100
}
for (; i<0x200; i++) {
*p_mmu_table = 0;
p_mmu_table++;
base++; //base 0x100-0x200
}
上一篇:s5pv210 uboot——移植DM9000網卡驅動(1)
下一篇:Linux內核啟動參數
- 熱門資源推薦
- 熱門放大器推薦
設計資源 培訓 開發板 精華推薦
- ESP8266遠程控制
- NCP1593AGEVB:3 A 同步降壓穩壓器評估板
- EVAL6230QR,L6230Q 三相無刷直流電機驅動器演示板
- 使用 Semtech 的 LM2576 的參考設計
- DC1902B,使用 LT4320IDD、32W 理想二極管橋全波整流器的演示板
- LT3479EDE 演示板,高電流升壓 LED 驅動器,Vin = 2.7V-4.5V
- BLS_MINI_SCREEN
- 使用 Microchip Technology 的 LM285BEOA-1.2 的參考設計
- SP6644UEB,SP6644 評估板,2 至 5.5V DC 至 DC 單輸出便攜式電源
- 超級電容均壓板(BW6101)已經測試