💾 Archived View for vierkantor.com › xukut › manual › exception.gmi captured on 2024-05-10 at 10:37:57. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
This is an explanation of low-level design in XukutOS. We hope that the design works well enough that you can stick to higher-level stuff for day to day activities.
The memory fault handler should not only touch statically-allocated memory (e.g. the kernel's own code, kernel stacks, objects declared in the assembler). If you do not follow this rule, infinite loops could occur.
Do not read from or write to exception-related registers (elr, esr, far, spsr, ...), unless:
* between the exception is taken and the read, all memory access is to statically-allocated memory (e.g. the kernel's own code, kernel stacks, objects declared in the assembler)
* between a write and exception return, all memory access is to statically-allocated memory (e.g. the kernel's own code, kernel stacks, objects declared in the assembler)
Instead, use the values stored on the stack by the exception handler stubs (FN_EXC / EINDE_FN_EXC).
The memory system works by swapping in memory pages lazily: only when a virtual address is accessed for the first time, will the address be mapped to a physical page. This also happens for memory allocated by the kernel. The first access causes a memory fault exception, which is then handled by the kernel by inserting the physical page. As a consequence, exceptions can occur while the kernel is handling another exception. This is called a "nested exception".
XukutOS manual → Memory: more details on the design of the memory system
Exceptions cause certain system registers to be overwritten with new values, e.g. the memory address that caused a fault, or the address to return to after the exception has been handled. This means we need to save any exception-specific registers before they get overwritten by a memory fault, and restore them before exception return. The exception code rules above guarantee that nested exceptions do not occur in places where the registers could be overwritten.
Nested exception handlers should make sure they don't re-use data structures used by the normal exception code, most importantly the object stack. Pass the parameter `keep_stack = 1' to `FN_EXC' when declaring a nested exception handler, and it will re-use the existing stacks (rather than start at the top of the kernel stacks).
Any questions? Contact me:
By email at vierkantor@vierkantor.com