Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Patina DXE Core Release Binary Composition and Size Optimizations

This document is a reference for the current set of size-related optimizations performed on the Patina DXE Core release binary.

TL;DR

Summary of the current status of the QEMU DXE Core binary size, marking the logical conclusion of the size optimization efforts:

  1. Rust compiler size related optimizations (Applied)
  2. Disabling logging can save an additional 150 KB (Not Applied)
  3. Defaulting to UEFI decompression in the section extractor while skipping Brotli and CRC32 can save another 150 KB (Not Applied)
  4. Excluding Patina debugger support saves another 55 KB (Not Applied)

Bringing the size from 1,162 KB to 406 KB (a reduction of 65%). The details are documented below.

1. Common Rust Compiler Optimizations Focused on Reducing Binary Size

Optimization Status: Applied

[profile.release]
codegen-units = 1               # Default is 16; setting it to 1 prioritizes size over compilation speed.
debug = "full"
lto = true                      # Enables Link Time Optimization - significant size reduction.
opt-level = "s"                 # Optimize for size - significant size reduction.
split-debuginfo = "packed"
strip = "symbols"               # Remove symbol information from the final binary (not very relevant for PE files).
incremental = true

Below is the composition of the Patina DXE Core release binary for QEMU, located at target\x86_64-unknown-uefi\release\qemu_q35_dxe_core.efi. This represents the final binary after applying the non-destructive compiler optimizations outlined in PR #19:

SegmentSize on Disk
.text495.0 KB
.rdata249.5 KB
.data3.0 KB
.pdata11.0 KB
miscellaneous4.0 KB
Total762 KB

Results: 1,162 KB down to 762 KB (a reduction of approximately 35%).

2. Logging: Reducing Binary Size by Disabling Logging

Optimization Status: Not Applied

The other substantial reduction in the release binary size is observed when logging is completely disabled, as shown below in \patina-dxe-core-qemu\Cargo.toml using release_max_level_off.

[dependencies]
log = { version = "^0.4", default-features = false, features = ["release_max_level_off"] }

Results: 762 KB to 599 KB (a reduction of approximately 160 KB (21%)).

3. Decompression: Reducing Binary Size by Defaulting to UEFI Decompression

Optimization Status: Not Applied

Defaulting to UEFI decompression in the section extractor while skipping Brotli and CRC32 can save another 140 KB.

[dependencies]
patina_section_extractor = { version = "4", registry = "patina-fw", default-features = false, features = ["uefi_decompress"] }

Results: 599 KB to 460 KB (a reduction of approximately 140 KB (23%)).

4. Debugger: Reducing Binary Size by Excluding Debugger Support

Optimization Status: Not Applied

Excluding debugger support can save another 55 KB. This reduces the size from 460 KB to ~406 KB.

#![allow(unused)]
fn main() {
// Commenting below lines will exclude debugger support
static DEBUGGER: patina_debugger::PatinaDebugger<Uart16550> =
    patina_debugger::PatinaDebugger::new(Uart16550::Io { base: 0x3F8 })
        .with_force_enable(false)
        .with_log_policy(patina_debugger::DebuggerLoggingPolicy::FullLogging);

    patina_debugger::set_debugger(&DEBUGGER);
}
[dependencies]
# Commenting below line will exclude debugger support
# patina_debugger = { version = "4", registry = "patina-fw" }

Results: 460 KB to 406 KB (a reduction of approximately 55 KB (11%)).

Release Binary Size After Above Optimizations

C:\r\patina-dxe-core-qemu>dir C:\r\patina-dxe-core-qemu\target\x86_64-unknown-uefi\release\qemu_q35_dxe_core.efi
 Volume in drive C has no label.
 Volume Serial Number is 40DF-F702

 Directory of C:\r\patina-dxe-core-qemu\target\x86_64-unknown-uefi\release

06/24/2025  04:53 PM           406,528 qemu_q35_dxe_core.efi
               1 File(s)        406,528 bytes
               0 Dir(s)  183,428,534,272 bytes free

Project MU vs Patina FV Size Comparison

Up to this point, we have seen what constitutes the Rust DXE Core binary and how it can be optimized. This section performs a platform image-level comparison between a C-based UEFI firmware image and a Rust-based Patina UEFI firmware image. There are many components that differ between the C-based UEFI and the Rust-based UEFI images. Below is a summary of the components that have been folded into the Rust DXE Core. On the left is the size represented by the Project MU-based QEMU FV file (DxeCore, RuntimeDxe, CpuDxe), and on the right the size represented by the Patina FV file (DxeCore).

ModuleMuPatina
DxeCore0x2EC3E (188.0 KB)0x63430 (405.0 KB)
RuntimeDxe0x206E (8.1 KB)
CpuDxe0x19266 (100.2 KB)
TOTAL0x49F12 (296.3 KB)0x63430 (405.0 KB)

The Rust binary includes the following additional features that are not available in the C-based UEFI image, with a size increase of approximately 110 KB compared to the C-based image:

  • Functionality that is typically split across multiple EFI binaries (DxeCore, RuntimeDxe, CpuDxe) in C-based implementations.
  • Advanced features such as built-in source-level debugging capabilities.
  • Two dispatchers: pure Rust component dispatch and FFS dispatch.
  • Stringent memory protection features not present in most C-based DXE Core implementations.