Lab2:物理內存管理
物理內存佈局的探測和管理
在Lab1當中,我們僅僅是把操作系統內核從硬盤上搬到了內存裏,而沒有對內存進行管理。
其實bootloader在加載ELF文件之前,首先會檢測所有的物理內存塊,把這些內存塊的信息存儲在內存當中的內存塊信息表e820map當中,其中包括:塊的起始地址addr、塊的大小size、塊的類型type(例如是不是可用的)。
當ucore內核開始運行時,將會利用這個信息表去建立一個Page結構表,它按物理地址的順序,保存了每一個物理頁(4KB)的信息,包括:物理頁被虛擬頁引用的次數、頁是否被保留、空閒頁鏈表指針、連續空閒頁的頁數。
隨後,操作系統將會建立一個空閒頁鏈表,它將所有連續空閒內存的起始頁的Page結構鏈接起來。
這樣,當用戶對內存進行請求alloc_page(int n)
和釋放free_page(int n)
的時候,直接遍歷空閒頁鏈表,並修改其中的Page結構即可。
分頁機制的建立
在bootloader階段,不僅初始化了全局描述符表,建立了段機制,同時也建立了臨時的二級頁表。而操作系統內核在後續過程中完善了二級頁表,將操作系統所用的邏輯地址與物理地址對應起來。其中頁目錄的首地址保存在CR3
寄存器當中。此時邏輯地址、線性地址和物理地址的關係如下:
也就是操作系統在物理內存實際是從0x0000000
開始,但是它看到的虛擬地址是0xC0000000
。
當分頁機制建立之後,虛擬地址到物理地址的映射過程如下:
-
將虛擬地址分爲段選擇子和偏移,按照分段機制轉化爲線性地址
-
將線性地址分爲3部分:頁目錄索引Dir、頁表索引Table、偏移Offset
-
根據
CR3
寄存器找到頁目錄表,並根據Dir找到對應的頁目錄項 -
查詢頁目錄項的標誌位,若頁表是否存在,若不存在則調用我們的
alloc_page
函數新建一個頁表 -
根據頁表索引找到頁表項,裏面存儲了物理頁的地址。如果物理頁不存在,則需要繼續分配內存。
可以看到,空閒內存的管理爲分頁機制提供了保障,至此操作系統完成了段頁式機制的處理。程序的虛擬地址可以轉化爲物理地址了。