The first concern of OS161 virtual memory system is how to manage physical
pages. Generally, we can pack a physical page's information into a structure
struct coremap_entry) and use this struct to represent a physical page.
We use an array of
struct coremap_entry to keep all physical pages information.
This array, aka, coremap, will be one of the most important data structure in this lab.
What should we store in coremap entry structure?
For each physical page, we want to know:
- Where is this page mapped? (For swapping)
- What's this pages status? (free, fixed, clean, dirty...)
- Other info (e.g. need by paging algorithm)
A page can have for different states, as shown below.
This diagram is quite clear. Several points to note:
When a physical page is first allocated, its state is DIRTY, not CLEAN. Since this page do not have a copy in swap file (disk). Remember that in a virtual memory system, memory is just a cache of disk.
For some reason, we may want to always keep a certain page in memory, e.g.
- kernel pages, since these pages are direct mapped.
- user stack and code segment pages which we already knew will be frequently accessed.
So we have a special state called "fixed", means that we'll never swap out these pages to disk.
We need to initiate our coremap in
vm_bootstrap. First, we need to find out
how many physical pages in system. We can do this using
is a big trick here. Since we will only know the physical page number, i.e.
coremap array length at runtime, so we'd better just define a
pointer and allocate the actually array at runtime after we got the physical
page number, rather than use a statically defined array with some MACRO like
MAX_PHY_PAGE_NUM. So at first glance, we may write:
But the above code will definitly fail.
Take a look at
we can see that this function will destroy its
before return. So after that, if we call
kmalloc, which call
ram_stealmem to get memory,
ram_stealmem will fail. The
contradiction is: we need to call
ram_getsize to get physical page number
so that we can allocate our coremap(
pages), but once we call
will not be able allocate any pages!
To resolve this contradiction, on one hand, we should initialize all other
data structures, e.g., locks, before we call
ram_getsize. Then we call
ram_getsize to get
lastaddr. After that, instead of using
kmalloc, we must allocate our coremap manually, without invoking any
other malloc routines. A possible solution may be:
Now we allocated our core map just between
lastaddr] will be system's free memory.
Then we initialize the coremap array, we need to mark any pages between [0,
freeaddr) as fixed, since this memory contains important kernel code and
data, or memory mapped I/Os. And we just mark pages between [
astaddr] as free.
At the end of
vm_bootstrap, we may want to set some flags to indicate that
vm has already bootstrapped, since functions like
alloc_kpages may call
different routines to get physical page before and after