【linux】arm mm內存管理

歡迎轉載,轉載時請保留做者信息,謝謝。html

郵箱:tangzhongp@163.comlinux

博客園地址:http://www.cnblogs.com/embedded-tzp數組

Csdn博客地址:http://blog.csdn.net/xiayulewaapp

 

 

這篇文章寫的很好:Linux中的內存管理   http://blog.chinaunix.net/uid-26611383-id-3761754.htmldom

 

  arm mmu硬件原理

clip_image001

 

clip_image002

 

由上圖,arm分四種模式,section,大小頁+ 極小頁,  section模式簡單,也能說明mmu本質,其它模式只是用了多級數組索引而已,本質是同樣的,詳細能夠閱讀arm920t的技術文檔,此處僅說section模式。ide

 

clip_image003

 

 

虛擬地址到物理地址轉換是由arm硬件自動管理的,上面這圖的Translation table是存在內存中的,是一個數組,數組的首地址即TTB(Translation table base), 其值被賦值給協處理器CP15Register 2, translation table base (TTB) register, 該數組是被Indexed by modified virtual address bits [31:20],共12位索引,數組元素個數有2 ^ 12 = 4096個,每一個MVA12位能夠索引1Msectionui

該數組元素的內容是:this

clip_image004

所以程序要作的工做主要爲在內存中申請該數組(全局,棧,堆都行),而後將該數組賦值,再將該數組首地址給CP15TTB寄存器,內存管理從宏觀來講就是這麼簡單。spa

 

轉換成程序語言就是:.net

static __global unsigned long  mmu_translation_table[4096] = {}; // 2^12

 

CP15.R2 = &mmu_translation_table[0]; //TTB 

 

因而可知,mmu_translation_table會額外佔用4096 * 4(sizeof(unsigned long)) = 16KB的空間。

 

mmu_translation_table[0]mmu_translation_table[1]...等又該如何初始化和賦值呢?

 

clip_image004[1]

 

上圖的Section base本質上是物理地址,佔31:20位。

能夠定義成一個結構體, 假設爲小端:

typedef  struct {

    u32  pfn : 12; // Section base address, page frame number

    u32  reserve0: 8;

    u32  AP: 2; // access permissions

    u32  reserve1: 1;

    u32  domain: 4; // Specify one of the 16 possible domains (held in the domain accesscontrol register) that contain the primary access controls

    u32  reserve2: 1;

    u32  C: 1; 

    u32  B: 1; // These bits (C and B) indicatewhether the area of memory mapped by this section is treated as write-back cachable, write-through cachable, noncached buffered, or noncached nonbuffered

    u32  des_type: 2; //section,大小頁+ 極小頁

} mmu_translation_table_element_t;

 

 

根據上述定義,能夠從新定義mmu table

static __global mmu_translation_table_element_t  mmu_translation_table[4096] = {0}; // 2^12

CP15.R2TTB = &mmu_translation_table[0]; (天然語言)

 

公式

綜上所述,物理地址與虛擬地址的關係明確爲:

 

mmu_translation_table[VA >> 20] = PA & ((~0) << 20) + 權限控制位(共20位)

 

可見,mmu_translation_table12位由物理地址的高12位組成,低20位爲該物理段的權限控制。

 

PA =  mmu_translation_table[VA >> 20] & ((~0) << 20) + VA & (1 << 20 - 1);

 

上述公式的解釋爲:虛擬地址的高12位做爲下標去索引mmu_translation_table,索引到的內容只取高12位,獲得了物理地址的高位地址,再與虛擬地址的低20位組合,則得到了真實的物理地址。

 

  linux mmu

 

內核地址空間劃分:

 

clip_image005

 

src\arch\arm\kernel\vmlinux.lds中,定義 . = 0xC0000000 + 0x00008000, 所以linux kernel 代碼的虛擬地址從0xC0008000處開始。

而在u-boot加載內核代碼時,有tftp 0x30008000 uImage,所以linux kernel的物理地址從0x30008000開始。

 

PA(0x30008000) ↔ VA(0xC0008000)

 

clip_image007

相關文章
相關標籤/搜索