Question 4 -- 30 points
The machine on my desk works as follows:
- Pages are 4096 bytes.
- Pointers are 4 bytes.
- Page table entries are also 4 bytes each.
- Both user processes and the operating system use
virtual memory. The OS has some mechanism (you don't have
to care what it is) to reference physical memory so that it
can control the VM system. However, its addresses are virtual addresses.
- The code section of a user process starts at address 0x1000.
- The globals section starts at the first multiple of 4096 past
the end of the code segment.
- The heap section starts immediately after the globals section and
may be increased with the sbrk() system call.
- The stack section starts at address 0x7fffffff and grows
downward, but typically it is of a fixed size that cannot grow.
- The operating system has its own code/global/heap. It begins
at address 0x8000000 and grows upward.
- The operating system also has its own stack, which starts
at address 0xffffffff and grows downward. Like the user's
stack it is typically of a fixed size.
Now, for reference, suppose that a user process is running which has
a 8000-byte code section, a 20K global/heap section, and a
12K stack. Moreover, suppose that the operating system's code/globals/heap
is 20K, and its stack is 12K.
Part 1
Suppose my system employs a single page table for all address translation.
The base of this page table is held in a PTBR register.
Draw a plausible state of the memory system when the above user
process is running.
Include protection bits in your drawing when they are relevant. You
may assume that everything fits into physical memory. Don't bother
with a cache or TLB.
Part 2
Suppose my system employs a two-level paging system for all address
translation. The base of the first-level page table is held in
a PTBR register.
Draw a plausible state of the memory system when the above user
process is running.
Part 3
Suppose my system employs four segment tables.
These are indexed by they highest two bits in the virtual address,
and are accessed by four STBR and STLR registers.
For the two segment tables indexed by 01 and 11, the
STBR points to the end of the table instead of beginning.
Draw a plausible state of the memory system when the above user
process is running.
Part 4
For each of the three scenarios, how much memory is taken up
by page/segment tables?
Part 5
In each of the three scenarios,
discuss exactly what must be done to the virtual memory system
when the OS performs a context switch from one process to another.
Don't bother with the cache or TLB. You can make qualitative statements
about which VM system is better, but it should be obvious to me
from your description.
Handy Arithmetic
0x7fffffff / 4096 = 0x7ffff = 524287
0x80000000 / 4096 = 0x80000 = 524288
0xffffffff / 4096 = 0xfffff = 1048575
0x7ffff / 1024 = 511
0x80000 / 1024 = 512
1024 * 512 = 524288
1024 * 1024 = 1048576
Answer
Part 1
If a single page table is used, then the page table must be
big enough to hold every single possible virtual frame number.
In other words, it has to have 0x80000 = 1048576 = 1M entries.
Most of those entries will be invalid, but they must be there
all the same. The following figure shows the state of the system.
In the page table, I show the following protection bits:
- i/v is invalid/valid.
- u/k is user/kernel. The user may only access pages
whose protection is u. The kernal can access either.
- r/w is read-only/read-write.
- x is executable.
Note that there should may also be a reference and dirty bit, but
I don't picture them. Also note that page zero is invalid, and
the user's code is read-only. Since I didn't tell you how big
the kernel's code is, I marked all the kernel's non-stack pages
as read-write and executable.
Part 2
If a two-level page table is used, then the scenario follows
Question 3 from the Fall 1995 final exam,
which we went over in class last thursday. Each page can hold 1024
PTE's, so each second-level page table will be responsible for 4Mb
worth of addresses. As such there may be 1024 second-level page
tables, so the first-level page table actually fits in a page.
Only four of its entries will be valid -- entry 0 (user code/globals/heap),
entry 511 (user stack), entry 512 (kernel code/globals/heap) and
entry 1023 (kernel stack). The picture is below. Note how far less
memory is used.
Part 3
There are four segments, one for the user code/globals/heap (first two
bits are 00) one for the user stack (bits 01), one for the
kernel code/globals/heap
(bits 10) and one for the kernel stack (bits 11). Each of these can
have exactly as many entries are there are valid pages, except that
there is an entry for page 0 which is invalid to catch pointer bugs.
It's a little confusing to have the STBR's of 01 and 11 point to
the end of the segment table, but as you see, it makes perfect sense.
The picture is below:
Part 4
The single page table has 1M of PTE's, so it is 4Mbytes.
The two-level scheme has 5 pages worth of PTE's, so it is 20K,
and the segment table scheme has 19 PTE's total, so it takes
76 bytes!
Part 5
In the single page table scheme, all that is required is for
the PTBR to be switched to the new process's. However, you should
notice that if the VM system has changed at all for the kernel, the
upper half of the new process's page table will have to be updated.
The two-level scheme is the same as the one-level scheme, only now
if the VM system has changed for the kernel, only the first-level
PTE's need to be changed. Thus, you can simply memcpy() the
last 512 entries of the page table from the old to the new process
on every context switch if you wanted to be lazy.
In the segment table scheme, a context switch simply involves
saving and restoring STBR00,
STLR00, STLR01 and STLR01. You don't have
to worry about the kernel at all!
Grading
Yes, a very complex question. Here's how I broke down the points.
- You include r/w/x/u/d bits in your PTE's: 1 point
- You included a kernel/user bit in your PTE's: 1 point
- You got the right number of pages for each segment: 2 points
- Part 1:
- You drew a reasonable page table for the user's portion of the
address space: 4 points
- You drew NULL or invalid PTE's for the pages which should not have
been mapped: 1 point
- You got the OS's part reasonably correct: 1 point.
- Part 2:
- You drew a reasonable two-level page table picture
for the user's portion of the
address space: 4 points
- You drew NULL or invalid PTE's for the pages
which should not have been mapped (in both
the first and second level page tables):
1 point
- You knew that each page of PTE's (both first and second-level)
held 1024 entries: 1 point
- You got the OS's part reasonably correct: 1 point.
- Part 3:
- You drew a reasonable picture for everything. 2 points
- Your segment tables were the right size. 1 point
- You had reasonable values for the STLR's. 1 point.
- Part 4:
- Part 1: The number 1048576 figured in there.
Hopefully, so did 4M: 2 points.
- Part 2: You got it in the right range (i.e. somewhere near 20K): 2 points.
- Part 3: You got it in the right range. 2 points.
- Part 5: Saying something close to reasonable for each part: 1 point each.
Histogram