操作系统实验:Lab2 物理内存管理

清华大学操作系统Lab2实验报告
课程主页:http://os.cs.tsinghua.edu.cn/oscourse/OS2018spring
实验指导书:https://chyyuu.gitbooks.io/ucore_os_docs/content/
github:https://github.com/chyyuu/ucore_os_lab

实验目的

  • 理解基于段页式内存地址的转换机制
  • 理解页表的建立和使用方法
  • 理解物理内存的管理方法

练习0:填写已有实验

Eclipse的compare with工具

在Project Explorer中选取lab1和lab2目录,右键选择Compare With -> Each Other,得到如图界面。随后,按照需要将lab1中的代码搬入lab2目录。

练习1:实现 first-fit 连续物理内存分配算法

在kern/mm/default_pmm.c中,主要改动了default_alloc_pages和default_free_pages两个函数。注释中说明了我的做法:

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:找到第一个长度大于等于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,在从这个块中取走长度为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;

// 原来的代码,检查每个block中的各个page property是否合法
    for (; p != base + n; p ++) {
        assert(!PageReserved(p) && !PageProperty(p));
        p->flags = 0;
        set_page_ref(p, 0);
    }

// 原来的代码,设置好释放空间的长度和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:检查是否可以和链表的前一项中的空间合并
    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:检查是否可以和链表的后一项中的空间合并
    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算法是否有进一步的改进空间

分析以上first fit算法的代码,可以看到无论是alloc过程还是free过程都需要O(n)的复杂度。如果使用first fit算法,我认为以上代码效率低的主要原因在于使用双向链表组织所有的block,这导致访问必须耗费线性时间。
如果使用树状结构组织,如下图所示,alloc过程将变成DFS,复杂度依旧是O(n),但是free过程在查找插入位置时可以二分查找,从而达到O(logn)的复杂度。

(xi,leni)表示(起始地址,块大小)。其中x0<x1<...<x6,且块地址不相互重叠

此外,first-fit算法还可以改成best-fit算法(适用于大部分分配的尺寸较小时)或worst-fit算法(适用于大部分分配的尺度适中时)。

练习2:实现寻找虚拟地址对应的页表项

//(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); 
请描述页目录项( Page Director Entry) 和页表( Page Table Entry) 中每个组成部分的含义和以及对ucore而言的潜在用处。

页目录项包括一些几部分:

名称 地址 ucore中的对应
Page Table 4KB Aligned Address 31 downto 12 对应的页表地址
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

页表项包括一些几部分:

名称 地址 ucore中的对应
Physical Page Address 31 downto 12 对应的物理地址高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执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?
  • 将引发页访问异常的地址将被保存在cr2寄存器中
  • 设置错误代码
  • 引发Page Fault

练习3:释放某虚地址所在的页并取消对应二级页表项的映射

//(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);
    }
数据结构Page的全局变量( 其实是一个数组) 的每一项与页表中的页目录项和页表项有无对应关系?如果有,其对应关系是啥?

有关系。页目录项保存的物理页面地址(即某个页表)以及页表项保存的物理页面地址都对应于Page数组中的某一页。

如果希望虚拟地址与物理地址相等,则需要如何修改lab2,完成此事? 鼓励通过编程来具体完成这个问题

由于在lab1中是对等映射关系,即

virtual address = linear address = physical address

可以考虑将lab2中的和段页式映射有关的代码恢复到lab1状态。
参考实验指导书中“系统执行中地址映射的四个阶段”一节,逐阶段修改。

  • 更改链接脚本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区域内存页映射的代码
    //disable the map of virtual_addr 0~4M
    // boot_pgdir[0] = 0;
    
实验结果(make qemu)

覆盖的知识点

  • 内存分配
  • 二级页表的创建

未覆盖的知识点

  • 段表的相关内容

与参考答案的区别

  • 练习1:自己完成。
  • 练习2:写完后未能自己调出bug,后参考了答案中的实现。
  • 练习3:自己完成。

总结

在完成本实验代码部分时,由于各个练习需要填写的代码处有完整的指导,因此实现的时候并不困难。但是在回答思考题的时候,发现对OS的理解还远远不够。
最大的困难在于理解练习2中给页中内容清0时,memset的参数填写的是线性地址而非物理地址。之后查看同学讨论后,有同学表示是因为此处已经开启了页表,因此这里硬件会完成线性地址到物理地址的转换。不过目前来看,虽然完成了相应的实验内容,但是对于OS启动时页表相关操作的理解还不够。在实验解释后,我还需要阅读Intel Manual等资料进一步了解x86中的段表页表。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • Introduction 该 lab 主要需要编写操作系统的内存管理部分。内存管理分为两个部分: 内核的物理内存分...
    找不到工作阅读 12,136评论 0 12
  • 操作系统对内存的管理 没有内存抽象的年代 在早些的操作系统中,并没有引入内存抽象的概念。程序直接访问和操作的都是物...
    Mr槑阅读 16,657评论 3 24
  • 6.1非连续内存分配的需求背景 用户想要一块区域,而在内存当中又没有满足这个大小的连续区域,那这个分配就会失败,基...
    龟龟51阅读 812评论 0 0
  • 声明一下 不是每天三四点钟起来想段子 那样有点阴影魔障 我还要找女票呢 ^_^ 话不多说省流量 一朵鲜花插...
    马刺爱波波阅读 246评论 0 0
  • 《爆漫王》是一部除二次元读者以外,普通读者也能看的优秀漫画。 《BAKUMAN》(バクマン。),一般译作《食梦者》...
    iamfanny阅读 2,725评论 4 8