How CSM Emulates Legacy BIOS Interrupts in UEFI

The Compatibility Support Module (CSM) is an optional component within Unified Extensible Firmware Interface (UEFI) implementations that allows backward compatibility with legacy operating systems and hardware expansion cards. It enables a modern UEFI platform to emulate a traditional 16-bit PC BIOS environment by recreating legacy memory maps, providing standard interrupt service routines, and utilizing CPU transition mechanisms known as thunking to switch between modern 64-bit/32-bit operating states and 16-bit real mode.

Construction of the Legacy Memory Map

A standard UEFI firmware boots the processor in 32-bit protected mode or 64-bit long mode with flat memory addressing and paging enabled. To satisfy legacy operating systems and Option ROMs, the CSM must carve out and reconstruct the traditional 1 MB IBM PC-compatible memory space:

  • Interrupt Vector Table (IVT): The CSM populates physical memory addresses 0x00000 through 0x003FF with 256 four-byte far pointers (segment:offset), each pointing to specific Interrupt Service Routines (ISRs).
  • BIOS Data Area (BDA): The range 0x00400 to 0x004FF is mapped and initialized with legacy hardware variables, such as serial/parallel port addresses, keyboard buffer pointers, and system timer ticks.
  • Option ROM Space: The region from 0xC0000 to 0xDFFFF is reserved for legacy expansion ROMs (such as legacy video BIOS or network boot ROMs), while 0xE0000 to 0xFFFFF is shadowed to hold the core legacy BIOS code and the system entry points.

Real-Mode Execution and the Thunking Mechanism

Because native UEFI executes in flat protected or long mode, it cannot directly invoke 16-bit real-mode code. The CSM resolves this by implementing a CPU state-switching system called a "thunk."

When the firmware or a legacy driver needs to switch contexts, the CSM thunk layer performs the following sequence:

  1. State Preservation: The CPU registers, control registers (such as CR3 for paging), and descriptor table registers (GDTR, IDTR) are saved in a temporary memory buffer.
  2. Mode Switching: The processor transitions down from 64-bit long mode to 32-bit compatibility/protected mode, disables paging via CR0, and then disables protected mode by clearing the Protection Enable (PE) bit in CR0.
  3. Register Realignment: The CPU segments (CS, DS, ES, SS) are reloaded with 16-bit selector values, and the IDTR is re-pointed to base address 0x00000 with a limit of 0x3FF (the IVT).
  4. Execution: The processor enters true 16-bit real mode and executes the legacy instruction stream or Option ROM.
  5. Restoration: Once execution completes, the thunk code reverses the process: it sets the PE bit, re-enables paging, reloads the 64-bit Global Descriptor Table (GDT), and returns to the UEFI environment.

Emulating Legacy BIOS Interrupts

Legacy operating systems rely heavily on software interrupts (e.g., INT 10h for video, INT 13h for disk access, and INT 16h for keyboard input). The CSM provides handlers for these interrupts in two distinct ways:

  • Native Legacy ISRs: Simple BIOS services, like timer ticks (INT 08h/INT 1Ch) or keyboard buffers (INT 09h/INT 16h), are implemented directly in 16-bit assembly within the shadowed legacy ROM area.
  • Protocol Bridging: For complex operations like disk I/O (INT 13h), the CSM uses a wrapper. When a 16-bit program calls INT 13h, the interrupt handler uses a reverse-thunk mechanism to transition back into 32-bit or 64-bit mode. The CSM maps the legacy drive number to the corresponding UEFI EFI_BLOCK_IO_PROTOCOL or EFI_DISK_IO_PROTOCOL to read or write the physical storage media. Once the UEFI disk operation finishes, the result is translated into standard BIOS return flags (e.g., setting the Carry Flag on failure) and returned to the real-mode caller.

Hardware Interrupt and Controller Emulation

Legacy BIOS environments assume the existence of legacy hardware components that do not natively operate under modern configurations:

  • Interrupt Routing: Standard PC architectures rely on dual Intel 8259 Programmable Interrupt Controllers (PIC). Modern platforms utilize Advanced Programmable Interrupt Controllers (APIC). The CSM configures the chipset and APIC into virtual wire mode or enables legacy PIC compatibility to route hardware interrupts (IRQs 0–15) to their corresponding IVT entries (INT 08h through INT 0Fh and INT 70h through INT 77h).
  • Timer and System Devices: The CSM initializes legacy hardware interfaces, such as the 8254 Programmable Interval Timer (PIT) and standard CMOS Real-Time Clock (RTC), guaranteeing that timekeeping interrupts behave identically to traditional BIOS expectations.

Boot Hand-Off

Once the legacy environment is structured and hardware initialized, the CSM loads the Master Boot Record (MBR) from the selected boot device into memory address 0x07C00. It configures the CPU registers to default real-mode initial states, sets the instruction pointer to 0000:7C00h, and triggers an INT 19h (Bootstrap Loader) call, ceding control entirely to the legacy bootloader.