MIT 6.828 操作系统工程 lab2 通关指南

这篇博客详细记录了作者完成 MIT 6.828 操作系统工程 Lab2 的过程,涵盖物理页面管理、虚拟内存、内核地址空间等方面。内容包括代码实现、问题解决和关键函数的说明,如 page_init()、page_alloc() 和 page_free()。同时,提供了实验代码仓库链接和相关参考资料。
摘要由CSDN通过智能技术生成

这篇是我自己探索实现 MIT 6.828 lab2 的笔记记录,会包含一部分代码注释和要求的翻译记录,以及踩过的坑/个人的解决方案

这里是我实现的完整代码仓库,也包含其他笔记等等:https://github.com/yunwei37/6.828-2018-labs

目录

lab2 主要是关于内存管理的部分。内存管理包含两个组件:

  • 内核的物理内存分配器:
    • 任务将是维护数据结构,该数据结构记录哪些物理页是空闲的,哪些是已分配的,以及多少进程正在共享每个分配的页。您还将编写例程来分配和释放内存页面。
  • 虚拟内存
    • 您将根据我们提供的规范修改JOS以设置MMU的页表。

实验2包含以下新的源文件:

  • inc/memlayout.h:描述了必须通过修改pmap.c来实现的虚拟地址空间的布局
  • kern/pmap.c
  • kern/pmap.h:PageInfo 用于跟踪哪些物理内存页可用的结构
  • kern/kclock.h:操纵PC的电池供电时钟和CMOS RAM硬件,其中BIOS记录PC包含的物理内存量。
  • kern/kclock.c

第1部分:物理页面管理

操作系统必须跟踪物理RAM的哪些部分空闲以及当前正在使用哪些部分,现在,您将编写物理页面分配器:它使用struct PageInfo对象的链接列表(与xv6不同,它们不嵌入在空闲页面中)跟踪哪些页面是空闲的,每个对象都对应于一个物理页面。

那么接下来就进入练习1的内容,我们可以先去看看需要做什么再回过来看代码:

练习1:在kern/pmap.c文件中,为以下功能实现代码:

  • boot_alloc()
  • mem_init()
  • page_init()
  • page_alloc()
  • page_free()

这两个部分的测试函数在 check_page_free_list() 和 check_page_alloc(),也许可以添加一点 assert() 进行验证。

这部分需要做不少了解性的工作,但我觉得帮助比较大的方向还是直接去看相应函数里面的提示和测试用例;毕竟这些写的都已经比较详细了:

先从 boot_alloc() 开始。它是一个简单的物理内存分配器,仅在JOS设置其虚拟内存系统时使用。这里的分配地址,实际上就是简单的更新地址值,在看完注释之后应该很快就可以开始写:

static void *
boot_alloc(uint32_t n)
{
   
	static char *nextfree;
	char *result;

	if (!nextfree) {
   
		extern char end[];
		nextfree = ROUNDUP((char *) end, PGSIZE);
	}

	if (n == 0) {
   
		return nextfree;
	} else if (n > 0) {
   
		result = nextfree;
		nextfree += ROUNDUP(n, PGSIZE);
		return result;
	}

	return NULL;
}

mem_init() 需要我们设置一个两层的页表,实际上这部分的内容不仅仅只包含在物理页面分配中,也包含了lab2余下的部分。我们可以先取消掉 panic 试试看:

很不幸,立马爆个 Triple fault. 出来了…不过还是能得到一部分有用的信息,它可以告诉我们有多少物理内存空间:

Physical memory: 131072K available, base = 640K, extended = 130432K

接下来我们就继续把这个 panic 取消掉,然后一步步调试。

根据 mem_init() 里面的下一步描述,我们需要使用 boot_alloc 分配一个 struct PageInfo 的数组,这一部分应该也很简单:

pages = (struct PageInfo*)boot_alloc(npages * sizeof(struct PageInfo));
memset(pages, 0, npages * sizeof(struct PageInfo));

(注意看对应英文的注释)

下一步就是 page_init() 函数,这一步我觉得它的注释比较混乱,但实际上需要注意的部分就是各个内存片段节点之间的顺序:

我们可以用打印log的方式打印出相关信息查看:

  • npages: 32768
  • npages_basemem: 160
  • PGNUM(PADDR(kern_pgdir)): 279
  • PGNUM(boot_alloc(0)): 344
  • PGNUM((void*)EXTPHYSMEM): 256
  • PGNUM((void*)IOPHYSMEM): 160

这几个之间一部分是IO的空洞,一部分是内核代码和我们分配记录的page信息,这部分要注意留空不分配;再仔细观察一下 check_page_free_list,尝试测试驱动开发:

(余下的一部分可用的工具类函数记得查询一下相关头文件)

void
page_init(void)
{
   
	size_t i;
	for (i = 1; i < PGNUM(IOPHYSMEM); i++) {
   
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值