Prep: Boot to Life, Traps, and Interrupts — 42k · 43k · 44k¶
Session: Friday Nov 6, 1h30 · Exercises: 42k_boot_to_life · 43k_traps · 44k_interrupts · Prep time: ~45 min · Lecture: Filesystems, Devices, and the Boot Sequence · Traps, Privilege Modes, and Interrupts
What you will build¶
Three few-line pieces; the reading is the work. First, the boot sequence: console, page allocator, kernel page table with the MMU on, and process table come up in dependency order, and cargo run prints the banner and idles. Second, the kernel drops from machine mode to supervisor mode, points stvec at the given trap vector, and survives its first trap — a breakpoint it counts and steps past. Third, it opens the interrupt gates so the CLINT timer, armed in machine mode and forwarded down as a supervisor software interrupt, is acknowledged and counted. The graded build checks that each subsystem reports ready, that execution continues past the breakpoint, and that ticks arrive at a sensible pace — neither absent nor a storm.
Concepts you need¶
- Boot is a dependency graph — L10 §7 · rv6 Architecture § The boot sequence
- Three privilege modes — L11 §1 · RISC-V guide § Privilege modes
- Exception, interrupt, trap — L11 §2
- The machine-to-supervisor handoff — L11 §3 · RISC-V guide § Control and status registers
- The supervisor trap path — L11 §4 · RISC-V guide § What the hardware does on a trap
- The timer's detour and the three gates — L11 §5 · rv6 Architecture § Path 1
Read before class¶
| What | Time |
|---|---|
| L10 §7–8 (boot graph; reading a boot log) | 12 min |
| L11 §1–2 (modes; exception versus interrupt) | 8 min |
| L11 §3–5 (handoff; trap path; timer) | 20 min |
RISC-V guide § Decoding scause · rv6 Architecture § Two builds |
5 min |
Mental model¶
Every trap lands on one vector with one cause register, so a handler first decodes scause. Two values you will not meet on Friday:
let a: usize = 0x8000_0000_0000_0009; // bit 63 set: interrupt 9 (a keypress)
let b: usize = 0x0000_0000_0000_000d; // bit 63 clear: exception 13 (load page fault)
let is_interrupt = |c: usize| (c >> 63) == 1; // test this FIRST
let code = |c: usize| c & 0xff;
// a: nothing failed; sepc is already the next instruction. Acknowledge, return.
// b: sepc points AT the load: re-run it once repaired, or kill the process.
The codes overlap — 9 is also "ecall from S-mode" — so skipping the top-bit test turns a page fault into a "handled" tick that spins on one instruction. Next week's keystroke, and later the system call, take this exact path.
Check yourself¶
- Why must the page allocator come up before the MMU is switched on?
Answer
Building the kernel page table allocates pages. With the free list empty the root is null,satppoints at physical page 0, and the next instruction fetch goes through garbage — a fault with no handler and no message. - A breakpoint handler returns without touching
sepc. What happens, and why is an interrupt different?Answer
sretresumes atsepc, still theebreak, so it traps again forever and the harness times out. An exception's instruction has not completed, so the handler chooses re-run or step past; an interrupt failed nothing, andsepcalready holds the next instruction. - The timer ticks once, then the kernel hangs. Which gate is closed?
Answer
None — one tick was delivered, so all three were open. The handler did not clearsip.SSIP;sretrestoresSIEfromSPIEand the still-pending interrupt is redelivered immediately: an interrupt storm, one instruction of progress per trap.
What "done" looks like¶
oslings run is green, then oslings submit before you leave. Not green? Submit anyway (substantial credit), then finish by Monday 11:59 pm and submit again.
If you finish early¶
Watch it boot with cargo run from rv6/. Then start next Thursday's prep page (console and shell), or the xv6 book chapter 4, "Traps and system calls."