(gdb) break kvmalloc (gdb) continue (gdb) next (gdb) next # till execution reaches the start of "switchkvm()" line (gdb) print/x kpgdir[0] why is this zero? let's look up a virtual address how about the first instruction of kvmalloc (gdb) x/i kvmalloc 0x80107beb(The exact values of the addresses may be different in your execution, but the behaviour should be similar).: push %ebp how would we translate 0x80107beb to a physical address? Also, let's look at the current value of the instruction pointer (gdb) x/i $eip 0x80107bfb : call 0x80107c02 (gdb) print/x 0x80107beb >> 22 $4 = 0x200 (gdb) print/x kpgdir[0x200] $6 = 0x114007 Q: what is this? Q: what is the PPN? Q: what does the 7 mean? (gdb) print/x (0x80107beb >> 12) & 0xfff $6 = 0x107 (gdb) print/x ((int*)0x114000)[0x107] $12 = 0x107001 Q: what is this? Q: why 1 in the low bits? (gdb) print/x 0x107000 + 0xbeb $13 = 0x107beb (gdb) x/i 0x107beb why did the physical address work in gdb? back to kvmalloc it called setupkvm to create a page table now it calls switchkvm to start using it switchkvm loads kpgdir into %cr3 and now 0x107beb won't work: (gdb) x/i 0x107beb 0x107beb: Cannot access memory at address 0x107beb why?
Read: swtch.S and proc.c (focus on the code that switches
between processes, specifically scheduler
and sched
).
Also process creation: sys_fork() and copyproc().
In this part of the homework you will investigate how the kernel switches between two processes.
Assignment:
Suppose a process that is running in the kernel
calls sched()
, which ends up jumping
into scheduler()
.
Turn in:
Where is the stack that sched()
executes on?
Turn in:
Where is the stack that scheduler()
executes on?
Turn in:
When sched()
calls swtch()
,
does that call to swtch()
ever return? If so, when?
Now think back to gcc calling conventions and the invariants
that gcc expects any function, including swtch
, to
maintain. Compare these invariants with what swtch
actually implements, and the state that our kernel maintains in
a struct context
.
Turn in: Could swtch
do less work and still be
correct? Could we reduce the size of a struct context
?
Provide concrete examples if yes, or argue for why not.
Surround the call to swtch()
in scheduler()
with calls
to cprintf()
like this:
cprintf("a"); swtch(&cpu->scheduler, &proc->context); cprintf("b");
Similarly,
surround the call to swtch()
in sched()
with calls
to cprintf()
like this:
cprintf("c"); swtch(&proc->context, cpu->scheduler); cprintf("d");
Rebuild your kernel and boot it on QEMU. With a few exceptions you should see a regular four-character pattern repeated over and over.
Turn in: What is the four-character pattern?
Turn in: The very first characters are ac
. Why does
this happen?