3: Context Switch

*User to kernel Mode Switch

There are three conditions will trigger switch.

  1. Exceptions: When the processor encounters unexpected condition like illegal memory access, divide-by-zero (in C), perform privileged instructions.
  2. Interrupts: Asynchronous signal to the processor that some external event has occurred that requires its attention, like timer interrupts, I/O requests such as mouse movement.
  3. System calls: User processes requests the kernel do som operation on the user’s behalf, like R/W files, creating new processes, network connections.

What types of these user-to-kernel switch are they?

  • inter-processor interrupt(IPI)
  • invalid opcode
  • segmentation fault
  • network card interrupt
  • divide-by-zero in python/java
    • exception from interpreter (not processor)

Interrupt Vector Table

Interrupt vector table stores the entries of different handlers for exceptions, interrupts, and traps in real mode.

There is a special register that point to the vector (array) in kernel memory, where each entry points to the first instruction of a different handler procedure in the kernel.

In x86, there are \(256\) entries in total. Each takes \(4\) bytes.

Old.

Interrupt Descriptor Table

Interrupt descriptor table tells CPU where the interrupt service routines are located.

Location calls entry, also called gate. There are \(256\) gates in total. Each gate is \(8\)-bytes long on \(32\)-bit processors; or \(16\)-bytes long on \(64\)-bit processors. Its location is kept in IDT register(IDTR), loaded with LIDT assembly instruction.

用户态到内核态只能经过这 \(256\) 个门

The following table is gate descriptor(32-bit) structure:

bits name
0 ~ 15 Offset
16 ~ 31 Segment Selector
32 ~ 39 Reserved
40 ~ 43 Gate Type
44 0
45 ~ 46 DPL
47 P
48 ~ 63 Offset
  • Offset: A 32-bit value, split in two parts, represents the address of the interrupt service routine.
  • Selector: A segment selector which must point to a valid code segment in your GDT (Global Descriptor Table).
  • Gate Type: A 4-bit value which defines the type of gate this interrupt descriptor represents.
  • DPL: A 2-bit value which defines the CPU privilege levels which are allowed to access this interrupt via the INT (Interrupt Instruction).
  • P: Present bit. Must be set 1 for the descriptor to be valid.

Why offset is split into two parts? For compatibility.

特性 IVT IDT
用途 实模式中断向量表 保护模式/长模式中断描述符表
存储位置 固定在 0x0000 到 0x03FF 动态位置,由 IDTR 指定
条目大小 \(4\) 字节 \(8\) 字节(\(32\) 位)或 \(16\) 字节(\(64\) 位)
条目内容 中断处理程序的入口地址 描述符(包含段选择器、偏移地址等)
支持的模式 实模式 保护模式、长模式
Table 1: Comparison between IVT and IDT

IVT 是早期的简单实现,而 IDT 是现代操作系统中更灵活和安全的中断处理机制。

interrupt procedure
Figure 1: Interrupt procedure

Interrupt Masking

There are two kinds of interrupts:

  • Maskable interrupts: all software interrupts, all system calls, and partial hardware exceptions.
  • Non-Maskable interrupts: partial hardware exceptions.
  • Specified by eflags registers.

Disable interrupts and enable interrupts. Both of them are privileged instructions.

Masked interrupts are deferred, but not ignored. Given the limited buffer for interrupts, hardware buffers one interrupt of each type.

*Interrupt Stack

Interrupt stack is a special stack in kernel memory that saves interrupt process status. Empty when there is no interrupt (running in user space).

  1. Why not directly use the user-space stack?

    For reliability and security

  2. How many interrupt stack in kernel?

    Kernel need to allocate each thread a interrupt stack

  • First fault: trap from user-space program to kernel-space exception handler.
  • Double fault: trap from exception handler to another handler.
  • Triple fault: reboot.

Kernel to User Mode Switch

  • New process

    When a new process is created (e.g., via fork and exec in Unix-like systems), the kernel initializes its context and then switches to user mode to start executing the user program.

  • Resume after an interrupt/exception/syscall

    After handling an interrupt, exception, or system call, the kernel restores the user process’s context and returns to user mode so the process can continue execution from where it was interrupted.

  • Switch to a different process

    The kernel may decide to switch to another process (context switch), often triggered by a timer interrupt (preemptive multitasking) or when the current process is blocked (e.g., waiting for I/O). The kernel saves the current process’s state and restores the next process’s state before switching to user mode.

  • User-level upcall

    Sometimes, the kernel needs to notify a user process of an event (such as asynchronous I/O completion or signals). This is done via a user-level upcall, where the kernel arranges for a specific user-mode handler to be invoked.

Upcalls allow apps to implement OS-like functionality to be invoked by OS.

  1. Asynchronous I/O notification, like waiting for I/O completion.

  2. Inter-process communication, such as debugger suspends a process.

  3. User-level exception handling, like ensuring files saved before app shuts down.

  4. User-level resource allocation, such as Java garbage collection.

*x86 Example

x86 Background

  • Memory is segmented, so pointers come in two parts: a segment and an offset.
    • program counter: cs register and eip register
    • stack pointer: ss register and esp register
    • CPL is stored as the \(2\) lower-bit of cs register
  • In Intel 8086: cs:eip = cs \(\times 16 +\) eip
    • both cs and eip are \(16\)-bits long, therefore CPU can access at most \(1\) MB memory space
  • eflags register stores the processor status and controls its behavior. Whether interrupts are masked or not.
  • Only a small number of instructions can change the cs register value
    • ljmp (far jump)
    • lcall (far call), which pushes eip and cs to the stack, and then far jumps
    • lref (far return), which inverses the far call
    • INT: an assembly languages instruction for x86 processors that generates a software interrupt. It takes the interrupt number formatted as a byte value. Which read cs/eip from the IVT
    • IRET: returns program control from an exception or interrupt handler to a program or procedure that was interrupted previously

x86 transfer

When an interrupt/exception/syscall occurs, the hardware will:

  1. mask interrupts
  2. save the special register values to other temporary registers
  3. switch onto the kernel interrupt stack
  4. push the three key values onto the new stack
  5. optionally save an error code
  6. invoke the interrupt handler (CPL changed!)
before interrupt
Figure 2: Before interrupt
at the beginning of handler
Figure 3: At the beginning of handler

Then the OS will:

  1. save the rest of the interrupted process’s state
    • pusha/ pushad
  2. execute the handler
  3. resume the interrupted process
    • popa/popad \(+\) pop error cod
  4. resume the interrupted process
    • iret (kernel mode to user mode)
during interrupt handler
Figure 4: During interrupt handler

Recap

(1). Define three types of user-mode to kernel-mode transfers.

(2). Define four type of kernel-mode to user-mode transfers.

(3). Most hardware architectures provide an instruction to return from an interrupt, such as iret. This instruction switches the mode of operation from kernel-mode to user-mode.

  1. Explain where in the operating system this instruction would be used.
  2. Explain what happens if an application program executes this instruction.

3: Context Switch
https://ddccffq.github.io/2025/11/18/操作系统/Context_Switch/
作者
ddccffq
发布于
2025年11月18日
许可协议