前言
本着学习操作系统的目的来学习mit6.828的课程,虽然之前也上过操作系统课,读过操作系统书,但都是停留在理论方面,这往往会导致过一段时间未用就会遗忘,所以最好的方式就是动手实践,不仅仅能够加深印象,而且可以从不同角度去认识操作系统。
同时,通过写Blog的方式,记录自己完成实验的过程,包括自己的理解,思考过程,以及出错分析,希望自己能够坚持到最后一个实验,也希望自己文章能够给别人带来一些帮助。
概览
在真正着手开发前,我们最好对整个任务有个概览,先从大局上认识它,再去琢磨细枝末节的东西,这样也许会更好一些,如果直接上手细节,缺乏对全局的认识,遇到问题比较难解决。
从lab1我们了解计算机启动的过程,从BIOS到Boot Loader,再到内核的过程,lab1的时候还没有内存分配方面的代码,下面我们探究探究内核如何进入下面要写的这些代码。
上面Boot Loader的代码,它的作用就是从文件系统读取内核代码,然后将控制权交给内核,在红色方框种就是进入到内核代码。下面我们看下内核代码做了些什么。
在kern/entry.S中,有上面的代码,方框显示调用了i386_init代码进行初始化操作,下面查看一下i386_init方法:
重点就是kern/init.c中的i386_init方法,在这个方法里,会打印6828 decimal is…的内容,这正是上面打印出来,其中最重要的就是mem_init方法,该方法在kern/pmap.c中,是整个lab2的核心,lab2就是填空完mem_init方法的内容
故从上面我们可以知道内核是如何进入到我们这个实验内容的过程。
实验目标
实验的目标主要是完成boot_alloc(),page_init(),page_alloc(),page_free(),这几个函数,boot_alloc用来分配内存的,page_init()用来初始化pages和page_free_list这两个数据结构(个人感觉开发过程中,比较难的过程包括数据结构的设计,但这部分工作已经帮我们做好了),page_alloc()函数是用来分配一个页,page_free()是用来释放一个页。
实验步骤
要完成以下内容,是需要对物理内存的布局有个清晰的认识,不然会对base memory, IO hole, extend memory这些概念所困扰,下面是我对这些区域的理解画了一张图。
Base Memory: 0 ~ 640k
IO hole: 640k ~ 0x100000
extend memory: 0x100000 ~ 0xffffffff
了解了基本区域之外,我们得了解一个特殊的叫做end的符号 ,该符号是由链接器产生的,指向的是kernel bbs段结束位置,那么end以上区域就是空闲区域,那么nextfree首次就等于end
有了上面的这些基础,那么对于Part 1应该就是很简单了
boot_alloc()
该函数就是分配内容用的,由于是内核,无法用我们平常在用户程序中调用malloc,其实我的理解它跟malloc功能一样。
// Allocate a chunk large enough to hold 'n' bytes, then update
// nextfree. Make sure nextfree is kept aligned
// to a multiple of PGSIZE.
//
// LAB 2: Your code here.
if (n == 0)
return result;
else {
result = nextfree;
while (n > 0)