操作系統(tǒng)實(shí)驗(yàn):Lab2 物理內(nèi)存管理

清華大學(xué)操作系統(tǒng)Lab2實(shí)驗(yàn)報(bào)告
課程主頁:http://os.cs.tsinghua.edu.cn/oscourse/OS2018spring
實(shí)驗(yàn)指導(dǎo)書:https://chyyuu.gitbooks.io/ucore_os_docs/content/
github:https://github.com/chyyuu/ucore_os_lab

實(shí)驗(yàn)?zāi)康?/h3>
  • 理解基于段頁式內(nèi)存地址的轉(zhuǎn)換機(jī)制
  • 理解頁表的建立和使用方法
  • 理解物理內(nèi)存的管理方法

練習(xí)0:填寫已有實(shí)驗(yàn)

Eclipse的compare with工具

在Project Explorer中選取lab1和lab2目錄蒸健,右鍵選擇Compare With -> Each Other,得到如圖界面渣叛。隨后盯捌,按照需要將lab1中的代碼搬入lab2目錄。

練習(xí)1:實(shí)現(xiàn) first-fit 連續(xù)物理內(nèi)存分配算法

在kern/mm/default_pmm.c中箫攀,主要改動(dòng)了default_alloc_pages和default_free_pages兩個(gè)函數(shù)幼衰。注釋中說明了我的做法:

static struct Page *
default_alloc_pages(size_t n) {
    assert(n > 0);
    if (n > nr_free) {
        return NULL;
    }
    struct Page *page = NULL;
    list_entry_t *le = &free_list;

// Step1:找到第一個(gè)長度大于等于n的塊
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        if (p->property >= n) {
            page = p;
            break;
        }
    }

// Step2:如果可以找到長度大于等于n的塊渡嚣,則
// (1) 如果長度大于n,在從這個(gè)塊中取走長度為n的存儲空間识椰,并將剩下的存儲空間插入到列表中
// (2) 刪除原來的塊
    if (page != NULL) {
        if (page->property > n) {
            struct Page *p = page + n;
            p->property = page->property - n;
            SetPageProperty(p);
            list_add_after(&(page->page_link), &(p->page_link));
        }
        list_del(&(page->page_link));
        nr_free -= n;
        ClearPageProperty(page);
    }
    return page;
}
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base;

// 原來的代碼腹鹉,檢查每個(gè)block中的各個(gè)page property是否合法
    for (; p != base + n; p ++) {
        assert(!PageReserved(p) && !PageProperty(p));
        p->flags = 0;
        set_page_ref(p, 0);
    }

// 原來的代碼,設(shè)置好釋放空間的長度和page property
    base->property = n;
    SetPageProperty(base);

// Step1:找到插入鏈表的位置(鏈表已按照地址從大到小排序)
    list_entry_t *le = list_next(&free_list);
    list_entry_t *prev = &free_list;
    while (le != &free_list) {
        p = le2page(le, page_link);
        if (base < p) {
            break;
        }
        prev = le;
        le = list_next(le);
    }

// Step2:檢查是否可以和鏈表的前一項(xiàng)中的空間合并
    p = le2page(prev, page_link);
    if (prev != &free_list && p + p -> property == base) {
        p -> property += base -> property;
        ClearPageProperty(base);
    } else {
        list_add_after(prev, &(base -> page_link));
        p = base;
    }

// Step3:檢查是否可以和鏈表的后一項(xiàng)中的空間合并
    struct Page *nextp = le2page(le, page_link);
    if (le != &free_list && p + p -> property == nextp) {
        p -> property += nextp -> property;
        ClearPageProperty(nextp);
        list_del(le);
    }

    nr_free += n;
}
你的first fit算法是否有進(jìn)一步的改進(jìn)空間

分析以上first fit算法的代碼,可以看到無論是alloc過程還是free過程都需要O(n)的復(fù)雜度航瞭。如果使用first fit算法坦辟,我認(rèn)為以上代碼效率低的主要原因在于使用雙向鏈表組織所有的block,這導(dǎo)致訪問必須耗費(fèi)線性時(shí)間滨彻。
如果使用樹狀結(jié)構(gòu)組織,如下圖所示休偶,alloc過程將變成DFS辜羊,復(fù)雜度依舊是O(n),但是free過程在查找插入位置時(shí)可以二分查找碱妆,從而達(dá)到O(logn)的復(fù)雜度昔驱。

(xi,leni)表示(起始地址,塊大小)纳本。其中x0<x1<...<x6萌衬,且塊地址不相互重疊

此外,first-fit算法還可以改成best-fit算法(適用于大部分分配的尺寸較小時(shí))或worst-fit算法(適用于大部分分配的尺度適中時(shí))朴艰。

練習(xí)2:實(shí)現(xiàn)尋找虛擬地址對應(yīng)的頁表項(xiàng)

//(1) find page directory entry
    pde_t *pdep = pgdir + PDX(la); 
//(2) check if entry is not present
    if (!(*pdep & PTE_P)) { 
//(3) check if creating is needed, then alloc page for page table
        if (create) { 
            struct Page *page = alloc_page(); 
            if (page != NULL) {
//(4) set page reference
                set_page_ref(page, 1); 
//(5) get linear address of page
                pte_t page_la = KADDR(page2pa(page)); 
//(6) clear page content using memset
                memset(page_la, 0, PGSIZE); 
//(7) set page directory entry's permission
                *pdep = page2pa(page) | PTE_P | PTE_W | PTE_U; 
//(8) return page table entry
                return ((pte_t *)(KADDR(PDE_ADDR(*pdep)))) + PTX(la); 
            } else {
                return NULL;
            }
        } else {
            return NULL;
        }
    }
//(8) return page table entry
    return ((pte_t *)(KADDR(PDE_ADDR(*pdep)))) + PTX(la); 
請描述頁目錄項(xiàng)( Page Director Entry) 和頁表( Page Table Entry) 中每個(gè)組成部分的含義和以及對ucore而言的潛在用處混移。

頁目錄項(xiàng)包括一些幾部分:

名稱 地址 ucore中的對應(yīng)
Page Table 4KB Aligned Address 31 downto 12 對應(yīng)的頁表地址
Avail 11 downto 9 PTE_AVAIL
Ignored 8
Page Size 7 PTE_PS
0 6 PTE_MBZ
Accessed 5 PTE_A
Cache Disabled 4 PTE_PCD
Write Through 3 PTE_PWT
User/Supervisor 2 PTE_U
Read/Write 1 PTE_W
Present 0 PTE_P

頁表項(xiàng)包括一些幾部分:

名稱 地址 ucore中的對應(yīng)
Physical Page Address 31 downto 12 對應(yīng)的物理地址高20位
Avail 11 downto 9 PTE_AVAIL
Global 8
0 7 PTE_MBZ
Dirty 6 PTE_D
Accessed 5 PTE_A
Cache Disabled 4 PTE_PCD
Write Through 3 PTE_PWT
User/Supervisor 2 PTE_U
Read/Write 1 PTE_W
Present 0 PTE_P
如果ucore執(zhí)行過程中訪問內(nèi)存毁嗦,出現(xiàn)了頁訪問異常回铛,請問硬件要做哪些事情?
  • 將引發(fā)頁訪問異常的地址將被保存在cr2寄存器中
  • 設(shè)置錯(cuò)誤代碼
  • 引發(fā)Page Fault

練習(xí)3:釋放某虛地址所在的頁并取消對應(yīng)二級頁表項(xiàng)的映射

//(1) check if this page table entry is present
    if (*ptep & PTE_P) { 
//(2) find corresponding page to pte
        struct Page *page = pte2page(*ptep); 
//(3) decrease page reference
        page_ref_dec(page);
//(4) and free this page when page reference reachs 0
        if (page -> ref == 0) {
            free_page(page);
        }
//(5) clear second page table entry
        *ptep = 0;
//(6) flush tlb
        tlb_invalidate(pgdir, la);
    }
數(shù)據(jù)結(jié)構(gòu)Page的全局變量( 其實(shí)是一個(gè)數(shù)組) 的每一項(xiàng)與頁表中的頁目錄項(xiàng)和頁表項(xiàng)有無對應(yīng)關(guān)系腔长?如果有验残,其對應(yīng)關(guān)系是啥?

有關(guān)系鸟召。頁目錄項(xiàng)保存的物理頁面地址(即某個(gè)頁表)以及頁表項(xiàng)保存的物理頁面地址都對應(yīng)于Page數(shù)組中的某一頁。

如果希望虛擬地址與物理地址相等欧募,則需要如何修改lab2槽片,完成此事? 鼓勵(lì)通過編程來具體完成這個(gè)問題

由于在lab1中是對等映射關(guān)系还栓,即

virtual address = linear address = physical address

可以考慮將lab2中的和段頁式映射有關(guān)的代碼恢復(fù)到lab1狀態(tài)。
參考實(shí)驗(yàn)指導(dǎo)書中“系統(tǒng)執(zhí)行中地址映射的四個(gè)階段”一節(jié)谷婆,逐階段修改辽聊。

  • 更改鏈接腳本tools/kernel.ld,將虛擬地址改為0x100000:
    SECTIONS {
      /* Load the kernel at this address: "." means the current address */
      . = 0x0100000;
    
  • 把kernel基地址改回0:
    /* All physical memory mapped at this address */
    #define KERNBASE            0x00000000
    
  • 注釋掉取消0~4M區(qū)域內(nèi)存頁映射的代碼
    //disable the map of virtual_addr 0~4M
    // boot_pgdir[0] = 0;
    
實(shí)驗(yàn)結(jié)果(make qemu)

覆蓋的知識點(diǎn)

  • 內(nèi)存分配
  • 二級頁表的創(chuàng)建

未覆蓋的知識點(diǎn)

  • 段表的相關(guān)內(nèi)容

與參考答案的區(qū)別

  • 練習(xí)1:自己完成异袄。
  • 練習(xí)2:寫完后未能自己調(diào)出bug烤蜕,后參考了答案中的實(shí)現(xiàn)迹冤。
  • 練習(xí)3:自己完成。

總結(jié)

在完成本實(shí)驗(yàn)代碼部分時(shí)泡徙,由于各個(gè)練習(xí)需要填寫的代碼處有完整的指導(dǎo)堪藐,因此實(shí)現(xiàn)的時(shí)候并不困難。但是在回答思考題的時(shí)候礁竞,發(fā)現(xiàn)對OS的理解還遠(yuǎn)遠(yuǎn)不夠。
最大的困難在于理解練習(xí)2中給頁中內(nèi)容清0時(shí),memset的參數(shù)填寫的是線性地址而非物理地址枫绅。之后查看同學(xué)討論后,有同學(xué)表示是因?yàn)榇颂幰呀?jīng)開啟了頁表并淋,因此這里硬件會(huì)完成線性地址到物理地址的轉(zhuǎn)換。不過目前來看句喷,雖然完成了相應(yīng)的實(shí)驗(yàn)內(nèi)容兔毙,但是對于OS啟動(dòng)時(shí)頁表相關(guān)操作的理解還不夠。在實(shí)驗(yàn)解釋后锡溯,我還需要閱讀Intel Manual等資料進(jìn)一步了解x86中的段表頁表哑姚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市倡蝙,隨后出現(xiàn)的幾起案子绞佩,更是在濱河造成了極大的恐慌,老刑警劉巖析既,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谆奥,死亡現(xiàn)場離奇詭異,居然都是意外死亡宰译,警方通過查閱死者的電腦和手機(jī)魄懂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門市栗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咳短,“玉大人蛛淋,你說我怎么就攤上這事」葱В” “怎么了叛甫?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長萌腿。 經(jīng)常有香客問我棠赛,道長,這世上最難降的妖魔是什么睛约? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任辩涝,我火速辦了婚禮,結(jié)果婚禮上捉邢,老公的妹妹穿的比我還像新娘商膊。我一直安慰自己,他們只是感情好藐翎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布实幕。 她就那樣靜靜地躺著,像睡著了一般末贾。 火紅的嫁衣襯著肌膚如雪整吆。 梳的紋絲不亂的頭發(fā)上辉川,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天员串,我揣著相機(jī)與錄音昼扛,去河邊找鬼欲诺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扰法,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浦箱,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼酷窥,長吁一口氣:“原來是場噩夢啊……” “哼伴网!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起澡腾,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤动分,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后姆另,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玛瘸,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年右核,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渺绒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菱鸥。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡氮采,死狀恐怖染苛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躯概,我是刑警寧澤畔师,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站姿锭,受9級特大地震影響伯铣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腔寡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一蹬蚁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧犀斋,春花似錦叽粹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啡氢,卻和暖如春术裸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亭枷。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工袭艺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叨粘。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓猾编,卻偏偏與公主長得像,于是被迫代替她去往敵國和親升敲。 傳聞我的和親對象是個(gè)殘疾皇子袍镀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Introduction 該 lab 主要需要編寫操作系統(tǒng)的內(nèi)存管理部分。內(nèi)存管理分為兩個(gè)部分: 內(nèi)核的物理內(nèi)存分...
    找不到工作閱讀 12,182評論 0 12
  • 操作系統(tǒng)對內(nèi)存的管理 沒有內(nèi)存抽象的年代 在早些的操作系統(tǒng)中冻晤,并沒有引入內(nèi)存抽象的概念。程序直接訪問和操作的都是物...
    Mr槑閱讀 16,672評論 3 24
  • 6.1非連續(xù)內(nèi)存分配的需求背景 用戶想要一塊區(qū)域绸吸,而在內(nèi)存當(dāng)中又沒有滿足這個(gè)大小的連續(xù)區(qū)域鼻弧,那這個(gè)分配就會(huì)失敗锦茁,基...
    龜龜51閱讀 813評論 0 0
  • 聲明一下 不是每天三四點(diǎn)鐘起來想段子 那樣有點(diǎn)陰影魔障 我還要找女票呢 ^_^ 話不多說省流量 一朵鮮花插...
    馬刺愛波波閱讀 248評論 0 0
  • 《爆漫王》是一部除二次元讀者以外攘轩,普通讀者也能看的優(yōu)秀漫畫。 《BAKUMAN》(バクマン码俩。)度帮,一般譯作《食夢者》...
    iamfanny閱讀 2,785評論 4 8