Week 6.b CS6640 10/12 2023 https://naizhengtan.github.io/23fall/ 1. kernel ~= three handlers 2. egos syscall implementation 3. egos exception handling --- 0. last time: egos booting process CPU jmps to 0x20400000 +-> earth.S:_enter +-> earth.c:main +-> grass.S:_enter +-> grass.c:main +-> app.S:_enter +-> sys_proc.c:main ... +-> sys_shell.c:main 1. kernel ~= three handlers Q: what are the three ways to trap to kernel a) interrupts We've learned this. Q: How does a CPU know what to execute when a interrupt is triggered? A: mtvec Q: How does kernel know which interrupt has been triggered? A: mcause Q: After handling interrupts, where does CPU to jump to? A: mepc Q: how it works? [draw a cpu + memory] b) exceptions CPU: "I don't know how to process". Show trap reason table [see handout] Q: ask students which exception the examples will trigger Examples: * read/write invalid memory * run invalid instructions * run privileged instructions in unprivileged mode These are synchronized traps. Q: how the exception works on RISC-V CPUs? Similar to interrupts. Again, mtvec, mcause, mepc, Q: if the same, how to tell exceptions from interrupts? Check the first bit of mcause. c) syscalls Interfaces for user applications to "talk" to kernel. Multiple design questions for kernel developers (you): Q1: how to trap to kernel? // Kernel has a function proc_yield(). // A user app which is another program want to call proc_yield(). // How to do this? Q2: how does kernel understand what the application wants? That is, what information is needed for handling a syscall? // Syscall type // Syscall arguments // Syscall return value Q3: Where to store the information? // registers? // stacks? // well-known memory places? 2. egos syscall implementation Overview, take a look at the workflow. [see handout] a) answers to Q1: sys_invoke() so far, MISP Example: explore MISP (in CPU manual) vs. mip.MISP (in RISC-V spec) (gdb) display/t $mip (gdb) b syscall.c:57 Q: why we have a loop here? because of async pending interrupts. Q: can we do better? use "ecall" b) answers to Q2: [read grass/syscall.h] struct syscall c) answers to Q3: [read grass/syscall.c] SYSCALL_ARGS (a well-known memory address) 3. egos exception handling Motivating example: a user program allocating too much memory. (crash1) The kernel will crash/panic/fatal error. This is not ideal. Ideally, an OS should kill the process. Example: [read example] Run an example "malloc" on MacOS. $ malloc (on one terminal) $ htop -F malloc (on another terminal) Q: What do you expect to see? Will see: """ ... allocated 107.00 GB memory zsh: killed ./malloc """ Code: go through a complete pass of the exception handling. trap_entry (cpu_intr.c) | +-> trap_handler (kernel.c) | (ctx_start) | +-> ctx_entry() | +-> excp_entry(id) | +->[your code] | +-> ctx_switch() // back to user stack | +-> [end of trap_handler] | +-> [end of trap_entry] -> [user space]