Exercise 1
Exercise 1. In the file kern/pmap.c, you must implement code for the following functions (probably in the order given).
boot_alloc()
mem_init() (only up to the call to check_page_free_list(1))
page_init()
page_alloc()
page_free()
check_page_free_list() and check_page_alloc() test your physical page allocator. You should boot JOS and see whether check_page_alloc() reports success. Fix your code so that it passes. You may find it helpful to add your own assert()s to verify that your assumptions are correct.
练习1主要是为了熟悉内存分配的操作,页面初始化,页面内存分配以及页面内存释放等
boot_alloc
主要是启动分配内存,目的是如果n大于0的话,就分配一个新的内存,否则就是返回下一个内存给它,可以看到代码里面的注释ROUNDUP
就是向上取n
的倍数,所以boot_alloc
里面要填充的代码就很简单了。为了方便调试,可以把日志打印出来
cprintf("boot_alloc memory at %x\n", nextfree);
cprintf("Next memory at %x\n", ROUNDUP((char *) (nextfree+n), PGSIZE));
if (n != 0) {
char *next = nextfree;
nextfree = ROUNDUP((char *) (nextfree + n), PGSIZE);
return next;
} else {
return nextfree;
}
使用make qemu-nox
可以看到输出
boot_alloc memory at f0114000
Next memory at f0115000
在mem_init
中可以看到调用过boot_alloc
是boot_alloc(PGSIZE)
,PGSIZE
是4096,是相吻合的。但是boot_alloc
最开始的地址是f0114000
就不是很清楚了
mem_init
是初始化内存,其中有一个要求是需要初始化pages
变量,这个变量是保存struct PageInfo
的结构体的,只需要开辟一块内存空间即可。所以还是使用boot_alloc
函数用来分配,就很简单了
pages = (struct PageInfo*)boot_alloc(sizeof(struct PageInfo) * npages);
memset(pages, 0, npages * sizeof(struct PageInfo));
需要注意的是需要给结构体分配n个页面的大小,即sizeof(struct PageInfo) * npages
,注意sizeof
的使用
page_init
就比较复杂了,不过根据注释来,也可以实现
void
page_init(void)
{
size_t i;
// 1 Mark physical page 0 as in use
pages[0].pp_ref = 1;
// 2. [PGSIZE, npages_basemem * PGSIZE] is free
for(i = 1; i < npages_basemem; i++) {
pages[i].pp_ref = 0<