資源
練習1:實現 first-fit 連續物理內存分配算法
題目
在實現first fit 內存分配算法的回收函數時,要考慮地址連續的空閒塊之間的合併操做。提示: 在創建空閒頁塊鏈表時,須要按照空閒頁塊起始地址來排序,造成一個有序的鏈表。可能會修改default_pmm.c中的default_init,default_init_memmap,default_alloc_pages,default_free_pages等相關函數。請仔細查看和理解default_pmm.c中的註釋。linux
請在實驗報告中簡要說明你的設計實現過程。請回答以下問題:你的first fit算法是否有進一步的改進空間?git
解答
個人設計實現過程
-
因爲default_pmm.c文件中已經提供了一種內存分配算法的實現,所以個人設計是在default_pmm.c的基礎上修改實現的。github
-
分配內存:default_pmm的現有算法在分配內存時和first fit基本相同,都是遍歷空閒鏈表,找到第一個不小於待申請的物理頁數目的空閒block。算法
- 若是空閒block的物理頁數目恰好等於待申請的數目,那麼直接將該空閒block所有分配給申請者,具體而言須要將該空閒block對應的節點page_link從空閒鏈表中移除、更新空閒頁面的總數nr_free、設置該空閒block的property以標識其已被分配。
- 若是空閒block的物理頁數目大於待申請的數目,那麼將空閒block拆分紅兩個block,第一個block的物理頁數目等於待申請的數目,第二個block的物理頁數目爲剩餘的數目。具體而言,首先,和第一種狀況相似,須要將第一個block對應的節點page_link從空閒鏈表移除、更新空閒頁面的總數nr_free、設置第一個block的property以標識其已被分配。而後,須要將第二個block對應的節點Page_link插入到空閒鏈表中。此時,default_pmm的作法是把第二個block直接插在空閒列表的開頭,這不符合first fit算法的要求,由於first fit要求空閒列表中的block須要按物理地址從小到大排列。所以這裏須要修改。
- 修改方案是:在搜索到第一個符合要求的空閒block,而且空閒block的頁數大於待申請的頁數時,就地拆分當前空閒block,並將第二個block插入到當前空閒block的後面,而後刪除當前空閒block便可。
-
釋放內存:default_pmm的現有算法在釋放內存時作法是:遍歷空閒鏈表,若是發現空閒鏈表當前節點對應的空閒block和待釋放block在物理地址上是連續的,則先將空閒鏈表中對應的空閒block刪除,而後合併到待釋放block中。遍歷完畢後,將待釋放block出入到空閒鏈表的開頭便可。這裏一樣不符合first fit算法的要求,由於待釋放的block未必是空閒鏈表中對應的block中物理地址最小的,將其插到開頭,將破壞first fit要求的空閒block按物理地址從小到大排列的規則。編程
- 修改方案:首先對default_pmm的遍歷鏈表進行優化:當空閒鏈表中對應的block是按照物理地址排序時,咱們能夠很容易找到待釋放block應該插入的位置:它應該插入到第一個物理地址比本身大的空閒block的前面。所以,咱們的while循環不須要從頭至尾遍歷一遍空閒鏈表,而是找到上述位置便可中止。
- 找到待插入位置時,還須要判斷先後的空閒block的物理地址是否與本身相鄰,共有4種可能,須要分類討論。
是否有進一步的改進空間
個人設計針對default_pmm的釋放內存算法進行了優化,目前暫沒發現其餘改進空間。數組
練習2:實現尋找虛擬地址對應的頁表項
題目
經過設置頁表和對應的頁表項,可創建虛擬內存地址和物理內存地址的對應關係。其中的get_pte函數是設置頁表項環節中的一個重要步驟。此函數找到一個虛地址對應的二級頁表項的內核虛地址,若是此二級頁表項不存在,則分配一個包含此項的二級頁表。本練習須要補全get_pte函數 in kern/mm/pmm.c,實現其功能。請仔細查看和理解get_pte函數中的註釋。數據結構
請在實驗報告中簡要說明你的設計實現過程。請回答以下問題:架構
- 請描述頁目錄項(Page Directory Entry) 和頁表項(Page Table Entry) 中每一個組成部分的含義以及對ucore而言的潛在用處。
- 若是ucore執行過程當中訪問內存,出現了頁訪問異常,請問硬件要作哪些事情?
個人設計實現過程
get_pte函數中的詳細註釋已經給出了處理流程,這裏結合個人代碼簡單描述一下。app
-
首先,輸入參數pgdir是頁目錄表的起始邏輯地址,線性地址la的最高10位是頁目錄表的索引,二者結合獲得對應的頁目錄項pde。函數
-
頁目錄項的最低位是PTE_P,標記當前頁目錄項對應的頁表空間是否存在。所以檢查頁目錄項的最低位,若爲1,則說明對應的頁表空間存在,這時須要進一步找到對應的頁表項pte的邏輯地址。頁目錄項pde將最低12位清零後便可獲得對應頁表的起始物理地址,加上0xC0000000後獲得起始邏輯地址,又因爲線性地址la的第21~12位是頁表索引,二者結合獲得對應的頁表項pte的邏輯地址。
-
若頁目錄項的最低位爲0,則說明對應的頁表空間不存在。這時檢查輸入參數create的值,若爲0則直接返回NULL。
-
若create的值爲1,則須要進行如下處理
- 爲當前頁表申請一個物理頁,設置物理頁的ref爲1,代表目前只有一個邏輯地址被映射到當前物理頁
- 初始化對應物理頁的內存空間爲全0
- 設置頁目錄項pde的值,注意除了設置頁表物理地址外,還要設置PTE_P, PTE_W及PTE_U等標誌位,表示對應的頁表空間如今已經存在、具備可寫權限、用戶態下可訪問
- 最後,將對應物理頁的起始物理地址加上0xc0000000獲得起始邏輯地址,加上線性地址la中提供的頁表索引,便可獲得對應頁表項pte的邏輯地址
回答問題1:頁目錄項和頁表項各部分的含義及用途
- 頁目錄項:頁目錄項各部分的含義見《Intel And IA-32 Architecture Software Developer's Manual》的如下表格,下面簡述各部分的用途:
- 第0位用來確認對應的頁表是否存在,爲1時表示存在,能夠進一步查找對應的頁表;爲0時表示頁表不存在,這時須要分配一個物理頁給當前頁表。
- 第1位用來確認對應的頁表是否可寫,因爲內存分配和釋放時均需修改對應的頁表項,所以第1位須要置位
- 第2位用來確認用戶態下是否能夠訪問,若是爲0則該頁目錄項對應的4M物理空間均不能在用戶態下訪問。因爲用戶須要對物理空間具備讀或寫權限,所以第2位也須要置位。實驗指導書中也有說明:「只有當一級二級頁表的項都設置了用戶寫權限後,用戶才能對對應的物理地址進行讀寫。 因此咱們能夠在一級頁表先給用戶寫權限,再在二級頁表上面根據須要限制用戶的權限,對物理頁進行保護。」
- 第3~4位用於cache,暫不關注。
- 第5位用來確認對應頁表是否被使用。
- 第31~12位是頁表的起始物理地址,用於定位頁表位置。
Bit | Contents |
---|---|
0 (P) | Present; must be 1 to reference a page table |
1 (R/W) | Read/write; if 0, writes may not be allowed to the 4-MByte region controlled by this entry |
2 (U/S) | User/supervisor; if 0, user-mode accesses are not allowed to the 4-MByte region controlled by this entry |
3 (PWT) | Page-level write-through; indirectly determines the memory type used to access the page table referenced by this entry |
4 (PCD) | Page-level cache disable; indirectly determines the memory type used to access the page table referenced by this entry |
5 (A) | Accessed; indicates whether this entry has been used for linear-address translation |
6 | Ignored |
7 (PS) | If CR4.PSE = 1, must be 0 (otherwise, this entry maps a 4-MByte page; see Table 4-4); otherwise, ignored |
11:8 | Ignored |
31:12 | Physical address of 4-KByte aligned page table referenced by this entry |
- 頁表項:頁表項各部分的含義見《Intel And IA-32 Architecture Software Developer's Manual》的如下表格,下面簡述各部分的用途:
- 第0位用來確認頁表項對應的物理頁是否存在,爲1時表示存在
- 第1位用來確認對應的物理頁是否可寫,爲0時表示不可寫
- 第2位用來確認用戶態下是否可訪問對應的物理頁,爲0時表示用戶態下不可訪問
- 第3~4位用於cache,暫不關注。
- 第5位用來確認對應頁表是否被使用。
- 第31~12位是對應物理頁的起始物理地址,用於定位物理頁位置。
Bit | Contents |
---|---|
0 (P) | Present; must be 1 to map a 4-KByte page |
1 (R/W) | Read/write; if 0, writes may not be allowed to the 4-KByte page referenced by this entry |
2 (U/S) | User/supervisor; if 0, user-mode accesses are not allowed to the 4-KByte page referenced by this entry |
3 (PWT) | Page-level write-through; indirectly determines the memory type used to access the 4-KByte page referenced by this entry |
4 (PCD) | Page-level cache disable; indirectly determines the memory type used to access the 4-KByte page referenced by this entry |
5 (A) | Accessed; indicates whether software has accessed the 4-KByte page referenced by this entry |
6 (D) | Dirty; indicates whether software has written to the 4-KByte page referenced by this entry |
7 (PAT) | If the PAT is supported, indirectly determines the memory type used to access the 4-KByte page referenced by this entry |
8 (G) | Global; if CR4.PGE = 1, determines whether the translation is global ; ignored otherwise |
11:9 | Ignored |
31:12 | Physical address of the 4-KByte page referenced by this entry |
回答問題2:出現頁訪問異常時硬件要作哪些事情
這個問題不太會。首先須要對頁訪問異常進行分類:缺頁(虛擬地址無對應的物理頁)、權限檢查出錯等。
練習3:釋放某虛地址所在的頁並取消對應二級頁表項的映射
題目
當釋放一個包含某虛地址的物理內存頁時,須要讓對應此物理內存頁的管理數據結構Page作相關的清除處理,使得此物理內存頁成爲空閒;另外還需把表示虛地址與物理地址對應關係的二級頁表項清除。請仔細查看和理解page_remove_pte函數中的註釋。爲此,須要補全在kern/mm/pmm.c中的page_remove_pte函數。
請在實驗報告中簡要說明你的設計實現過程。請回答以下問題:
- 數據結構Page的全局變量(實際上是一個數組) 的每一項與頁表中的頁目錄項和頁表項有無對應關係?若是有,其對應關係是啥?
- 若是但願虛擬地址與物理地址相等,則須要如何修改lab2,完成此事? 鼓勵經過編程來具體完成這個問題
個人設計實現過程
page_remove_pte函數中的詳細註釋已經給出了處理流程,下面簡單介紹個人代碼實現過程。
- 檢查頁表項pte的最低位PTE_P的值,若爲0,則說明對應的物理頁不存在,此時直接返回便可
- 若頁表項pte的最低位爲1,則說明對應的物理頁存在。這時,首先將頁表項的低12位清零獲得物理頁的起始地址,並據此獲得對應的Page結構,將Page的ref字段減1,代表取消當前邏輯地址到此物理地址的映射。而後,判斷Page的ref的值是否爲0,若爲0,則說明此時沒有任何邏輯地址被映射到此物理地址,換句話說當前物理頁已沒人使用,所以調用free_page函數回收此物理頁;若不爲0,則說明此時仍有至少一個邏輯地址被映射到此物理地址,所以不需回收此物理頁。
- 將對應的頁表項pte清零,代表此邏輯地址無對應的物理地址。
- 調用tlb_invalidate函數去使能TLB中當前邏輯地址對應的條目。
回答問題1: pages與頁目錄項和頁表項的對應關係
當頁目錄項或頁表項有效時(即頁目錄項或頁表項有具體的數值而非全0),數據結構pages與頁目錄項和頁表項有對應關係。pages每一項記錄一個物理頁的信息,而每一個頁目錄項記錄一個頁表的信息,每一個頁表項則記錄一個物理頁的信息。假設系統中共有N個物理頁,那麼pages共有N項,第i項對應第i個物理頁的信息。而頁目錄項和頁表項的第31~12位構成的20位數分別對應一個物理頁編號,所以也就和pages的對應元素一一對應。
回答問題2:如何修改lab2使得虛擬地址與物理地址相等?
擴展練習1:buddy system(夥伴系統) 分配算法(待完成)
題目
Buddy System算法把系統中的可用存儲空間劃分爲存儲塊(Block)來進行管理, 每一個存儲塊的大小必須是2的n次冪(Pow(2, n)), 即1, 2, 4, 8, 16, 32, 64, 128...
參考夥伴分配器的一個極簡實現, 在ucore中實現buddy system分配算法,要求有比較充分的測試用例說明實現的正確性,須要有設計文檔。
擴展練習2:任意大小的內存單元slub分配算法(待完成)
題目
slub算法,實現兩層架構的高效內存單元分配,第一層是基於頁大小的內存分配,第二層是在第一層基礎上實現基於任意大小的內存分配。可簡化實現,可以體現其主體思想便可。
參考linux的slub分配算法/,在ucore中實現slub分配算法。要求有比較充分的測試用例說明實現的正確性,須要有設計文檔。
疑問
-
如何理解lab2中不一樣階段的屢次地址映射?
-
如何理解lab2的內存佈局?
/* * * Virtual memory map: Permissions * kernel/user * * 4G ------------------> +---------------------------------+ * | | * | Empty Memory (*) | * | | * +---------------------------------+ 0xFB000000 * | Cur. Page Table (Kern, RW) | RW/-- PTSIZE * VPT -----------------> +---------------------------------+ 0xFAC00000 * | Invalid Memory (*) | --/-- * KERNTOP -------------> +---------------------------------+ 0xF8000000 * | | * | Remapped Physical Memory | RW/-- KMEMSIZE * | | * KERNBASE ------------> +---------------------------------+ 0xC0000000 * | | * | | * | | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * (*) Note: The kernel ensures that "Invalid Memory" is *never* mapped. * "Empty Memory" is normally unmapped, but user programs may map pages * there if desired. * * */
- 爲何lab2的物理內存佈局是這樣的?
e820map: memory: 0009fc00, [00000000, 0009fbff], type = 1. memory: 00000400, [0009fc00, 0009ffff], type = 2. memory: 00010000, [000f0000, 000fffff], type = 2. memory: 07ee0000, [00100000, 07fdffff], type = 1. memory: 00020000, [07fe0000, 07ffffff], type = 2. memory: 00040000, [fffc0000, ffffffff], type = 2.