参考资料
MIT-6.828 Lab 2: Memory Management实验报告
《MIT JOS Lab2: Memory Management》实验报告
准备工作
切换到lab2的分支,然后将lab1的代码合入到lab2中
$git checkout -b lab2 origin/lab2
$git merge lab1
Part 1: Physical Page Management
Exercise1
第一部分只有一个Exercise,即写一个physical page allocator
。
It keeps track of which pages are free with a linked list of struct PageInfo objects, each corresponding to a physical page.这句话告诉我们这个allocator的基本形式是一个链表,链表的节点是struct PageInfo objects
。
boot_alloc
在内核刚初始化的时候,我们只能通过移动指针来分配内存。boot_alloc
将指针从end
开始,增加到end + n
,表示分配了n
个字节的内存。
static void *
boot_alloc(uint32_t n)
{
static char *nextfree; // virtual address of next byte of free memory
char *result;
// Initialize nextfree if this is the first time.
// 'end' is a magic symbol automatically generated by the linker,
// which points to the end of the kernel's bss segment:
// the first virtual address that the linker did *not* assign
// to any kernel code or global variables.
if (!nextfree) {
extern char end[];
nextfree = ROUNDUP((char *) end, PGSIZE);
}
// 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.
+++ result = nextfree;
+++ nextfree = ROUNDUP((char *) nextfree + n, PGSIZE);
return result;
}
mem_init
pages
全局变量保存着所有页表的信息。
在我的环境中,Physical memory: 131072K available, base = 640K, extended = 130432K
,因此总共有32768个页表。
//
"// Allocate an array of npages 'struct PageInfo's and store it in 'pages'."
"// The kernel uses this array to keep track of physical pages: for"
"// each physical page, there is a corresponding struct PageInfo in this"
"// array. 'npages' is the number of physical pages in memory. Use memset"
"// to initialize all fields of each struct PageInfo to 0."
"// Your code goes here:"
+++ pages = (struct PageInfo *)boot_alloc(npages * sizeof(struct PageInfo));
+++ memset(pages, 0, sizeof(npages * sizeof(struct PageInfo)));
page_init
由于没有仔细理解struct PageInfo
中pp_ref
的意义,因此下面的代码都忽略了对pp_ref
的赋值。(第二次提交之后,修改了这部分代码,因此对每一个被使用的页表,pp_ref
都赋值为1)。pp_ref is the count of pointers to this page, for pages allocated using page_alloc.
,即在分配的时候,需要将pp_ref
置1,表示page_alloc
时,有一个指针指向该页表。
void
page_init(void)
{
// The example code here marks all physical pages as free.
// However this is not truly the case. What memory is free?
// 1) Mark physical page 0 as in use.
// This way we preserve the real-mode IDT and BIOS structures
// in case we ever need them. (Currently we don't, but...)
// 2) The rest of base memory, [PGSIZE, npages_basemem * PGSIZE)
// is free.
// 3) Then comes the IO hole [IOPHYSMEM, EXTPHYSMEM), which must
// never be allocated.
// 4) Then extended memory [EXTPHYSMEM, ...).
// Some of it is in use, some is free. Where is the kernel
// in physical memory? Which pages are already in use for
// page tables and other data structures?
//
// Change the code to reflect this.