MIT 操作系统实验 MIT JOS lab5

Lab 5: File system, Spawn and Shell

lab 5 如果实验者仅仅按照code 提示去补全代码把实验搞定,就会觉得明显这里比前面几个实验要水.

但是!如果自己有兴趣去深究的话,就会觉得很值得的.不要仅仅满足于代码补全填空.你都走到这一步了.何不多花些时间尽量的多学习一点FS捏?

玩到lab5的话,希望可以一起交流讨论 touch me by e-mail: [email protected]

Disk Access

The x86 processor uses the IOPL bits in the EFLAGS register to determine whether protected-mode code is allowed to perform special device I/O instructions such as the IN and OUT instructions. Since all of the IDE disk
registers we need to access are located in the x86‘s I/O space rather than being memory-mapped, giving "I/O privilege" to the file system environment is the only thing we need to do in order to allow the file system to access these registers. In effect, the
IOPL bits in the EFLAGS register provides the kernel with a simple "all-or-nothing" method of controlling whether user-mode code can access I/O space.

在 kern/env.c里面补全下面的代码即可

The Block Cache

In our file system, we will implement a simple "buffer cache" (really just a block cache) with the help of

the processor‘s virtual memory system. The code for the block cache is in fs/bc.c

static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_eip, addr, utf->utf_err);

	// Sanity check the block number.
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Allocate a page in the disk map region, read the contents
	// of the block from the disk into that page.
	// Hint: first round addr to page boundary. fs/ide.c has code to read
	// the disk.
	//
	// LAB 5: you code here:

    envid_t envid = thisenv->env_id;
    void *blkaddr = ROUNDDOWN(addr, PGSIZE);

    if (sys_page_alloc(envid, blkaddr, PTE_SYSCALL) < 0)
    {
        panic("bg_pgfault:can't allocate new page for disk block\n");
    }

    if (ide_read(blockno * BLKSECTS, blkaddr, BLKSECTS) < 0)
    {
        panic("bg_pgfault: failed to read disk block\n");
    }

    if (sys_page_map(envid, blkaddr, envid, blkaddr, PTE_SYSCALL) < 0)
    {
        panic("bg_pgfault: failed to mark disk page as non dirth\n");
    }

	// Clear the dirty bit for the disk block page since we just read the
	// block from disk
	if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
		panic("in bc_pgfault, sys_page_map: %e", r);

	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}

// Write req->req_n bytes from req->req_buf to req_fileid, starting at
// the current seek position, and update the seek position
// accordingly.  Extend the file if necessary.  Returns the number of
// bytes written, or < 0 on error.
int
serve_write(envid_t envid, struct Fsreq_write *req)
{
	if (debug)
		cprintf("serve_write %08x %08x %08x\n", envid, req->req_fileid, req->req_n);

	// LAB 5: Your code here.
    int r = 0;
    struct OpenFile *o = NULL;
    size_t nbytes = 0;
    r = openfile_lookup(envid, req->req_fileid, &o);
    if(r < 0)
    {
        cprintf("serve_write: failed to lookup open file id\n");
        return r;
    }

    nbytes = MIN(req->req_n, PGSIZE - (sizeof(int) + sizeof(size_t)));
    nbytes = file_write(o->o_file, (void *) req->req_buf, nbytes, o->o_fd->fd_offset);

    if (nbytes >= 0)
    {
        o->o_fd->fd_offset += nbytes;
    }

    return nbytes;
	//panic("serve_write not implemented");
}

如果我说我在这个鬼地方panic了三天,不停的提示0xef40300地址处发生错误,我靠...原来是因为我下面这个解答敲出来的时候, 中间迭代变量 j 写成了 i ... 血泪的 i j k !! 道友们如果不想自己被自己坑的话,以后还是多注意点...能不用 ijk 就不要用.段代码都不要用...自己好好想个好点的变量名,不要看别人写ijk自己也就跟着写. 我以前抗争了一段时间,后面又开始用ijk,觉得只要代码短点就没事了. 但是长期coding累了之后就特别容易发生错误.
千万千万别用一个字母去做变量名...

// Copy the mappings for shared pages into the child address space.
static int
copy_shared_pages(envid_t child)
{
	// LAB 5: Your code here.

    int r = 0;
    uint32_t i, j, pn;

    for (i = PDX(UTEXT); i < PDX(UXSTACKTOP); i++)
    {
        if(uvpd[i] & PTE_P)
        {
            for(j = 0; j < NPTENTRIES; j++)
            {
                pn = PGNUM(PGADDR(i, j, 0));
                if(pn == PGNUM(UXSTACKTOP - PGSIZE))
                {
                    continue;
                }
                if((uvpt[pn] & PTE_P) && (uvpt[pn] & PTE_SHARE))
                {
                    if( (r = sys_page_map(0,
                                         (void *)(pn * PGSIZE),
                                         child,
                                         (void *)(pn * PGSIZE),
                                         uvpt[pn] & PTE_SYSCALL)) < 0)
                    {
                        return r;
                    }
                }
            }
        }
    }

	return 0;
}

找到trap_dispatch()

对号入座.

	// Handle keyboard and serial interrupts.
	// LAB 5: Your code here.

    if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL)
    {
        serial_intr();
        return;
    }

    if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD)
    {
        kbd_intr();
        return;
    }

测试

目前shell 不知道怎么的,出现了一个找不到设备的bug提示信息.

先把lab5放出来. 还有很多不满意的地方, 后续有机会这几天只要没事就肯定会update : )

panic 几天没关系, 咱没在怕的, 加油~

时间: 2024-10-20 04:32:35

MIT 操作系统实验 MIT JOS lab5的相关文章

MIT 操作系统实验 MIT JOS lab2

MIT JOS lab2 在/kern/kdebug.c 里面会看到这段代码,关注下面的__STAB_BEGIN__ 那段代码 __STAB_BEGIN__   __STAB_END__相关定义在/kern/kernel.ld里面 下面我给出了kernel.ld的主要内容 ENTRY(_start) SECTIONS { /* Link the kernel at this address: "." means the current address */ . = 0xF0100000

MIT 操作系统实验 MIT JOS lab1

JOS lab1 嘿嘿,实验环境还是相当的友好的. 很多东西都准备好了.把重点放在理论的印证上面. MIT才是改变并引领世界的牛校,心神往之,吾身不能至啊~ 国内的北大,上交等学校的OS实验都是直接用的JOS,这点证据还是容易找的...说明什么,不言而喻咯... ----------------------------------------------------------------------------------------------------------------------

MIT 操作系统实验 MIT JOS lab3

MIT JOS lab3 Allocating the Environments Array In lab 2, you allocated memory in  mem_init()  for the  pages[]  array, which is a table the kernel uses to keep track of which pages are free and which are not. You will now need to modify  mem_init()  

MIT 操作系统实验 MIT JOS lab4

MIT JOS lab4 写在前面的碎碎念~ : 经历了LAB 3的洗礼,死磕到了lab 4. 这里还是首先向各位为JOS 实验做过笔记,写过博客,把自己实验代码托管到JOS上面的先行者们致敬! 如果没有这么好的开源环境, 这么好的东西学不来. 珍惜, 不用嘴. Doing is better than saying! -----------------------------------------------------------------------------------------

[操作系统实验lab3]实验报告

[感受]: 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴含的内容丰富很多,也算是有所收获,和大家分享一下我个人的一些看法与思路,如果有错误的话请指正. [关键函数理解]: 首先第一部分我觉得比较关键的是对于一些非常关键的函数的理解与把握,这些函数是我们本次实验的精华所在,虽然好几个实验都不需要我们自己实现,但是这些函数真的是非常厉害!有多厉害,呆会就知

[Ubuntu]操作系统实验笔记

前些日子为了更新Ubuntu到14.04这个LTS版本,连带着把Windows也重新安装了一遍.懒得再安装虚拟机了,尝试一下在Ubuntu14.04这个64位系统里做操作系统实验咯. 1.安装交叉编译器 第一个要解决的问题就是交叉编译器,材料里提供的是x86平台上的交叉编译器.按道理来说64位系统应该是支持32程序的呢.试一下. 先不吐槽说说明文档里面的代码了.首先要解决的是各种权限问题.sudo su似乎不能全部搞定. 经过一堆权限不够的提示后我对安装已经基本没有信心了. 2.安装gxemul

0311 了解和熟悉操作系统实验

实验0.了解和熟悉操作系统实验 专业:商业软件工程2班   姓名:王俊杰  学号:201406114252 一.        实验目的 (1)掌握操作系统的定义和概念: (2)了解各类操作系统的发展历史: 二.        实验内容和要求 使用网络搜索了解各类计算机操作系统的知识,并整理成一篇文档. 实验方法.步骤及结果测试 了解和掌握内容包括: 计算机操作系统的定义和概念: 操作系统是方便用户.管理和控制计算机软硬件资源的系统软件(或程序集合). 从用户角度看,操作系统可以看成是对计算机硬

实验0、了解和熟悉操作系统实验

实验0.了解和熟悉操作系统实验 专业:商业软件工程2班   姓名:韩麒麟  学号:201406114253 一.        实验目的 (1)掌握操作系统的定义和概念: (2)了解各类操作系统的发展历史: 二.        实验内容和要求 使用网络搜索了解各类计算机操作系统的知识,并整理成一篇文档. 三.实验方法.步骤及结果测试 了解和掌握内容包括: 1.计算机操作系统的定义和概念: 操作系统(Operating System,简称OS)是管理电脑硬件与软件资源的程序,同时也是计算机系统的内

0311 实验0、了解和熟悉操作系统实验

实验0.了解和熟悉操作系统实验 专业:商软(2)班   姓名:列志华  学号:201406114254 一.        实验目的 (1)掌握操作系统的定义和概念: (2)了解各类操作系统的发展历史: 二.        实验内容和要求 使用网络搜索了解各类计算机操作系统的知识,并整理成一篇文档. 实验方法.步骤及结果测试 了解和掌握内容包括: 一.  计算机操作系统的定义和概念: 操作系统是现代计算机系统中不可缺少的系统软件,是其他所有系统软件和应用软件的运行基础.操作系统控制和管理整个计算