xv6, line by line
tour 46
Tours46 Boot: returning from a trap that never happened

Tour 46 · The dance of privilege · about 25 minutes · 17 steps

Boot: returning from a trap that never happened

A RISC-V hart can lower its privilege in exactly one way: by returning from a trap. mret returns from a machine-mode trap, sret from a supervisor-mode trap. There is no “enter supervisor mode” instruction. So to get from machine mode, where every hart wakes up, to supervisor mode, where the kernel lives, start fakes it. It writes into the machine-mode CSRs exactly what a trap from supervisor mode would have left there, and then executes mret. The hart “returns” to a place it has never been. This is transition T8, the only one that involves machine mode.

Tour 2: Power-on to main, on every hart at once walked through start line by line, and Tour 42: One hart's stacks, from power-on to the first user instruction followed the boot stack. This tour takes the state lens: for each CSR that start writes, what it means in the privileged architecture, the value gdb read back on all three harts in this build, and what we saw happen in a scratch copy of xv6 when that line was removed. It ends with a question that matters for every later tour: why machine mode is never entered again.

All three harts do this at the same moment, each on its own slice of stack0, with no lock, because every register start touches is private to the hart that writes it.

Best after: 2. Power-on to main, on every hart at once, 41. Every transition: mode, stack and page table, 42. One hart's stacks, from power-on to the first user instruction

Who is running where

QEMU’s virt machine has just been switched on with -smp 3. When the tour starts:

Hart What it is doing
0 In machine mode at pc = 0x1000, about to run QEMU’s boot ROM
1 The same, at the same address
2 The same, at the same address

There are no processes, no page tables, no stacks. The kernel image is already in memory at 0x80000000, placed there by QEMU’s -kernel option.

Three harts are running. This tour follows one path through the code, but the machine has three CPUs executing at the same time. Watch the locks held display at the top of each step, and read the Meanwhile, on other harts boxes: they show what the other CPUs could be doing at that very moment.
The route
  1. 1Reset leaves almost nothing defined kernel/memlayout.h
  2. 2Three slices of stack0, written by three harts at once kernel/entry.S
  3. 3MPP, the privilege a trap would have come from kernel/start.c
  4. 4mepc, the instruction a trap would have interrupted kernel/start.c
  5. 5satp = 0, so main's first fetch is not translated kernel/start.c
  6. 6Delegation, and the rule it cannot bend kernel/start.c
  7. 7sie, the individual switches kernel/start.c
  8. 8PMP, the permission machine mode must grant kernel/start.c
  9. 9menvcfg.ADUE, or the kernel faults on its first fetch kernel/start.c
  10. 10Sstc, the timer that never visits machine mode kernel/start.c
  11. 11mcounteren.TM, permission to read the clock kernel/start.c
  12. 12The first alarm, set from machine mode kernel/start.c
  13. 13tp, the one thing that survives the drop kernel/start.c
  14. 14mret, exactly kernel/start.c
  15. 15Why machine mode never comes back kernel/start.c
  16. 16Three harts arrive in main, in supervisor mode kernel/main.c
  17. 17What start set, and who touches it later kernel/main.c

Keys: ← → step · Home start