Becoming Familiar with Weensy OS
In assignment 6, you'll be writing a virtual memory system for Weensy OS. Today, you're going to start familiarizing yourself with some key features of Weensy and some of the functions that you'll want to use.
If you have not finished the exercises from Tuesday, it will be useful to finish those up and then tackle these (we think these will take less time).
Get some code
Today's code can be found in the cs61-exercises
repository in the
l23
directory. This is an early version of the WeensyOS (it is not the
same as the code base from which you will be starting assignment 6; it
is sufficient for today's exercises, but should not be used to start the
assignment; we'll release that code over the weekend).
What are some of the key parameters describing Weensy
Let's start by perusing kernel.h
.
1. How large is a Weensy virtual address space?
2. Which is larger, the physical address space or the virtual one?
3. How many pages are there in a virtual address space?
4. How many pages are there in the physical address space?
One of your best friends in this assignment is a function called
virtual_memory_map
. The video presented the three key bits in an x86
PTE, the present bit, the read write bit, and the supervisor/user bit.
In Weensy, we refer to these bits with the three macros: PTE_P
(present), PTE_W (writable), and PTE_U (accessible to user or
unprivileged code). Read the description of virtual_memory_map
to
answer the next few questions. For each question below, describe
logically what will happen. Let's do an example:
virtual_memory_map(kernel_pagetable, 0, 0, 32 * 1024, PTE_P);
A true statement, but a non-answer to the question might be, "It maps 32 KB in VAS 0 to physical address 0 with permission PTE_P." A better answer is, "It maps 32 KB of physical memory into the kernel's address space. Interestingly, it maps the virtual addresses to the same physical addresses. This memory is read-only, accessible only to the operating system. It would be a good place to store the kernel's code and read-only data."
Here we go! (Each question is standalone -- do not assume they would all be in effect at the same time.)
5.
virtual_memory_map(kernel_pagetable, 0, 0, 8 * PAGESIZE, PTE_P);
6.
size_t size = 16 * PAGESIZE;
virtual_memory_map(process_pagetable, PROC_START_ADDR, MEMSIZE_PHYSICAL - size, size, PTE_P | PTE_U);
7.
virtual_memory_map(process_pagetable, PROC_START + PAGESIZE, 0x100000, 4096, PTE_P|PTE_W|PTE_U);
8.
virtual_memory_map(process_pagetable, 0x400000, 0, PAGESIZE, PTE_P);
9. Write a call to virtual_memory_map
that might be suitable to
allocate a 4 KB stack segment to the kernel.
10. When might you need to call the function virtual_memory_lookup
?
11. Chris and Alex are arguing about page tables. Chris claims that you really don't need a user/supervisor bit in page tables entries, because the kernel has its own page table and processes have their own page table, so a process could never access a translation to a kernel page. Alex says that the bits are quite important, because they allow you to map the kernel's pages into a process's address space safely. Chris says this is a dumb idea. What do you think?
12. If you read through the rest of kernel.h
you might have found a
function that will be useful for debugging. What is it?
13. lib.c
contains functions deemed to be handy for both user
processes and the kernel. One such routine is the ever-useful memcpy
.
Could you use it all of the following cases: copying a file pathname
inside a user process? copying a file pathname inside the kernel?
copying a file pathname between a user process and the kernel? For each
case, why or why not?
14. Chris and Alex are at it again! Alex says that the only time processes should share pages is if they are sharing data. Chris says that they should share code pages as well. What do you think?
Wrapping Up
Please fill out this survey.