操作系统:ucore的部分Bug&挑战练习

本文详述了在ucore操作系统学习过程中遇到的问题,包括Lab2 Result代码错误,Lab3 Clock算法实现,以及Lab8内核和用户程序错误的分析与修复。作者分享了错误原因、解决方案,并提供了部分代码实现和测试结果的解读。
摘要由CSDN通过智能技术生成

ucore是清华大学提供的一个学习操作系统的平台。ucore有完整的mooc视频与说明文档。

https://objectkuan.gitbooks.io/ucore-docs/content/#

本文将主要记录在完成ucore平台的实验时,个人认为ucore内核及Result中的存在的问题,以及部分挑战练习内容。由于个人水平有限,可能理解有误,欢迎前来讨论。

本文主要内容:

  • Lab2 物理内存管理 练习一 Result代码错误
  • Lab3 虚拟内存管理 挑战练习 Clock算法实现
  • Lab8 文件系统 内核错误 用户程序ls错误

Lab2 练习一 Result代码错误

在实现first fit 内存分配算法的回收函数时,要考虑地址连续的空闲块之间的合并操作。提示:在建立空闲页块链表时,需要按照空闲页块起始地址来排序,形成一个有序的链表。

ans中思路是把所有的空闲页都加入空闲列表,这样效率非常低,且其中有很多标志位置位错误。我选择使用类似于实验指导书上的思路,将一个空闲块中的一个空闲页加入到空闲列表中。所有的操作只是对空闲段里面的第一个空闲页的操作。

代码中详细的注释,这里不做过多的说明。

/*
 * Details of FFMA
 * Prepare: In order to implement the First-Fit Mem Alloc (FFMA), we should manage the free mem block use some list.
 * 为了能够接入FFMA我们要先建立空闲列表
 * The struct free_area_t is used for the management of free mem blocks.
 * free_area_t是空闲列表的中的结构体
 * At first you should be familiar to the struct list in list.h.
 * struct list is a simple doubly linked list implementation.
 * 首先要在list.h找到list结构体
 * list是一个双向链表
 * You should know howto USE: list_init, list_add(list_add_after), list_add_before, list_del, list_next, list_prev
 * 嗨呀就是简单的链表操作
 * Another tricky method is to transform a general list struct to a special struct (such as struct page):
 * you can find some MACRO: le2page (in memlayout.h), (in future labs: le2vma (in vmm.h), le2proc (in proc.h),etc.)
 * 可以吧list的结构体转为page|proc的结构体
 **/
free_area_t free_area;

#define free_list (free_area.free_list)
#define nr_free (free_area.nr_free)
/**
 * default_init:
 * you can reuse the  demo default_init fun to
 * init the free_list and set nr_free to 0.
 * 代码已经实现了 init freelist 然后设置nr_free 为0
 * free_list : is used to record the free mem blocks.
 * nr_free   : is the total number for free mem blocks.
 */
static void default_init(void) {
    list_init(&free_list);
    nr_free = 0;
}

/**
 * default_init_memmap:
 * 调用顺序: kern_init --> pmm_init-->page_init-->init_memmap--> pmm_manager->init_memmap
 * This fun is used to init a free block (with parameter: addr_base, page_number).
 * 这个函数是用来初始化一个free block 参数有base和page_number
 * 若本页是空的 且不是第一页,flag中的property位设置为0
 * 若本页是空的 且是第一页,flag中的property位设置为1 说明其有效
 * 若本页空 且是第一页 property就是总共的空block数
 * reference 引用的count清0 也就是有没有对应咯
 **/
static void default_init_memmap(struct Page *base, size_t n) {
    //assert用来检查一个判断是否为真
    assert(n > 0);
    struct Page *p = base;
    for (; p != base + n; p++) {
        p->flags = 0;
        //若本页空&&不是第一页,property就是总共的空block数
        p->property = 0;
        //reference引用的count清0
        p->ref = 0;
        ClearPageReserved(p);
        // from memlayout
        // if this bit=1:
        // the Page is reserved for kernel,
        // cannot be used in alloc/free_pages;
        // otherwise, this bit=0
    }
    //跟新一共有多少个free page
    nr_free += n;
    //first block
    SetPageProperty(base);
    //若本页空&&第一页,property就是总共的空block数
    base->property = n;
    list_add(&free_list, &(base->page_link));
}

/**
 * default_alloc_pages:
 * search find a first free block (block size >=n)
 * in free list and reszie the free block,
 * return the addr of malloced block.
 **/
static struct Page *
default_alloc_pages(size_t n) {
    list_entry_t *list_iterator, *nxtptr;
    struct Page *first_fit_page;
    assert(n > 0);
    //要分配的页数大于剩余的free数
    if (n > nr_free) {
        return NULL;
    }
    list_iterator = &free_list;
    //循环访问一次free list
    while ((list_iterator = list_next(list_iterator)) != &free_list) {
        //从link回去找到page的base addr
        first_fit_page = le2page(list_iterator, page_link);
        //若当前的page可用大于需要的size
        //注意这个地方,只有一个空闲区域里面的first page才会有property的data
        if (first_fit_page->property >= n) {
            //将这片空闲区域中的n个block分配出去
            //检查这n个block能否分配
            struct Page *alloc = first_fit_page;
            for (; alloc != first_fit_page + n; alloc++) {
                //若Reserved位为1 不能alloc和free
                assert(!PageReserved(alloc));
            }
            //若这个空闲区域里面空闲的数量比我需要的数量还要多
            if (first_fit_page->property > n) {
                //原来空闲的空间这样子 H是空闲区域里面first page
                //||H1....................x..................||
                //现在这个空闲的区域变成了这样子
                //.......n.......||H2........x-n.............||
                //设置其property为剩下的x-n个block
                //向后找n个page后的page
                struct Page *new_head = first_fit_page + n;
                new_head->property &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值