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

Open Device Partnership (ODP) documentation

This document will briefly review the value proposition of ODP and why it is the right technology for the future of firmware development, at the right time.

Welcome to ODP!

ODP is a community-driven framework for building secure, modular, and reusable firmware components across a range of systems. Whether you’re interested in low-level boot firmware, embedded controller services, or integrating a complete firmware stack, ODP has something for you.

What is ODP?

ODP brings modern software engineering practices—like memory safety and dependency injection—to the world of firmware. It leverages Rust to improve confidence, maintainability, and modularity across diverse hardware and system designs.

It also embraces existing standards like UEFI, DICE, ACPI, and EC protocols—but makes them more accessible and safer to implement.

ODP projects

Patina (boot firmware) provides a UEFI compatible firmware interface written in the Rust language with a focus on memory safety and composition. Compatible with current UEFI device drivers and loaders but with a focus on the future. Patina documentation is covered in the Patina Book.

Secure Embedded Controller (EC) provides modern EC firmware written in Rust. Designed for safety and composability, it serves as a foundational layer for secure device management. Secure EC documentation is covered in the Secure Embedded Controller Book.

Unified Embedded Controller Services provides modern EC services firmware written in Rust. Designed for safety and composability, it serves as a foundational layer for secure EC services on Windows platforms. EC services documentation is covered in the Embedded Controller Services section of the Secure EC Book.

Why ODP?

Modern computing devices are ubiquitous in our current time. They are integral to multiple aspects of our lives, from our workplace, to our finances, our creative endeavors, and our personal lifestyles.

Computer technology seemingly leapt from its cradle a half century ago and never slowed its pace. It is easy to take much of it for granted.

We marvel as the new applications show us increasingly amazing opportunities. We also recognize and guard against the threats these applications pose to ourselves and society.

And in this heady environment, it is sometimes easy to forget that the “hidden parts” of these computers we use – the lower-level hardware and firmware – is often built upon languages and processes that, although having evolved to meet the demands of the time, are reaching the end of their practical sustainability for keeping up with the accelerating pace of the world around us.

What was originally just a “boot layer” and a few K of code for key hardware interfacing is now shouldering the responsibility of securing personal information and behavior patterns that a malicious intruder could use for nefarious purposes.

High-value proprietary algorithms and Artificial Intelligence models are now built into the firmware and must be locked down. An increasing number of “always ready” peripherals, such as the battery and charger, biometric identification mechanisms, network connections, and other concerns are being increasingly handled by independent MCUs that must coordinate with one another and with the host system in a responsive, increasingly complex, yet highly secure manner.

Trying to manage all of this with what has been the status-quo for these concerns in past decades, without memory-safe languages and with a loosely-federated collection of standards and patterns agreed upon by an ad-hoc consortium of vendors is increasingly dangerous and costly.


Legacy ApproachODP Approach
🐜 Many vendor-specific changesets ❌🧩 Cross-platform modularity 🔒
❄️ Weak component isolation 🩸🔐 Secure runtime services 🤖
🔩 Proprietary tool building ⚔️🛠️ Rust-based build tools, Stuart 🧑‍🔧

The firmware we once almost ignored is now the front line of platform security


The Open Device Partnership offers an alternative and a way forward to a more sustainable future that, while still built upon the proven paradigms of the past, boldly rejects the patterns that are known to be costly and ineffective in favor of future-ready, portable, sustainable, and expandable alternatives.

Key to this is the adoption of the programming language Rust as the successor to C. This immediately brings greater confidence that the code will not be susceptible to programming-error related vulnerabilities that may lead to either costly performance behaviors or be maliciously exploited by opportunistic bad actors. Code may be marked unsafe to allow certain difficult-to-static-analyze behaviors that can be asserted to be risk-free, so potentially dangerous area must be carefully justified. Furthermore, the patterns adopted by ODP provides the confidence that code from outside of one’s immediate provenance of control may be audited and trusted and ready to join into a firmware construction built upon industry standards.

In the pages ahead, we’ll look a little more closely at the advantages of ODP one at a time.

Security

Reduce firmware attack surface significantly, and meet modern security expectations using proven tools and patterns.

Security and Trustworthiness from the Ground Up

“If the foundation is weak, nothing built on top can be trusted.”

Rust is a modern, memory-safe language that mitigates entire classes of vulnerabilities endemic to C memory management, buffer overflows, use-after-free, and so forth by detecting and addressing these issues at compile time – so there are few, if any, unpleasant surprises at runtime.

ODP is foundationally centered around Rust and not only embraces these philosophies, it defines patterns that further enhance the memory-safe paradigm, by preventing unauthorized access between ownership domains and guarding against possible malicious intrusions while implementing proven industry-standard patterns.

flowchart LR
  Start[Power On] --> ROM
  ROM --> FirmwareCheck[Validate Firmware Signature]
  FirmwareCheck --> DXECore[Load DXE Core]
  DXECore --> OSLoader[Invoke Bootloader]
  OSLoader --> OSVerify[Validate OS Signature]
  OSVerify --> OSBoot[Launch OS]
  OSBoot --> Ready[Platform Ready]

Adoption of standards and patterns of DICE and EL2 Hypervisor supported architectures – from a Rust-driven baseline - enables a hardware-rooted chain of trust across boot phases, aligning with NIST and platform security goals and requirements.

ODP makes component modularity and portability with a transparent provenance a practical and safe proposition by making it feasiable to audit and verify firmware behavior in specifically constrained ways.

Modular and Composable Firmware Architecture

ODP offers Modularity and Agility not normally found in the firmware domain.

The buzz and the headlines generated by advances in the computer world typically belong to those who have created magic at the application layer. As such, this portion of the development community has seen exponential advances in the tooling and languages at their disposal. This has provided a high level of modularity and with it, agility, that has become synonymous with the market responsiveness we see in the evolution of our favorite applications.

Firmware development, on the other hand, has generally been mired in the processes of the past, and has not enjoyed this same level of modularity and agility.

“Systems scale better when their parts can evolve independently.”

Composable and portable component modules

ODP changes that paradigm and raises the tide. It is inspired by modern software engineering practices: composability, dependency injection, testability.

Components (e.g., battery service, serial logging, boot policies) are decoupled and swappable, enabling faster iteration and better maintainability.

graph LR
  PowerPolicy --> BatteryService
  PowerPolicy --> ChargerService
  PowerPolicy --> ThermalService
  BatteryService --> BatteryController
  ChargerService --> SMbusDriver

Because Rust enforces its memory and safety management guarantees at compile time, tooling such as that found in ODP Patina for example will build a DXE Core monolithically, without the need for an RTOS, and supports a composed modularity paradigm by design, streamlining certification and troubleshooting.

Cross-Domain Coherence

ODP is not just a patch atop of old layers. It is explicitly aligning system layers to reduce duplication, ambiguity, and failure points.

ODP is not just a firmware stack, but a vision that unites the embedded controller, main firmware, and even secure services under a coherent design and tooling approach.

Common patterns with clearly defined lanes

“Secure systems require secure interfaces — everywhere.”

Shared services and conventions allow clear division of responsibility between firmware, EC, and OS—while promoting reuse and coordination.

graph LR
    Host[Host Domain] --> HostServiceA
  Host --> HostServiceB

  HostServiceA --> HostDriverA
  HostServiceB --> HostDriverB

  EC[Embedded Controller Domain] --> ECServiceA
  EC --> ECServiceB

  subgraph Shared Interface
    HostServiceA <---> ECServiceA
    HostServiceB <---> ECServiceB
  end

Improved Developer Experience

ODP reduces developer friction and increases confidence, thus shortening the time to value for the development effort.

“Firmware development shouldn’t feel like archaeology.”

Developers can build and test components in isolation (e.g., battery, GPIO, boot timer), aided by QEMU emulation, mocks, and test harnesses.

ODP can improve developer engagement and productivity by:

  • 🚀 Reducing developer friction
  • 🛠️ Supporting tooling that’s approachable and efficient
  • 🧪 Enabling fast iteration and confident change
  • 💬 Reinforcing that firmware development is not arcane magic, just solid coding.

The Rust ecosystem brings built-in unit testing, logging, dependency control (Cargo), and static analysis.

timeline
  title Developer Workflow Evolution
  2000 : Edit ASM/C, guess BIOS behavior
  2010 : Use UEFI drivers, painful debug cycle
  2023 : Rust-based firmware prototypes emerge
  2024 : ODP introduces modular build + Stuart tools
  2025 : Fully testable DXE + EC code in Rust with shared tooling
flowchart LR
  Idea["💡 Idea"] --> Dev["🧩 Create Service Component"]
  Dev --> Test["🧪 Unit & Desktop Test"]
  Test --> Build["🔧 Cross-target Build<br/>(host & EC)"]
flowchart LR
  Build --> Sim["🖥️ Simulate with Mock Devices"]
  Sim --> Flash["🚀 Build & Flash"]
  Flash --> Log["📄 Review Logs / Debug"]
  Log --> Iterate["🔁 Iterate with Confidence"]

Sustainability and Long-Term Cost Reduction

ODP can help cut tech debt at its root by investing in sustainable design by enabling leaner teams and cleaner codebases.

“Technical debt is financial debt — just hidden in your firmware.”

Build right and reuse

Replacing legacy code with safer, testable, and reusable modules means lower maintenance costs over time.

flowchart LR
  Legacy["Legacy Stack"] --> Duplication["💥 Code Duplication"]
  Legacy --> Debugging["🐛 Opaque Bugs"]
  Legacy --> Porting["🔧 Costly Platform Bring-up"]
  Legacy --> Compliance["⚖️ Expensive Security Reviews"]
  Legacy --> Waste["🗑️ Rewrite Instead of Reuse"]

HAL separation

The ability to reuse and recompose across product lines (via ODP libraries) reduces the need to “reinvent the wheel” for each board/platform, as Hardware Abstraction Layers can be cleanly isolated from the business logic of a component design, and easily expanded upon for new features.

More than HAL

This component philosophy extends much further than replaceable HAL layers – it permeates throughout the component and service structure patterns ODP exposes. This allows agile modularity, greater reuseability, and shorter development cycles.

sequenceDiagram
  participant Dev as Developer
  participant Repo as Shared Component Repo
  participant DeviceA as Platform A
  participant DeviceB as Platform B

  Dev->>Repo: Build & Test Component
  DeviceA->>Repo: Pull Component A
  DeviceB->>Repo: Pull Component A
  Dev->>DeviceA: Customize Config
  Dev->>DeviceB: Customize Config
  Note right of Dev: One codebase, many targets

Alignment with Industry Trends and Standards

ODP is forward-facing from its original concept, and embodied in its design. Adoption of ODP positions you at the forefront of secure, future-facing firmware innovation.

“ODP doesn’t rewrite the rules — it implements them with confidence.”

Perfectly Timed

ODP taps into the growing ecosystem momentum around Rust and embedded standards. Rust adoption at Microsoft, Google, and the Linux kernel reflects a broader industry shift.

Open Source and Collaborative

ODP Encourages upstream contributions and compliance with modern firmware interfaces (UEFI, ACPI, DICE).

An open collaboration model invites cross-vendor reuse and innovation while building upon existing standards known to the industry.

graph TD
  A1[UEFI Spec] --> B1[DXE Core]
  A2[ACPI] --> B2[Runtime Services]
  A3[DICE] --> B3[Secure Boot]
  A4[SPDM] --> B3
  A5[DMTF] --> B4[Mgmt Layer]

  B1 --> C[ODP Framework]
  B2 --> C
  B3 --> C
  B4 --> C

ODP Repositories

There are over 60 repositories that make up the whole of the ODP umbrella. Many of these are simply HAL definitions for particular hardware, but others define the critical business logic and data traits that comprise the portable and modular framework ODP provides. Many of the crates defined by these repositories may be interdependent.

Other repositories represented here define tools and tests that are useful in development.


Patina

RepositoryDescriptionTag
Developing UEFI with Rust(Document) Overview of ODP Patina and Rust, contribution guide, and build setup.Patina
patinaLibrary of crates implementing Patina UEFI code.Patina
patina-dxe-core-qemuBuilds .efi image from Patina libraries and local components for QEMU.Patina
patina-qemuQEMU platform firmware integrating .efi Patina binaries.Patina
patina-readiness-toolTests platform readiness for Patina.Patina
patina-fw-patcherSpeeds up incremental firmware build iterations vs. full stuart_build.Patina
patina-mtrrMTRR (Memory Type Range Register) library for x86_64.Patina
patina-pagingCommon paging support for ARM64 and x64.Patina
uefi-corosenseiUEFI fork of corosensei crate.Patina

EC

RepositoryDescriptionTag
embedded-servicesService definitions wrapping HAL components.EC
soc-embedded-controllerDemonstration of EC firmware built using ODP components.EC
embedded-batteriesSmartBattery spec traits for HAL abstraction.EC
embedded-sensorsEmbedded sensors HAL abstraction.EC
embedded-fansHAL definition for fan control.EC
embedded-power-sequenceSoC power on/off abstraction.EC
embedded-cfuImplements Windows CFU commands/responses.EC
embedded-usb-pdCommon types for USB-PD.EC
embedded-mcuMCU traits and libraries for hardware peripherals.EC
hid-embedded-controllerHID over I2C demo library for ECs.EC
ec-test-appTest application to exercise EC functionality via ACPI.EC
ffaFF-A services in Rust for Hafnium.EC
haf-ec-serviceRust EC services for Hafnium.EC
ec-slimloaderStage-one EC bootloader.EC
ec-slimloader-descriptorsBoot descriptors for multi-image firmware scenarios.EC
(plus all drivers, PACs, and HAL crates such as bq24773, bq40z50, tmp108, mec17xx-pac, npcx490m-examples, embassy-*, etc.)EC

Security

RepositoryDescriptionTag
rust_crate_auditsAggregated Rust crate audits.Security

Tooling

RepositoryDescriptionTag
odp-utilitesRust utilities for embedded development.Tooling
systemview-tracingAdds Segger SystemView tracing to ODP.Tooling
nxp-headerCLI utility for NXP image headers.Tooling

Summary and Takeaways

Thank you for following along with our exploration of the Open Device Partnership project and its subsystems. In this guide, we have covered a range of topics from component architecture to testing strategies, all while adhering to the principles of modularity and reusability.

Key Takeaways

  • Modular Design: We emphasized the importance of modularity in firmware development, allowing for easier maintenance and upgrades.
  • Asynchronous Programming: We utilized asynchronous programming patterns to handle events and messages efficiently, which is crucial for embedded systems.
  • Testing: We implemented comprehensive testing strategies, including unit tests and integration tests, to ensure the reliability of our components.
  • Dependency Injection: We demonstrated how to use generic types and dependency injection to create flexible and reusable components.
  • Real-World Applications: We provided practical examples of how to implement battery and charger subsystems, showcasing the real-world applicability of the ODP framework.
  • Community and Contribution: We highlighted the importance of community involvement and how to contribute to the ODP project, fostering a collaborative environment for innovation.

Broader Lessons

  • Interfaces matter: Whether ACPI, ESPI, or custom channels, the boundary between EC and host is as important as the internal logic.
  • Security is non-optional: Real devices must layer in secure boot, signed updates, and privilege boundaries (e.g., Hafnium).
  • Emulation is a bridge: Virtual components in QEMU or std environments aren’t just toys; they give you a fast turnaround loop and a safe test bed.
  • Community accelerates adoption: Patterns only become standards when shared; contributing back to ODP closes the loop.