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
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
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.)
virtual_memory_map(kernel_pagetable, 0, 0, 8 * PAGESIZE, PTE_P);
size_t size = 16 * PAGESIZE; virtual_memory_map(process_pagetable, PROC_START_ADDR, MEMSIZE_PHYSICAL - size, size, PTE_P | PTE_U);
virtual_memory_map(process_pagetable, PROC_START + PAGESIZE, 0x100000, 4096, PTE_P|PTE_W|PTE_U);
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
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?
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?
Please fill out this survey .