操作系统lab2实验总结——Part1
?
這是MIPS虛擬映射布局圖,在接下來的實(shí)驗(yàn)中,我們需要特別注意的地址分別是kuseg和kseg0區(qū),首先列出這兩個區(qū)域的意義。
MIPS虛存映射布局
32位的MIPS CPU最大尋址空間為4GB(2^32字節(jié)),這4GB虛存空間被劃分為四個部分:
kuseg (TLB-mapped cacheable user space, 0x00000000 - 0x7fffffff): 這一段是用戶模式下可用的地址,大小為2G,也就是MIPS約定的用戶內(nèi)存空間。需要通過MMU進(jìn)行虛擬地址到物理 地址的轉(zhuǎn)換。
kseg0 (direct-mapped cached kernel space, 0x80000000 - 0x9fffffff): 這一段是內(nèi)核地址,其內(nèi)存虛存地址到物理內(nèi)存地址的映射轉(zhuǎn)換不通過MMU,使用時只需要將地址的最高位清零 (& 0x7fffffff), 這些地址就被轉(zhuǎn)換為物理地址。也就是說,這段邏輯地址被連續(xù)地映射到物理內(nèi)存的低端512M空間。對這段地址 的存取都會通過高速緩存(cached)。通常在沒有MMU的系統(tǒng)中,這段空間用于存放大多數(shù)程序和數(shù)據(jù)。對于有 MMU 的系統(tǒng),操作系統(tǒng)的內(nèi)核會存放在這個區(qū)域。
kuseg中有三個大小為PDMAP(4MB)的區(qū)域,分別從0x7f400000開始是ENVS,PAGES和User VPT。需要注意的是PAGES和User VPT的關(guān)系:User VPT中存放了1024個頁表,由于自映射的關(guān)系,這個頁表里又包括了頁目錄的頁表,每一個頁表中又有1024個頁表項(xiàng)。PAGES存放了48個頁表,這48個頁表映射的內(nèi)容是16*1024個物理頁框的結(jié)構(gòu)體(struct Page)的物理內(nèi)存。在lab2實(shí)驗(yàn)中,我們只用了boot_map_segment函數(shù)將PAGES的內(nèi)容進(jìn)行了映射,并沒有操作User VPT的空間。
第一幅圖將是我們理解整個mm/pmap.c的核心,接下來將按照init/init.c中的順序進(jìn)行逐一解釋每個函數(shù)的細(xì)節(jié)和整體的啟動布局。
1 //這是init/init.c里的函數(shù)調(diào)用順序 2 mips_detect_memory(); 3 mips_vm_init(); 4 page_init(); init/init.c一、mips_detect_memory()
1.代碼塊
1 void mips_detect_memory() 2 { 3 //in bytes 4 basemem = 64 * 1024 * 1024;//物理內(nèi)存的大小為64MB-->26位 5 npage = 16 * 1024;//物理頁框的個數(shù) 6 maxpa = basemem;//最大的物理地址 7 extmem = 0;//延申的空間 8 printf("Physical memory: %dK available, ", (int)(maxpa / 1024)); 9 printf("base = %dK, extended = %dK\n", (int)(basemem / 1024), 10 (int)(extmem / 1024)); 11 } mips_detect_memory2.初始化一些內(nèi)存相關(guān)的參數(shù),意義寫在注釋里,不贅述。
二、mips_vm_init()
1.代碼塊
1 void mips_vm_init() 2 { 3 extern char end[]; 4 extern int mCONTEXT; 5 extern struct Env *envs; 6 7 Pde *pgdir; 8 u_int n; 9 10 /* Step 1 */ 11 pgdir = alloc(BY2PG, BY2PG, 1); 12 printf("to memory %x for struct page directory.\n", freemem); 13 mCONTEXT = (int)pgdir;//mCONTEXT是虛擬地址 14 15 boot_pgdir = pgdir; 16 17 /* Step 2*/ 18 pages = (struct Page *)alloc(npage * sizeof(struct Page), BY2PG, 1); 19 printf("to memory %x for struct Pages.\n", freemem); 20 21 n = ROUND(npage * sizeof(struct Page), BY2PG); 22 23 boot_map_segment(pgdir, UPAGES, n, PADDR(pages), PTE_R); 24 25 /* Step 3*/ 26 envs = (struct Env *)alloc(NENV * sizeof(struct Env), BY2PG, 1); 27 n = ROUND(NENV * sizeof(struct Env), BY2PG); 28 boot_map_segment(pgdir, UENVS, n, PADDR(envs), PTE_R); 29 30 printf("pmap.c:\t mips vm init success\n"); 31 } View Code2.目的:
step1:申請了4KB的頁目錄空間。(pgdir)
step2:申請了192KB的結(jié)構(gòu)體空間,將這一塊物理內(nèi)存進(jìn)行二級映射。
step3:申請了線程的空間。(這一塊不在這里討論)
3.布局圖
在函數(shù)的起始位置聲明了
extern char end[];?end[]的地址就是0x8040 0000,在tools/scse0_3.lds處進(jìn)行了定義。
理解這個函數(shù)的關(guān)鍵是理解alloc()函數(shù) 1 static void *alloc(u_int n, u_int align, int clear) 2 { 3 4 extern char end[]; 5 u_long alloced_mem; 6 7 if (freemem == 0) 8 { 9 freemem = (u_long)end; 10 } 11 12 freemem = ROUND(freemem, align); 13 alloced_mem = freemem; 14 freemem = freemem + n; 15 16 if (clear) 17 { 18 bzero((void *)alloced_mem, n); 19 } 20 21 if (PADDR(freemem) >= maxpa) 22 { 23 panic("out of memorty\n"); 24 return (void *)-E_NO_MEM; 25 } 26 27 return (void *)alloced_mem; 28 } allocfreemem(全局變量)是end到physics Memory Max的空閑內(nèi)存,每一次調(diào)用都將alloced_mem移到分配空間的開頭,freemem移到分配空間的結(jié)尾,并返回了alloced_mem的地址。
所以mips_vm_init對于0x8040 0000以后的空間操作如下:
?
首先給pgdir在0x80400000申請了一個4KB的空間,然后給全局變量struct Page *pages申請了npage * sizeof(struct Page)即16*1024*12=192KB的空間。
1 struct Page{ 2 struct { 3 struct Page *le_next; 4 struct Page **le_prev; 5 } pp_link; 6 u_short pp_ref; 7 }; struct Page//?sizeof(struct Page)=0xC接著在boot_map_segment()里,每一次映射在一級頁表的索引是相同的,所以會創(chuàng)造一個二級頁表。
4.boot_map_segment(Pde *pgdir, u_long va, u_long size, u_long pa, int perm)
4.1代碼塊
1 void boot_map_segment(Pde *pgdir, u_long va, u_long size, u_long pa, int perm) 2 { 3 int i, va_temp; 4 Pte *pgtable_entry; 5 6 assert(size % BY2PG == 0); 7 8 for (i = 0; i < size; i += BY2PG) 9 { 10 pgtable_entry = boot_pgdir_Walk(pgdir, va + i, 1);//返回的是頁表項(xiàng)的虛擬地址 11 *pgtable_entry = (pa + i) | perm | PTE_V; //物理地址映射上 12 } 13 } View Code4.2理解和畫了一個的圖(具體說明了end[]以后的虛擬空間是怎么布局的)
這個函數(shù)的目的是將虛擬地址空間[va, va+size) 和物理地址空間[pa, pa+size)建立映射關(guān)系。什么叫建立映射關(guān)系呢?即在虛擬地址所對應(yīng)的二級頁表里存放(物理頁框的)物理地址。下面以下面這個調(diào)用為例,說明二級頁表的映射過程。
boot_map_segment(pgdir, UPAGES, n, PADDR(pages), PTE_R);這個函數(shù)的具體映射是通過boot_pgdit_walk實(shí)現(xiàn)的。
static Pte *boot_pgdir_walk(Pde *pgdir, u_long va, int create)?
? ? ? ? ??
?下面說明一下Pde*的理解(Pde*和Pte*是一樣的)
Pde *pgdir_entryp;在include/mmu.h中定義了
typedef u_long Pde;Pde的類型就是unsigned long,占4B。它的指針是要尋找虛擬空間,大小也是一個頁表項(xiàng),4B。Pde和Pde*都是4B,使它們的轉(zhuǎn)換非常方便。指針實(shí)際上一塊以它為地址的內(nèi)存單元。所以Pde的指針(Pde*)所指的地址就是虛擬地址,而這塊地址的內(nèi)容(Pde)是物理地址,所以實(shí)現(xiàn)了虛擬地址和物理地址的映射關(guān)系。
三、page_init()
1.代碼塊
1 void page_init(void) 2 { 3 /* Step 1 */ 4 LIST_INIT(&page_free_list); //page free list is a struct 5 /* Step 2*/ 6 freemem = ROUND(freemem, BY2PG); 7 /* Step 3 */ 8 int i; 9 int free_page_size = PADDR(freemem) / BY2PG; 10 for (i = 0; i < free_page_size; i++) 11 { 12 pages[i].pp_ref = 1; 13 } 14 /* Step 4 */ 15 for (; i < npage; i++) 16 { 17 pages[i].pp_ref = 0; 18 LIST_INSERT_HEAD(&page_free_list, &pages[i], pp_link); 19 } 20 } page_init()2.目的
這個函數(shù)本身很簡單,其中有兩個問題需要注意:
- 問題1:struct Page *pages; 為什么要申請這些結(jié)構(gòu)體?它和我們的頁表有什么關(guān)系?
- 問題2:Step3"Mark all memory below `freemem` as used"的意義是什么?
在之前的操作中,我們一直使用了兩個虛擬地址,一個是在kuseg0(end[](0x8040 0000) 以后),一個是在kuseg(里面有UPAGES,UVPT,UENVS)。前者不需要mmu直接將高位清零得到物理地址,后者需要mmu將虛擬地址映射到物理地址。所以其實(shí)我們對于end[]以后的所有操作可以理解成這是在對物理內(nèi)存進(jìn)行操作。物理內(nèi)存的大小有多少呢?64MB。64MB的物理內(nèi)存中有16*1024個物理頁框,則16*1024個struct Page和64MB的物理頁框是一一對應(yīng)的。我們知道對空閑物理內(nèi)存進(jìn)行管理有兩種基本的操作:1.位圖;2.鏈表。所以page_free_list可以把空閑的struct Page串起來。
在step3中我們就將end[]后面已經(jīng)使用的內(nèi)核虛擬地址所對應(yīng)的物理地址占用的內(nèi)存,轉(zhuǎn)換為 [PADDR(freemem) / BY2PG] 個頁表,并把它們標(biāo)記過已經(jīng)使用的。
struct Page和物理內(nèi)存是怎么一一對應(yīng)的呢?
(pp - pages)<< PGSHIFT
就是算出這是pages里的第幾個Page,再乘上4KB,就是物理地址了。
上面的兩個問題就解決了。
轉(zhuǎn)載于:https://www.cnblogs.com/puublog/p/10657916.html
總結(jié)
以上是生活随笔為你收集整理的操作系统lab2实验总结——Part1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj 2142 礼物
- 下一篇: 两人团队项目-石家庄地铁查询系统(web