# How Ventoy Chain-Boots WIM, IMG, and VHD Files Using the VDiskChain Mechanism

> Discover how Ventoy chain boots WIM, IMG, and VHD files via VDiskChain. Ventoy creates an in-memory virtual disk for seamless booting without extraction.

- Repository: [longpanda/Ventoy](https://github.com/ventoy/Ventoy)
- Tags: internals
- Published: 2026-03-01

---

**Ventoy creates an in-memory virtual block device containing a chain header and image chunks, presenting it to firmware as a physical disk so standard bootloaders can boot WIM, IMG, and VHD files without extraction.**

The **ventoy/Ventoy** project enables booting from disk image files without unpackaging them. At the core of this capability lies the **VDiskChain mechanism**, which constructs a virtual disk device that chain-boots Windows Imaging Format (WIM), raw IMG, and Virtual Hard Disk (VHD/VHDX) files. This article examines the source code to explain how Ventoy transforms these file formats into bootable virtual block devices.

## Architecture Overview of the VDiskChain Mechanism

Ventoy does not mount WIM, IMG, or VHD files as loopback devices. Instead, it builds a **virtual block device** composed of a **chain header** (`ventoy_chain_head`) and a series of **image chunks** (`ventoy_img_chunk`). This virtual device is registered with the UEFI firmware via a **Block-IO protocol**, allowing the firmware to treat the memory buffer as a physical disk. Any downstream bootloader—such as the Windows `wimboot` loader, GRUB, or a VHD-boot driver—reads the file exactly as if it were a physical drive.

The process follows three distinct stages:

- **Detection and Preparation**: Parsing the `vdisk=` command line and loading the raw image data.
- **Chain Construction**: Allocating the chain header, filling OS parameters, and mapping image chunks.
- **Block-IO Installation**: Registering the virtual device with the UEFI firmware and launching the boot file.

## Stage 1: Image Detection and Preparation

When a user selects a `.wim`, `.img`, or `.vhd` file, Ventoy parses the command line argument `vdisk=` (or the internal flag set by GRUB commands `vt_load_vhdboot` or `vt_load_wimboot`). The system loads the raw image data into memory through the function `vdisk_get_vdisk_raw`.

In **`EDK2/…/VDiskChain/VDiskChain.c`** (lines 300–340), the `vdisk_parse_cmdline` function extracts the image path. If the image is compressed, `vdisk_decompress_vdisk` handles decompression. For WIM files, `vdisk_patch_vdisk_path` prepares the path string for later injection into the bootloader.

## Stage 2: Building the Chain Header and Image Chunks

The core data structure is **`ventoy_chain_head`**, defined in **[`include/ventoy.h`](https://github.com/ventoy/Ventoy/blob/main/include/ventoy.h)** (lines 17–38). This header stores:

- **OS parameter block**: Used by UEFI for boot services.
- **Disk geometry**: `disk_drive` and `disk_sector_size`.
- **Image metadata**: Real and virtual image sizes.
- **Chunk offsets**: Pointers to `img_chunk`, `override_chunk`, and `virt_chunk` arrays.

In **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c)**, the function `ventoy_alloc_chain` allocates memory for the header plus the chunk array. The function `ventoy_fill_os_param` populates the UEFI OS parameters. The following code snippet from `ventoy_cmd_load_wimboot` illustrates this construction:

```c
/* ventoy_cmd.c – part of vt_load_wimboot */
grub_err_t ventoy_cmd_load_wimboot (grub_extcmd_context_t ctxt,
                                   int argc, char **args)
{
    /* args[0] = path to the WIM file */
    grub_file_t file = ventoy_grub_file_open (VENTOY_FILE_TYPE, "%s", args[0]);

    /* Build the chain header */
    size_t img_chunk_size = g_img_chunk_list.cur_chunk * sizeof (ventoy_img_chunk);
    size_t chain_size     = sizeof (ventoy_chain_head) + img_chunk_size;
    ventoy_chain_head *chain = ventoy_alloc_chain (chain_size);

    /* Fill OS parameter and geometry */
    ventoy_fill_os_param (file, &(chain->os_param));
    chain->disk_drive        = file->device->disk->id;
    chain->disk_sector_size  = (1 << file->device->disk->log_sector_size);
    chain->real_img_size_in_bytes = file->size;
    chain->img_chunk_offset  = sizeof (ventoy_chain_head);
    chain->img_chunk_num     = g_img_chunk_list.cur_chunk;
    memcpy ((char *)chain + chain->img_chunk_offset,
            g_img_chunk_list.chunk, img_chunk_size);

    /* Export the chain address to the VDisk driver */
    ventoy_memfile_env_set ("vtoy_chain_mem", chain, (ulonglong)chain_size);
    grub_env_export ("vtoy_chain_mem_addr");
    return GRUB_ERR_NONE;
}

```

**Override chunks** enable on-the-fly patching. For example, Ventoy injects the `wimboot` binary into a WIM file by creating an override chunk that patches the original image to reference the injected loader.

## Stage 3: Virtual Block Device Installation

Once the chain is built, the UEFI-side driver installs the virtual block device. In **[`VDiskChain.c`](https://github.com/ventoy/Ventoy/blob/main/VDiskChain.c)**, the function `vdisk_install_blockio` (lines 449–452) registers a **Block-IO protocol** and a **Device-Path protocol** with the firmware.

```c
/* VDiskChain.c – called from VDiskChainEfiMain */
EFI_STATUS EFIAPI vdisk_install_blockio (EFI_HANDLE ImageHandle,
                                         UINT64 ImgSize)
{
    gVDiskBlockData.Media.BlockSize = 512;
    gVDiskBlockData.Media.LastBlock = (ImgSize / 512) - 1;
    gVDiskBlockData.Media.ReadOnly  = TRUE;

    /* Register the BlockIo and DevicePath protocols */
    return gBS->InstallMultipleProtocolInterfaces (
                 &gVDiskBlockData.Handle,
                 &gEfiBlockIoProtocolGuid,   &gVDiskBlockData.BlockIo,
                 &gEfiDevicePathProtocolGuid,gVDiskBlockData.Path,
                 NULL);
}

```

After installation, `vdisk_boot` searches for standard EFI boot files (`bootx64.efi`, `grubx64.efi`) on the virtual disk and launches them via `gBS->StartImage`. When the OS hands over control, Ventoy disconnects and uninstalls the virtual device.

## Image-Type Specific Implementation

The VDiskChain mechanism adapts its behavior based on the file extension and content type.

### WIM Files and wimboot Integration

For **WIM** files, Ventoy uses the **wimboot** loader (located in the `wimboot/wimboot-2.7.3/src/` directory). The chain contains a VDisk-image of the `wimboot` binary plus an **override chunk** that patches the original WIM to reference `wimboot`. The function `vdisk_patch_vdisk_path` searches for the marker `0x59595959` (the string `YYYY…Y` inside wimboot) and overwrites it with the actual WIM path:

```c
/* VDiskChain.c – vdisk_patch_vdisk_path */
STATIC EFI_STATUS vdisk_patch_vdisk_path (CHAR16 *pos)
{
    /* The command line contains:  vdisk=... .vtoy   */
    CHAR16 *end = StrStr (pos, L".vtoy");
    end += 5;                       /* skip ".vtoy" */
    CHAR8 *buf = (CHAR8 *)g_disk_buf_addr;

    /* Locate the 32‑byte marker "YYYY...Y" and replace the
       placeholder with the real WIM path. */
    for (UINTN i = 0; i < g_disk_buf_size; ++i) {
        if (*(UINT32 *)(buf + i) == 0x59595959) {     /* "YYYY" */
            CopyMem (buf + i, pos, (end - pos) * sizeof(CHAR16));
            break;
        }
    }
    return EFI_SUCCESS;
}

```

When the virtual disk boots, the firmware loads `wimboot`, which extracts the Windows image and hands control to `bootmgr.exe`.

### Raw IMG Files

For **IMG** files, Ventoy presents the raw disk image directly without additional loaders. The first sector of the IMG typically contains a bootloader (such as SYSLINUX or GRUB) that executes directly from the virtual block device.

### VHD and VHDX Files

For **VHD/VHDX** files, Ventoy uses **vhdboot** implemented in **[`ventoy_vhd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_vhd.c)**. The code parses the VHD footer, builds the partition table in memory, and patches the boot sector so the firmware can start Windows directly from the virtual hard disk. The chain holds the VHD file as a virtual block device, with override chunks fixing the BCD file and boot sector prior to handoff.

## Key Source Files in ventoy/Ventoy

| File | Role |
|------|------|
| **`EDK2/…/VDiskChain/VDiskChain.c`** | Core UEFI driver: parses `vdisk=` command line, decompresses VDisk payload, patches paths, installs Block-IO and Device-Path protocols, and boots the first EFI file. |
| **`EDK2/…/VDiskChain/VDiskChain.h`** | Declarations for the driver-side API including `vdisk_install_blockio` and `vdisk_get_vdisk_raw`. |
| **`EDK2/…/VDiskChain/VDiskRawData.c`** | Stub replaced at runtime with raw `wimboot`/`vhdboot` binary data (the VDisk payload). |
| **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c)** | GRUB command implementation (`vt_load_wimboot`, `vt_load_vhdboot`, `ventoy_raw_chain_data`) that allocates and populates `ventoy_chain_head`. |
| **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c)** | VHD-specific handling: parses VHD footer, builds override chunks, and creates chains for VHD boot. |
| **`wimboot/wimboot-2.7.3/src/*`** | The `wimboot` loader source code used for WIM image extraction and boot. |
| **[`include/ventoy.h`](https://github.com/ventoy/Ventoy/blob/main/include/ventoy.h)** | Shared structure definitions (`ventoy_chain_head`, `ventoy_img_chunk`, `ventoy_override_chunk`) used by both bootloader and VDisk driver. |

## Summary

- **VDiskChain** creates a virtual block device in memory, eliminating the need to extract WIM, IMG, or VHD files to physical media.
- The **`ventoy_chain_head`** structure manages disk geometry, OS parameters, and pointers to image chunks stored in memory.
- **Block-IO protocol installation** in [`VDiskChain.c`](https://github.com/ventoy/Ventoy/blob/main/VDiskChain.c) registers the virtual device with UEFI firmware, enabling standard boot file loading.
- **Override chunks** allow runtime patching—for example, injecting `wimboot` into WIM files or fixing VHD boot sectors—before the OS takes control.
- The implementation spans both GRUB modules ([`ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_cmd.c)) and UEFI drivers ([`VDiskChain.c`](https://github.com/ventoy/Ventoy/blob/main/VDiskChain.c)), with image-specific logic in [`ventoy_vhd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_vhd.c) and the `wimboot` sub-project.

## Frequently Asked Questions

### What is the VDiskChain mechanism in Ventoy?

The **VDiskChain mechanism** is Ventoy's method for booting disk image files by constructing an in-memory virtual block device. It combines a chain header (`ventoy_chain_head`) with image chunks and registers the result as a UEFI Block-IO device, allowing the firmware to boot WIM, IMG, and VHD files as if they were physical disks.

### How does Ventoy boot WIM files without extracting them?

Ventoy injects the **wimboot** loader into the WIM file using an override chunk. The `vdisk_patch_vdisk_path` function patches the wimboot binary with the actual WIM path, then registers the combination as a virtual disk. When booted, wimboot mounts the WIM internally and launches Windows, all without extracting the image to the USB drive.

### What is the difference between IMG and VHD handling in VDiskChain?

**IMG** files are passed through as raw disk images—their first sector contains a bootloader that executes directly. **VHD/VHDX** files require additional processing: Ventoy parses the VHD footer, constructs a partition table in memory, and patches the boot sector via [`ventoy_vhd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_vhd.c) before presenting the virtual disk to the firmware.

### Which source files contain the VDiskChain implementation?

The core implementation resides in **`EDK2/…/VDiskChain/VDiskChain.c`** (UEFI driver) and **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c)** (GRUB module). Structure definitions are in **[`include/ventoy.h`](https://github.com/ventoy/Ventoy/blob/main/include/ventoy.h)**, while VHD-specific logic is in **[`ventoy_vhd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_vhd.c)**. The `wimboot` loader source is located in **`wimboot/wimboot-2.7.3/src/`**.