CS 332 w22 — Interrupts and System Calls
Table of Contents
1 Reading: Limited Direct Execution
Read Chapter 6 (p. 55–68) of the OSTEP book. It builds on the dual-mode execution reading from Wednesday and discusses how this switch from user mode to kernel mode actually occurs.
Important terms:
- system call
- trap
- trap table
- trap handler
Key questions to consider as you read:
- Where does the CPU run after a trap?
- What is the trap handler written in? C? Java?
- What stack does it use?
- Is the work the CPU had been doing before the trap lost forever?
- If not, how does the CPU know how to resume that work?
2 Mode Transfer
- When does the system go from user to kernel mode?
- Interupts
- Processor Exceptions
- Cool example: to set a breakpoint, kernel replaces instruction in memory with special instruction that traps into the kernel. At the point, the kernel will restore the old instruction and transfer control to the debugger.
- System calls (traps)
- When does the system go from kernel to user mode?
- After starting a new process
- Resume after interrupt, exception, or trap
- Context switch
3 Mode Transfer Mechanisms
- Minimum features:
- Limited entry into the kernel
- Atomic changes to processor state
- Transparent, restartable execution
3.1 Interrupt Vector Table
During boot, the system will set up an interrupt vector table the system will use to look up the handler (function) to call when a particular interrupt or trap occurs.
- On x86, 0-31 are for processor exceptions (e.g., divide by zero)
- 32-255 are for interrupts (timer, keyboard, etc.)
- 64 is usually reserved for system call handler
3.2 Kernel Stack
Where should the interrupted process's state be saved? What stack should the kernel code use?
- Just use the user process stack? That's not protected memory, so probably don't want kernel data there
- Solution: allocate two stacks per process, a user stack and a kernel stack
3.3 x86 Mode Transfer
- Mask (disable) interrupts (this delays any interrupts until they are enabled/unmasked—if interrupts are masked for too long they may be lost)
- Save key process state (stack pointer, processor state (
eflags
register), instruction pointer (%rip
)) in temporary hardware registers - Switch to the kernel stack
- Push saved values onto kernel stack
- Optionally save an error code
- Call the interrupt handler
3.4 Implementing System Calls
- User program calls user stub in the normal way
- User stub sets up code for system call and executes
trap
instruction - Hardware transfers control to kernel, using interrupt vector table to jump to the appropriate handler. The handler acts as a stub on the kernel side, copying and checking arguments and then calling the kernel implementation of the system call
- After the system call completes, reutrn to the handler
- Handler returns to user level at the next instruction in the user stub
- The stub returns to the original caller
3.4.1 osv
System Calls
- usyscall.h
- usyscall.S
- syscall-num.h
- syscall.c
4 Signals
User processes can receive their own kind of user-level interrupts, delivered by the kernel. On UNIX-based systems, these are called signals. On Windows, they're asynchronous events. User processes will have handlers for various signals. There would be used from things like asynchronous I/O, user-level exception handling, and interprocess communication. For example, the kill
command on Linux is used to send signals to active processes, such as telling a process to terminate.