-
Notifications
You must be signed in to change notification settings - Fork 24
How CSMWrap Works
Farel Reski Aditiya edited this page Jun 1, 2025
·
1 revision
CSMWrap bridges the gap between a modern UEFI environment and the requirements of a legacy BIOS by performing a series of setup steps before handing control to a legacy operating system.
-
Initialization:
- Sets up basic EFI services (console output via
printf.c). - Allocates a private data structure (
struct csmwrap_priv) to store state.
- Sets up basic EFI services (console output via
-
Hardware/Firmware Checks & Setup:
-
Legacy Region Unlocking (
unlock_region.c): This is a critical step. The memory range 0xC0000-0xFFFFF (Option ROM and UMA area) must be made writable.- It first attempts to use
EFI_LEGACY_REGION2_PROTOCOL. - If the protocol is unavailable or fails, it falls back to chipset-specific methods:
- Intel chipsets: Modifies PAM (Programmable Attribute Map) registers via PCI configuration space (e.g., for PIIX4, Q35, Skylake+).
- AMD chipsets: Modifies MTRRs (Memory Type Range Registers) to make the region write-back.
- It first attempts to use
-
Video Initialization (
video.c):- Identifies the active PCI VGA device, often by locating the EFI Graphics Output Protocol (GOP) provider.
- Sets up the
cb_framebufferstructure (part of the Coreboot table) with information from EFI GOP (resolution, framebuffer address, color depth). This information is used by SeaVGABIOS. - Decides whether to use the embedded SeaVGABIOS or try to load an Option ROM from the GPU.
-
ACPI Initialization (
acpi.c):- Initializes the uACPI library.
- Locates the RSDP (Root System Description Pointer) provided by the UEFI firmware. This RSDP will be passed to the legacy environment.
- SMBIOS Table: The physical address of the SMBIOS table from UEFI is stored and later passed to the CSM.
-
E820 Memory Map (
e820.c):- Calls UEFI
GetMemoryMap()to get the current memory layout. - Converts UEFI memory types to E820 types.
- Populates an E820 map, reserving space for the low stub, EBDA, and Option ROMs. This map is stored in the low stub area.
- Calls UEFI
-
Coreboot Table (
coreboot.c):- Builds a Coreboot-compatible parameter table in low memory. This table includes:
- Memory ranges.
- Serial port configuration (if any, usually stubbed).
- Framebuffer information (from
video.c). - ACPI RSDP pointer.
- SMBIOS entry point.
- CBMEM (Coreboot Memory) console (if logging via CBMEM is enabled).
- Builds a Coreboot-compatible parameter table in low memory. This table includes:
-
Legacy Region Unlocking (
- A block of conventional memory (below 1MB, typically starting at 0x00000) is allocated or reserved. This "low stub" area is crucial for the 16-bit environment.
- It contains:
- The SeaBIOS CSM binary (
Csm16.binfromsrc/bins/Csm16.h, relocated here). - The SeaBIOS VBIOS binary (
vgabios.binfromsrc/bins/vgabios.h, placed typically at 0xC0000 after shadowing). - The generated E820 memory map.
- The Coreboot table.
- Space for the CSM's BDA (BIOS Data Area) and EBDA (Extended BIOS Data Area).
- A small 16-bit thunking mechanism (
Thunk16.asm*,x86thunk.c) to transition between UEFI's protected/long mode and the CSM's 16-bit real mode. - Space for the CSM's runtime stack.
- The SeaBIOS CSM binary (
-
Intel Platform Workarounds (
intel_workarounds.c): Applies specific workarounds, such as disabling the 8254 PIT Programmable Interval Timer's "Gate Enable" (8254CGE) on certain Intel chipsets to prevent conflicts. -
Thunking to CSM:
- The
EFI_LEGACY_BIOS_PROTOCOLequivalent functions are invoked using the 16-bit thunk. - The primary function called is
Compatibility16InitializeYourself(or its modern equivalent name in SeaBIOS CSM). This function withinCsm16.bin:- Initializes legacy hardware (PIC, PIT, DMA controllers).
- Sets up interrupt vectors.
- Scans for and initializes Option ROMs (including the VBIOS at 0xC0000).
- Builds the BBS (BIOS Boot Specification) table.
- The
-
Video Option ROM / SeaVGABIOS:
- If a GPU Option ROM is used, it's loaded and executed.
- If SeaVGABIOS is used, it's copied to 0xC0000 and initialized. It uses the framebuffer information from the Coreboot table to set up a VBE (VESA BIOS Extensions) compatible display mode.
-
Preparing for ExitBootServices:
- ACPI tables are finalized for handoff (
acpi_prepare_exitbs). - UEFI video output via GOP might be disabled if SeaVGABIOS has taken over.
- ACPI tables are finalized for handoff (
-
Exiting Boot Services:
-
ExitBootServices()is called. This terminates all UEFI runtime services except for a minimal set (like reset/shutdown, GetTime, SetVariable if persistent). - CSMWrap takes full control of the hardware.
-
-
Final Legacy Setup:
- External interrupts are disabled.
- The 8259 PIC is programmed to its default legacy state.
- The PIT is programmed to its default legacy state.
-
Legacy Boot:
- The CSM's
Compatibility16Bootfunction (or equivalent) is called via thunk. - This function typically performs an INT 19h (System Bootstrap) to load the boot sector from the highest priority device in the BBS table.
- The CSM's
-
Csm16.bin(from SeaBIOS, embedded insrc/bins/Csm16.h): The core Compatibility Support Module. It handles most of the legacy BIOS emulation, Option ROM scanning, and boot device management. -
vgabios.bin(from SeaBIOS, embedded insrc/bins/vgabios.h): A VESA-compliant VBIOS. It provides INT 10h video services. -
Thunk16.asm32/Thunk16.asm64andx86thunk.c: Code responsible for transitioning the CPU between UEFI's native mode (32-bit protected or 64-bit long mode) and the 16-bit real mode required by the CSM. -
uACPI (
uACPI/submodule): A lightweight ACPI library used to parse and manage ACPI tables. -
Nyu-EFI (
nyu-efi/submodule): Provides a minimal C runtime, EFI headers, and the linker script for building UEFI applications.
This steps allows CSMWrap to create an environment where legacy operating systems believe they are running on a traditional BIOS-based machine.