參考:https://www.cnblogs.com/yangjiguang/p/7647801.html
一、映射過程詳解
關(guān)于頁表:ARMv6的MMU進(jìn)行地址映射時(shí)涉及到兩種頁表,一級(jí)頁表(first level page table)和二級(jí)頁表(coarse page table)。
關(guān)于映射方式:映射方式有兩種,段映射和頁映射。段映射只用到一級(jí)頁表,頁映射用到一級(jí)頁表和二級(jí)頁表。
關(guān)于映射粒度:段映射的映射粒度有兩種,1M section和16M supersection;頁映射的映射粒度也有兩種,4K small page和64K large page。
硬件在做地址轉(zhuǎn)換時(shí),如何知道當(dāng)前是什么映射方式以及映射粒度是多少呢?
這些信息可以從頁表的入口描述符中獲得。
一級(jí)頁表的入口描述符(first-level descriptor)格式如下:
第[1:0]位決定映射方式:
[1:0]=10b時(shí),是段映射,此時(shí)只需作一級(jí)映射,描述符的最高12或8位存放的是段基址;
[1:0]=01b時(shí),是頁映射,此時(shí)虛擬地址轉(zhuǎn)換為物理地址需要經(jīng)歷二級(jí)映射,描述符的最高22位存放的是二級(jí)頁表的物理地址;
第[18]位決定段映射的粒度:
[18]=0b時(shí),映射粒度為1M,描述符的最高12位存放段基址;
[18]=1b時(shí),映射粒度為16M,描述符的最高8位存放段基址;
當(dāng)映射方式為頁映射時(shí),我們用到二級(jí)頁表,二級(jí)頁表的入口描述符(second-level descriptor)格式如下:
第[1:0]位決定頁映射的映射粒度:
[1:0]=10b或11b時(shí),映射粒度為4KB,描述符的最高20位為頁基址;
[1:0]=01b時(shí),映射粒度為64KB,描述符的最高16位為頁基址;
下面分4種情況對(duì)地址映射過程做詳細(xì)描述:
1)段映射,映射粒度為1M
2)段映射,映射粒度為16M
3)頁映射,映射粒度為4K
4)頁映射,映射粒度為64K
1.1段映射,映射粒度為1M
當(dāng)映射方式為段映射,且映射粒度為1M時(shí),映射圖如下:
虛擬地址到物理地址的映射過程如下:
虛擬地址的[31:20]位存放一級(jí)頁表的入口index,[19:0]位存放段偏移;
從TTBR(translation table base register,協(xié)處理器CP15中的一個(gè)寄存器,用于存放一級(jí)頁表的基址)寄存器中獲取一級(jí)頁表的基址;
一級(jí)頁表基址+ VA[31:20] = 該虛擬地址對(duì)應(yīng)的頁表描述符的入口地址;
頁表描述符的[31:20]位為該虛擬地址對(duì)應(yīng)的物理段基址;
物理段基址+ VA[19:0]段偏移= 物理地址
由映射圖可知,一個(gè)虛擬地址可以索引2^12個(gè)一級(jí)頁表入口,每個(gè)入口映射2^20大小的內(nèi)存,故虛擬地址可以映射的最大物理內(nèi)存為:2^12 * 2^20,即4G。
1.2 段映射,映射粒度為16M
當(dāng)映射方式為段映射,且映射粒度為16M時(shí),映射圖如下:
虛擬地址到物理地址的映射過程如下:
虛擬地址的[31:24]位存放一級(jí)頁表的入口index,[23:0]位存放段偏移;
從TTBR(translation table base register,協(xié)處理器CP15中的一個(gè)寄存器,用于存放一級(jí)頁表的基址)寄存器中獲取一級(jí)頁表的基址;
一級(jí)頁表基址+ VA[31:24] = 該虛擬地址對(duì)應(yīng)的頁表描述符的入口地址;
頁表描述符的[31:24]位為該虛擬地址對(duì)應(yīng)的物理段基址;
物理段基址+ VA[23:0]段偏移= 物理地址
由映射圖可知,一個(gè)虛擬地址可以索引2^8個(gè)一級(jí)頁表入口,每個(gè)入口映射2^24大小的內(nèi)存,故虛擬地址可以映射的最大物理內(nèi)存為:2^8 * 2^24,即4G。
1.3 頁映射,映射粒度為4K
當(dāng)映射方式為頁映射,且映射粒度為4K時(shí),映射圖如下:
虛擬地址到物理地址的映射過程如下:
虛擬地址的[31:20]位存放一級(jí)頁表的入口index,[19:12]位存放二級(jí)頁表的入口index,[11:0]位存放頁偏移;
從TTBR(translation table base register,協(xié)處理器CP15中的一個(gè)寄存器,用于存放一級(jí)頁表的基址)寄存器中獲取一級(jí)頁表的基址;
一級(jí)頁表基址+ VA[31:20] = 一級(jí)頁表描述符的入口地址;
一級(jí)頁表描述符的[31:10]位存放二級(jí)頁表的基址;
二級(jí)頁表基址+ VA[19:12] = 二級(jí)頁表描述符的入口地址;
二級(jí)頁表描述符的[31:12]位存放該虛擬地址在內(nèi)存中的物理頁基址;
物理頁基址+ VA[11:0]頁偏移= 物理地址
由映射圖可知,一個(gè)虛擬地址可以索引2^12個(gè)一級(jí)頁表入口,每個(gè)一級(jí)頁表入口指向的二級(jí)頁表最大可以有2^8個(gè)二級(jí)頁表入口,每個(gè)二級(jí)頁表入口映射2^12大小的內(nèi)存,故虛擬地址可以映射的最大物理內(nèi)存為:2^12 * 2^8 * 2^12 ,即4G。
1.4 頁映射,映射粒度為64K
當(dāng)映射方式為頁映射,且映射粒度為64K時(shí),映射圖如下:
虛擬地址到物理地址的映射過程如下:
虛擬地址的[31:20]位存放一級(jí)頁表的入口index,[19:16]位存放二級(jí)頁表的入口index,[15:0]位存放頁偏移;
從TTBR(translation table base register,協(xié)處理器CP15中的一個(gè)寄存器,用于存放一級(jí)頁表的基址)寄存器中獲取一級(jí)頁表的基址;
一級(jí)頁表基址+ VA[31:20] = 一級(jí)頁表描述符的入口地址;
一級(jí)頁表描述符的[31:10]位存放二級(jí)頁表的基址;
二級(jí)頁表基址+ VA[19:16] = 二級(jí)頁表描述符的入口地址;
二級(jí)頁表描述符的[31:16]位存放該虛擬地址在內(nèi)存中的物理頁基址;
物理頁基址+ VA[15:0]頁偏移= 物理地址
由映射圖可知,一個(gè)虛擬地址可以索引2^12個(gè)一級(jí)頁表入口,每個(gè)一級(jí)頁表入口指向的二級(jí)頁表最大可以有2^4個(gè)二級(jí)頁表入口,每個(gè)二級(jí)頁表入口映射2^16大小的內(nèi)存,故虛擬地址可以映射的最大物理內(nèi)存為:2^12 * 2^4 * 2^16 ,即4G。
1.5 地址映射總圖
《ARM1176 JZF-S Technical Reference Manual》中有一張對(duì)上述四種映射情況的匯總圖:
2. 關(guān)于一級(jí)頁表基址
參考《ARM1176 JZF-S Technical Reference Manual》6.12 MMU descriptors
ARMv6中有兩個(gè)協(xié)處理器寄存器用來存放一級(jí)頁表基地址,TTBR0和TTBR1。操作系統(tǒng)把虛擬內(nèi)存劃分為內(nèi)核空間和用戶空間,TTBR0存放用戶空間的一級(jí)頁表基址,TTBR1存放內(nèi)核空間的一級(jí)頁表基址。
- In this model, the virtual address space is divided into two regions:
- · 0x0 -> 1<<(32-N) that TTBR0 controls
- · 1<<(32-N) -> 4GB that TTBR1 controls.
N的大小由TTBCR寄存器決定。0x0 -> 1<<(32-N)為用戶空間,由TTBR0控制,1<<(32-N) -> 4GB為內(nèi)核空間,由TTBR1控制。
N的大小與一級(jí)頁表大小的關(guān)系圖如下:
操作系統(tǒng)為用戶空間的每個(gè)進(jìn)程分配各自的頁表,即每個(gè)進(jìn)程的一級(jí)頁表基址是不一樣的,故當(dāng)發(fā)生進(jìn)程上下文切換時(shí),TTBR0需要被存放當(dāng)前進(jìn)程的一級(jí)頁表基址;TTBR1中存放的是內(nèi)核空間的一級(jí)頁表基址,內(nèi)核空間的一級(jí)頁表基址是固定的,故TTBR1中的基址值不需要改變。
2.u-boot中MMU初始化代碼分析
2.1 start.s中mmu使能
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, =CFG_PHY_UBOOT_BASE
ldr r2, =0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15, 0, r1, c2, c0, 0
/* Enable the MMU */
mmu_on:
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #1
mcr p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
2.2 lowlevlel_init.s中映射表初始化
.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
.macro FL_SECTION_ENTRY base,ap,d,c,b /*.macro指令是匯編中宏定義的意思,此帶參宏將FL_SECTION_ENTRY base,ap,d,c,b定義成一個(gè)word大小的特定值*/,
.word (\base << 20) | (\ap << 10) | \ /*這個(gè)特定值就是轉(zhuǎn)換表的填充量,其中,參數(shù)base是映射出來的段地址的基地址,從第20位開始。*/
(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)/*20位的大小正好是1MB,由此可知轉(zhuǎn)換表中未保留前20位,映射出來的地址之間間隔為1MB*/
/*故這里采用的是段式映射;繼續(xù)來分析參數(shù),ap是訪問控制位,從第10位開始。d、c、b都是一些權(quán)限位*/
.endm /*.endm,即結(jié)束宏定義*/
注:該宏的用途就是定義一個(gè).word的字段
/*這里開始設(shè)置虛擬映射轉(zhuǎn)換表,這里使用的是段式映射模式,即以段(1MB)為單位進(jìn)行映射*/
/*因此表中的一個(gè)單元只能管1MB,整個(gè)4G內(nèi)存需要?jiǎng)?chuàng)建4096個(gè)表單元,所以后面采用了循環(huán)的方法來創(chuàng)建*/
.section .mmudata, "a"
.align 14
// the following alignment creates the mmu table at address 0x4000.
.globl mmu_table
mmu_table:
.set __base,0 //虛擬地址0開始
// Access for iRAM
.rept 0x100 //循環(huán)定義0x100次,定義0x100個(gè) .word .word .word......,
FL_SECTION_ENTRY __base,3,0,0,0 //.word字段中 高12位位物理基地址
.set __base,__base+1 //地址加1
.endr
此處是定義了0x100個(gè).word 表單元,每個(gè)表單元對(duì)應(yīng)的虛擬地址和物理地址一致 0x00000000-0x10000000~0x10000000
// Not Allowed
.rept 0x200 - 0x100
.word 0x00000000
.endr
此處循環(huán)定義0x100個(gè) 0x00000000,即物理地址為0,即虛擬地址 0x10000000-0x20000000無法訪問
.set __base,0x200 //物理基地址為0x20000000
// should be accessed
.rept 0x600 - 0x200 //循環(huán)0x400次
FL_SECTION_ENTRY __base,3,0,1,1 //定義頁表單元,高12位物理地址為base
.set __base,__base+1
.endr
此處實(shí)現(xiàn)的映射關(guān)系為 虛擬地址0x20000000-0x60000000 對(duì)應(yīng)的物理地址為 0x20000000-0x60000000
.rept 0x800 - 0x600
.word 0x00000000
.endr
虛擬地址 0x60000000-0x80000000空間無法訪問
.set __base,0x800
// should be accessed
.rept 0xb00 - 0x800
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
平行映射, 虛擬地址0x80000000-0xb0000000 對(duì)應(yīng)的物理地址為 0x80000000-0xb0000000
.set __base,0xB00
.rept 0xc00 - 0xb00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
平行映射, 虛擬地址0x80000000-0xb0000000 對(duì)應(yīng)的物理地址為 0x80000000-0xb0000000
.set __base,0xB00
.rept 0xc00 - 0xb00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
.set __base,0x200
// 256MB for SDRAM with cacheable
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
此處實(shí)現(xiàn)映射 虛擬地址0xc0000000-0xd0000000 物理地址 0x20000000-0x30000000
VA PA length
0-10000000 0-10000000 256MB
10000000-20000000 0 256MB
20000000-60000000 20000000-60000000 1GB 512-1.5G
60000000-80000000 0 512MB 1.5G-2G
80000000-b0000000 80000000-b0000000 768MB 2G-2.75G
b0000000-c0000000 b0000000-c0000000 256MB 2.75G-3G
c0000000-d0000000 20000000-30000000 256MB 3G-3.25G
轉(zhuǎn)自:https://www.cnblogs.com/tanghuimin0713/p/3917178.html
聯(lián)系客服