1.分頁機制
- 虛拟記憶體通過CPU的硬體單元映射到實體記憶體中,實體記憶體也以頁為機關進行管理,稱為實體頁面(Physical Page)或者頁幀(Page Frame)。
- 程序虛拟位址空間的頁稱為虛拟頁(Virtual Page)
- 作業系統為了管理這些頁幀需要按照實體位址順序給每個頁幀編号,稱為頁幀号(Page Frame Numeber,PFN)
- CPU内部負責虛拟頁面到實體頁面轉換的硬體單元稱為記憶體管理單元(Memory Management Unit,MMU)
- ARM處理器的MMU包括TLB和Table Walk Unit,TLB是一塊高速緩存,緩存頁表轉換的結果,減少記憶體通路時間
- 一個完整的頁表翻譯和查找的過程叫做頁表查詢(Translation Table Walk)
2.虛拟位址到實體位址的轉換
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0zZzkleGJTYoRnMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2ATMyADNyATMwIjMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
當TLB未命中時,處理器按上圖流程查詢頁表
- 處理器根據頁表基位址控制寄存器TTBCR和虛拟位址判斷使用哪個頁表基位址寄存器TTBRx
- 頁表基位址寄存器中存放着一級頁表的基位址
- 處理器根據虛拟位址的bit[31:20]作為索引,在以及頁表中找到頁表項
- 一級頁表的表項中存放着二級頁表的實體基位址,虛拟位址的bit[19:12]作為索引在二級頁表中找到相應的頁表項。
- 二級頁表項裡存放着4KB實體基位址。
3.記憶體布局圖
- Linux核心包括核心模式和使用者模式
- ARM處理器的user模式共使用者程序使用,supervisor模式供核心使用;
- Linux核心通常把0~3G給使用者空間, 3GB ~ 4GB給核心空間
- Linux32位的典型記憶體空間布局圖如下
- 核心空間從3GB(0xC000000)開始,
- lowmem(0xC000000 - 0xef800000)是線性映射區,大小為760Mb
- 線性映射區即,實體記憶體線性的映射到核心空間中
- 實體位址[0:760MB]被線性映射到[3GB:3GB+760MB]的虛拟位址上
- 線性映射區虛拟位址和實體位址相差PAGE_OFFSET,3GB
- 核心空間被分為兩大區域,低端區域用于線性映射區,高端區域用于vmalloc區域及其他映射區
4.從程序角度看記憶體管理
- ELF(Executable and Linkable Format)是linux上流行的可執行檔案格式
- 用來定義不同類型的對象檔案中存放了什麼東西,以及什麼格式去存放
- 結構如下圖所示
Linux核心學習(3)-記憶體管理1.分頁機制2.虛拟位址到實體位址的轉換3.記憶體布局圖4.從程式角度看記憶體管理 - 常見的幾個段(Section):
- 代碼段(.text):存放源代碼被編譯後的機器指令;
- 資料段(.data):存放已經初始化的全局變量和已經初始化的局部靜态變量;
- bss段(.bss):存放為初始化的全局變量和未初始化的局部靜态變量;
- 可以通過如下指令編譯成elf檔案
$ arm-linux-gnueabi-gcc -static test.c -o test.elf
- 可以使用readelf工具來檢視elf包含哪些段(section)
$ arm-linux-gnueabi-readelf -S test.elf
- 程式在編譯時盡量把相同權限屬性的段配置設定在同一個空間裡,叫做分段(Segment)
- 描述這些Segment的結構叫做程式頭(Program Header),描述了ELF檔案是如何映射到程序位址空間的
arm-linux-gnueabi-readelf -l test.elf
- 可以看到上面的31個section被分為了7個segment,并表明了映射關系
- 可以通過proc檔案系統動态窺探linux核心運作情況