111qqz的小窝

老年咸鱼冲锋!

【施工中】MIT 6.828 lab 2: Memory Management

Part 1: Physical Page Management

操作系统必须时刻追踪哪些物理内存在使用,哪些物理内存没有在使用。

一个问题是,

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要求写一个physical page allocator。我们先看第一个函数boot_alloc()

 

这个函数只有在JOS初始化虚拟内存之前会被调用一次。

通过查看 mem_init 函数可以知道,boot_alloc 是用来初始化页目录(page directory)

为什么我们需要一个单独的page allocator呢?原因是:

kernel启动时需要将物理地址映射到虚拟地址,而我们需要一个page table来记录这种映射关系。但是创建一个page table涉及到为page table所在的page分配空间…而为一个page分配空间需要在将物理地址映射到虚拟地址以后。。

解决办法是,使用一个单独的page allocator,在一个固定的位置allocate memory. 然后在这部分去做初始化的工作。

参考xv6-book:

There is a bootstrap problem: all of physical memory must be mapped in order
for the allocator to initialize the free list, but creating a page table with those mappings
involves allocating page-table pages. xv6 solves this problem by using a separate page
allocator during entry, which allocates memory just after the end of the kernel’s data
segment. This allocator does not support freeing and is limited by the 4 MB mapping
in the entrypgdir, but that is sufficient to allocate the first kernel page table.

这个函数有两个难点,第一个是,如何才能”allocate memory”? 说到”allocate memory”总是想到malloc…但是现在我们什么都没有…

然而实际上很简单(虽然我卡了好一会。。。),我们只要计算出第一个虚拟地址就好了。根据注释, magic symbol ‘end’位于没有被任何kernel code或全局变量占用的虚拟地址的起始位置。

第二个是,如何确定何时空间不够? 我们观察函数i386_detect_memory

发现这个函数的作用是得到剩余的物理内存。其中basemem就是0-640k之间的memory,extmem是1M以后的memory.

npages是剩余物理内存的页数,每页的大小是PGSIZE。因此一共能分配的空间大小为(npages*PGSIZE)

而虚拟地址的base为KERNBASE(定义在inc/memlayout.h中),因此最大能访问的虚拟地址为KERNBASE+(npages*PGSIZE)

最后的实现为:

接下来的部分就相对简单了。首先是mem_init,初始化PageInfo,由于是在page_init之前,不能使用page_alloc,因此这部分allocate也是由boot_alloc完成的。这也是唯二的由boot_alloc来分配内存的部分。代码如下:

接下来是page_init.这部分主要是判断哪些page是free的,哪些不是,参考注释,主要是[EXTPHYSMEM,…)这部分。 我们知道,对于EXTPHYSMEM之上的内存空间,首先kernel占用的空间,kernel之后是分配给kern_pgdir的空间,再然后是分配给PageInfo的空间。这之后的空间,应该都是可用的。因此代码如下:

再然后是page_alloc函数。其实就是取一个链表头的操作。

再之后的page_free. 相对应的,就是在链表头插入一个节点的操作。

到现在,练习1就算完成了。怎么知道我们的实现是对的呢,启动JOS,断言应该挂在page_insert处,并且make grade显示Physical page allocator: OK  就应该是没问题了。

【施工完成】MIT 6.828 lab 1: C, Assembly, Tools and Bootstrapping

花费了30+小时,终于搞定了orz

 

Part 1: PC Bootstrap

The PC’s Physical Address Space

8086/8088时代

由于8086/8088只有20跟地址线,因此物理内存空间就是2^20=1MB.地址空间从0x00000到0xFFFFF.其中从0x00000开始的640k空间被称为”low memory”,是PC真正能使用的RAM。从 0xA0000 到 0xFFFFF 的384k的non-volatile memory被硬件保留,用作video display buffers和BIOS等。

READ MORE →

【施工中】MIT 6.828 Operating System Engineering 学习笔记

课程主页

这课稍微有点硬核…感觉基础稍微有些不扎实就做不下去orz.

网上似乎是有博客写了6.828的学习笔记,不过我更希望自己能够独立完成,二手的知识,谁知道是对的错的呢…况且课程本身给的参考资料应该还是足够多的。

环境的话,手头没有ubuntu系统,恰好半年前剁了阿里云的轻应用服务器,就在上面做吧。

为了这门课,我读了/计划读以下书籍(随时更新)。大概也是为了检查一遍自己的知识体系。

每个lab用到的网页形式的参考资料,会在每个lab的博客中分别给出。

最后,放一段《游褒禅山记》中的文字,与君共勉!

夫夷以近,则游者众;险以远,则至者少。而世之奇伟、瑰怪,非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。有志矣,不随以止也,然力不足者,亦不能至也。有志与力,而又不随以怠,至于幽暗昏惑而无物以相之,亦不能至也。然力足以至焉,于人为可讥,而在己为有悔;尽吾志也而不能至者,可以无悔矣,其孰能讥之乎?