name: Non-Obvious Kernel Design Guidelines description: Critical design decisions from kernel.pdf §5,6,9 that are easy to get wrong type: project
These are completely different:
Mode switch: user↔kernel via INT/IRET/ESP0. Happens every syscall and interrupt.
Context switch: one thread → another, by replacing %esp with another thread's kernel stack pointer. Does NOT involve INT or IRET (unless doing it wrong).
There should be exactly one code path for context switching. Multiple context-switch code paths indicate multiple conflicting partial understandings and typically mean multiple bugs.
When a thread is suspended in kernel mode (e.g., blocked on a lock), the context switch brings it back to where it was in kernel mode - not to user space.
Design locking architecture upfront. "You can't add locking in at the last minute."
disable_interrupts() is for managing interrupts, not for managing other threads. Use it only to make short (provably few-instruction) critical sections atomic with respect to interrupts.
Must use mutex/cond/spinlock for anything involving cross-thread coordination.
A kernel using only disable_interrupts() for synchronization will not be preemptible → will grade poorly.
Treat design as if targeting multiprocessor: interrupt disabling only fixes one processor.
Round-robin FIFO is sufficient. Scheduler run-time must be O(1) with respect to number of threads in any queue.
Timer interrupt rate: switch threads at least every 5ms; 2ms is better. Vary the timer rate during development to find race conditions.
Preemptibility is ~10% of grade: kernel should always handle interrupts promptly regardless of what code is running.
Graders prefer a kernel that always switches to the waiting thread (rather than resuming the interrupted thread) when an interrupt signals a completion event.
Bottom 16 MB ([0x00000000, 0x01000000)) = kernel, direct-mapped. User code must NOT be able to read or write this range.
User frames come from 0x01000000 upward.
malloc() and friends only manage kernel virtual memory. For physical frames, implement a separate free-frame allocator (the singly-linked list stored in frames themselves).
smemalign(alignment, size) + sfree(ptr, size) for aligned kernel allocations (page tables, page directories). Must track size to call sfree.
Never disable paging or switch to real mode - get course staff permission first.
When inserting a "fake" mapping into a page table, TLB may cache it long after removal. Use INVLPG or write to %cr3 to flush as needed.
.text and .rodata sections loaded read-only (user threads cannot write them).
Zero out unused partial pages between executable sections.
getbytes() abstraction in kern/loader.c wraps exec2obj RAM disk access.
elf_check_header() + elf_load_helper() from 410kern/elf/load_helper.c parse ELF.
Validate every byte of every pointer argument against the invoking task's page tables.
For exec() string args: walk the null-terminated array and each null-terminated string byte by byte.
Validation may be "early" or "late" - both are legal - but must happen before any pointer dereference that could crash the kernel.
Kernel must never crash or kill a thread due to bad syscall arguments; return negative error code instead.
Free resources as quickly as possible after thread exit. "Zombie threads" should not hold resources long.
A thread cannot free its own kernel stack (it's standing on it) - design carefully for who frees it.
vanish() on the last thread in a task triggers full task teardown: free all user frames, page tables, page directory, thread structs, etc.
For source-level user-space debugging to work:
sim_reg_process(pd_addr, execname) when loading a new program (or sim_reg_child() for fork).set_cr3() when switching address spaces (Simics auto-switches symbol tables).sim_unreg_process() when a task exits.Why: These are the non-obvious architectural decisions that kernel.pdf marks as important and that past student kernels commonly got wrong.
How to apply: When reviewing or suggesting implementation strategies for these areas, check against these guidelines.
Table of Content