Operating Systems


[total 20 marks]

Hand-In Procedure

You are to turn in this homework before the lecture begins. Please drop your homework in a cardboard box near to the lecture podium. Your homework must be hand-written (typed homeworks will not be accepted).

Assignment : Paging

[2 marks]

On x86 using 4KB pages only, we wish to map virtual address 0x80100000 to physical address 0x00100000 with read-only permissions. Assume that all segments are setup to [0:0xffffffff] and use only paging. You will need to describe the offset at which the page directory and the page table need to be modified and to what values.

Assignment : Page table reload

[6 marks]

Let's look at the page table (kpgdir) that setupkvm produces

(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 :  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?
(The exact values of the addresses may be different in your execution, but the behaviour should be similar).

Assignment : Addressing

[2 marks]

Suppose you wanted bootmain() to load the kernel at 0x80200000 instead of 0x80100000, and you did so by modifying bootmain() to add 0x100000 to the va/pa of each ELF section. Something would go wrong. What?

Assignment : Traps

[4 marks]

xv6 defines two structures that hold saved registers for a process: struct trapframe on sheet 06, and struct context on sheet 20. Explain a situation in which a suspended process will have three sets of saved registers in its kstack.

Assignment : Context switching

[6 marks]

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?