Interrupts

Subpage of Operating Systems

Diving deep into the design and structure of Operating Systems.

Interrupts are signals sent from hardware to the CPU, causing it to stop its current execution and jump to an interrupt handler in the kernel. Interrupts are asynchronous – they happen at any time, independent of the running thread.

An interrupt controller is a hardware component that manages interrupt signals from peripherals, prioritizing them and presenting them to the processor to enable efficient, non-polling, real-time multitasking. It acts as an intermediary, routing multiple device requests to the CPU and identifying the appropriate Interrupt Service Routine (ISR) via a vector table.

In short, the interrupt controller:

  • Collects interrupts from devices (timer, keyboard, disk, network).
  • Prioritises them.
  • Delivers them to the appropriate CPU core.

Handling Interrupts

When an interrupt arrives:

  1. The CPU finishes the current instruction (or stops at a safe boundary).
  2. It flushes the pipeline (discards partially executed instructions).
  3. It saves a minimal state (often just the program counter and some flags) onto the kernel stack.
  4. It jumps to the interrupt handler in the kernel (entering kernel mode). This is effectively a forced context switch, but it’s not a full thread switch yet.
  5. The interrupt handler does its work (e.g., marks a thread as ready).
  6. After the handler finishes, the kernel may decide to call the scheduler. The kernel can then context switch to a different thread.

Crucially, the interrupt handler itself runs in kernel mode, but it is not a thread – it’s a small, fast piece of code that either does minimal work or delegates longer work to kernel threads (bottom halves / tasklets).

Task State Segment (TSS)

The Task State Segment (TSS) in x86 is a specialized hardware-supported structure that stores task context and manages stack switching during interrupts or privilege changes. While modern operating systems often bypass hardware task switching in favor of software-based approaches, the TSS remains crucial for handling privilege-level transitions and certain fault conditions.

The TSS itself is a privileged data structure in x86 architecture that stores the complete state of a task (registers, stack pointers, segment selectors, flags, etc.).

There are different types of task switching we may see:

  1. Hardware Task Switching (Protected Mode)
    • Each task has its own TSS.
    • On a switch (via CALL, JMP, or interrupt gates), the CPU saves the current task’s state into its TSS and loads the new task’s state from another TSS.
    • This includes general-purpose registers, instruction pointer (EIP), flags, and stack pointers.
  2. Privilege-Level Stack Switching
    • The TSS contains separate stack pointers (SS0:ESP0, SS1:ESP1, SS2:ESP2) for each privilege level.
    • When an interrupt or system call moves execution from user mode (Ring 3) to kernel mode (Ring 0), the CPU automatically switches to the kernel stack defined in the TSS.
    • This prevents user-mode code from corrupting kernel stacks and enforces isolation.
  3. Long Mode (x86-64)
    • Hardware task switching is not supported.
    • The TSS instead provides an Interrupt Stack Table (IST), which defines alternate stacks for specific exceptions (e.g., double faults).
    • This ensures stability when the normal stack is corrupted.

The design of the TSS ensures the following:

  • Automatic Context Management: Early OS designs relied on hardware to simplify multitasking. The TSS allowed the CPU to handle context switches without complex software routines.
  • Security: By embedding privilege-level stack pointers, the TSS enforces strict separation between user and kernel stacks.
  • Fault Handling: The IST in x86-64 ensures reliable recovery from catastrophic errors like double faults.

However, modern OSes (Linux, Windows) avoid hardware task switching due to inefficiency and lack of flexibility. Instead, they implement software-based context switching, but still rely on the TSS for:

  • Privilege-level stack switching
  • Handling double faults and critical exceptions

/ Continue

Follow the technical trail.

Use the dense notes as the source material, then move through the guided route, writing, or project proof when you want a cleaner entry point.