Beyond BIOS Second Edition Digital Edition
Beyond BIOS Second Edition Digital Edition
al Editi
E on
Digital Editions of selected In
D ntel Press books arre in
addition to and co omplemen nt the prin
nted bookss.
Second Edition
Vincent Zimmer
Michael Rothman
Suresh Marisetty
Copyright © 2010 Intel Corporation. All rights reserved.
ISBN 13 978-1-934053-29-4
This publication is designed to provide accurate and authoritative information in regard to the
subject matter covered. It is sold with the understanding that the publisher is not engaged in
professional services. If professional advice or other expert assistance is required, the services
of a competent professional person should be sought.
Intel Corporation may have patents or pending patent applications, trademarks, copyrights, or other
intellectual property rights that relate to the presented subject matter. The furnishing of documents and
other materials and information does not provide any license, express or implied, by estoppel or
otherwise, to any such patents, trademarks, copyrights, or other intellectual property rights.
Intel may make changes to specifications, product descriptions, and plans at any time, without notice.
Fictitious names of companies, products, people, characters, and/or data mentioned herein are not
intended to represent any real individual, company, product, or event.
Intel products are not intended for use in medical, life saving, life sustaining, critical control or safety
systems, or in nuclear facility applications.
Intel, the Intel logo, Celeron, Intel Centrino, Intel NetBurst, Intel Xeon, Itanium, Pentium, MMX, and
VTune are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United
States and other countries.
10 9 8 7 6 5 4 3 2 1
First printing, November 2010
To my wife Jan, and my daughters Ally and Zoe, without whose love this
book would not have been possible. To my parents Stanley and Joann, and
my sister Natalie, who have helped me on my journey through life.
—Vincent Zimmer
Preface xix
Chapter 1 Introduction 1
Terminology 5
A Short History of EFI 6
EFI Becomes UEFI—The UEFI Forum 7
PIWG and USWG 10
Platform Trust/Security 14
Embedded Systems: The New Challenge 17
Summary 19
v
vi n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
UEFI Images 31
Events and Task Priority Levels 37
Summary 41
Chapter 17 Manageability 347
Overall Management Framework 348
UEFI Error Format Standardization 351
Windows Hardware Error Architecture and the Role of UEFI 358
x n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Index 381
Foreword to the First Edition n xi
Foreword to the
First Edition
Beyond BIOS. Those two words began to circulate through the elite firmware
architects and developers in the industry standard computing circle around
1998, when Intel, Microsoft, HP and a number of other companies began to
lay out the plan for bringing up the first Intel® Itanium® systems. The plan was
originally called IBI, the Intel Boot Initiative. Mainstream PCs had been using
BIOS ever since the beginning of the IBM PC. Its drawbacks and limitations
were magnified in the “big iron” machines based on the Itanium processors.
For example, BIOS depends on many of the PC-AT hardware such as the 8254
timer and 8259 interrupt controller, which were not designed to scale to larger
servers like the HP Integrity Superdome† servers. Worse, BIOS assumes a 1MB
execution memory limit and has very limited memory space to execute the
Option ROMs on the add-in cards. BIOS’ 16-bit nature stifles the platform
advancement for Itanium systems that are 64-bit based.
There have been non-BIOS solutions in the more proprietary vertical
integrated systems design, such as Open Firmware used by IBM Power†, SUN
SPARC†, and Apple PowerPC†; ARCS† by DEC Alpha, and PDC/IODC† by
HP PA-RISC. Open Firmware is Forth-based, it is difficult to find the talent,
and its specifications have not kept up with the evolution of the technology.
ARCS lacks the driver model to support add-in cards. With BIOS hitting the
wall and no clear alternative that can be brought into the industry standard
arena, Intel spearheaded the IBI, which at this stage is named Extensible
Firmware Interface (EFI), to reflect objective of the effort. EFI brought
the modern computer software architectural concepts into firmware. EFI
enables firmware development in high-level languages like C, provides proper
xii n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
boot, we’re finally moving away from the old BIOS to this unified extensible
firmware interface, and that gives us new flexibility and capability, and it’s
got a rich API set to build on, so many of you are working with us on that.”
For any student in this field, this book provides an important bridge between
normative specifications and the informative details of the development.
Today, Itanium-based systems are no longer the only machines supporting
EFI. All the Intel®-based Apple Mac† systems are supporting EFI. Systems
based on Intel® 64 IA-32 processors are also in the process of supporting
UEFI. Embedded systems are also making use of the UEFI/PI architecture in
its specialized environment. Operating systems, such as Windows†, Linux†,
HP-UX†, Open VMS, FreeBSD, and so on are already EFI-based on Itanium-
based systems. Windows, Linux and OS-X† are in the process of supporting
UEFI on Intel® 64 IA-32 processor-based systems. Currently OS-X already
supports EFI on the IA-32 processor-based Mac systems.
This book is the first to describe in detail the Framework implementation
of UEFI and PI architecture. I am very pleased to recommend this new must-
read to you who may have been living in the BIOS world for so long to see the
life beyond BIOS as envisioned by Bill Gates. I also recommend that readers
take full advantage of the open source TianoCore.org. Sample code is worth a
thousand words. The EDK is a great companion for the book.
Dong Wei
Vice President and Chief Executive, the Unified Forum
HP Distinguished Technologist
Granite Bay, California
June 18, 2006
xiv n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Foreword to the Second Edition n xv
Foreword to the
Second Edition
One weekend this summer in the Silicon Valley, I was at a party hosted by
an executive from a hard disk drive manufacturer. Many of the people there
are in the computer industry. Inevitably the conversations were around the
hot topics in the industry, most notably cloud computing. While people were
busy explaining what they know about the cloud and all the $aaS (everything
as a service), the executive declared that he would be happy as long as cloud
means more demands for the storage capacity. He said his company is ready to
ship hard disk drives with 3 TB, but he claims that the industry is not entirely
ready to support these storage devices. The room went quiet. Not all the people
there understood what he was talking about, but all wanted to know why the
industry that is seemingly able to support all the grandiose concepts human
beings can think of has difficulty handling this seemingly easy task. What he
said next excited me.
“Beyond BIOS.” The executive spoke of these two words. My moment
came to explain to the crowd the root of the problem. It is amazing to see
the ah-hah moment when they see the definition of the Master Boot Record
(MBR) that we have been using to boot a PC from a hard disk drive since the
dawn of PC. It allows for partition size of up to 2 TiB (or 2.2 TB), assuming
today’s 512-byte sector size. “How come our high-paying architects have not
solved this simple problem?” one asked. I told them that a solution based on the
Unified Extensible Firmware Interface (UEFI) GUID-Partition Table (GPT)
disk format has been in existence for over a decade now (support for GPT disks
is available for all Itanium-based systems) and Windows† has supported GPT
data disks since Windows XP and GPT boot disks since Windows Vista SP1
xvi n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
on x64. “Then why are we not entirely ready and how do we get the industry
entirely ready?” asked another. The best approach is to have all the computers
support the UEFI boot from GPT format hard disk drives! I mentioned this
book to the crowd. The crowd started to get the terms, UEFI, GPT…
Time is ripe for the second edition of this book. Tremendous progresses
have been made since the publication of the first edition more than four
years ago. Time went by fast. It would have been hard to believe then, but
the majority of the x64 systems are now based on the UEFI technology (even
though some may not have exposed the UEFI boot interface). Many vendors
spearheaded the support for the UEFI boot on their systems, among them,
Apple iMac†, HP commercial notebooks, IBM System X† servers and Dell
PowerEdge† servers. The UEFI Forum has also defined support for many new
UEFI interfaces including network boot over IPv6, ARM† processor binding,
security enhancements, human interface infrastructure enhancements,
and so on. In addition, the UEFI Forum also evolved what was known as
“Framework” to Platform Initialization (PI) to define the phases of control from
the platform reset into the UEFI environment and to establish the firmware
internal interface architecture as well as firmware-to-silicon interfaces that
enable silicon driver modularity and interoperability. The resulting modularity
made PI the preferred implementation of UEFI. In the mean time, the open
source implementation of UEFI has gone through some changes. With the
evolution of Framework to PI, EFI Development Kit (EDK) II was introduced
to better realize the modularity and reuse. EDK II also contains the ARM and
Itanium port, in addition to the x64 port. Going forward, it is foreseeable that
EDK II will become the common converged firmware infrastructure across
the compute continuum. More recently, Intel named a release of EDK II as
UDK2010. It signifies that there is a UEFI Development Kit now matching
the UEFI Specifications as of January 2010 (namely UEFI v2.3 and PI v1.2).
As a matter of fact, IBM System X servers as well as HP Superdome† 2 and
Integrity† servers have been leading the way in transitioning to EDK II and are
in the process of updating to UDK2010 as we speak. This is the perfect time
to update the book.
This book is for you if you’d like to understand the UEFI/PI architecture;
that is, to understand how to move beyond BIOS. This book provides an
important bridge between normative specifications and the informative details
of the development. Now it has been updated to match the latest UEFI
Specifications and the EDK II codebase along with its UDK2010 release. I
am very pleased to recommend this new must-read to you, and please take
full advantage of the open source EDK II code base hosted by SourceForge.
Foreword to the Second Edition n xvii
Dong Wei
Vice President (Chief Executive), the UEFI Forum
Secretary, the ACPI SIG
Chair, The PCI SIG Firmware WG
xviii n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Preface n xix
Preface
There are two mistakes one can make on the road to truth…not going all the
way, and not starting.
— Buddha
This is a book about a new way to solve an old set of problems that are persistent
as well as fundamental, but not always well understood: How should you boot
a computer? What sits at the reset vector? What can the operating system count
on when it is loaded and initially receives control? What should the internal
structures be between these two endpoints? How can the same basic structure
work for handhelds and megaservers? How do we convince ourselves today’s
design will work 10 or 20 years from now? How much will it cost to switch?
How much will it cost steady state? What comes after BIOS (Basic Input/
Output System)?
Beyond BIOS is a book about a largely invisible subject. The general user, if
they have any view of BIOS at all, tends to view it as ten unnecessary seconds
on the way to booting the operating system or as setup. The community that
knows and uses the BIOS has tended to view it as an uncontrolled place of
kludge, myth, bug, and legend. The very small community of BIOS developers
has viewed their code not only as highly mutable and embodying much of the
compatibility that has made the PC and its offspring so successful, but also as
their livelihood.
This is a book that is about what comes after BIOS, which we call the
Unified Extensible Firmware Interface (UEFI) and Platform Initialization (PI).
In doing so, it must also be a book at least partly about what a BIOS or its
replacement is called upon to do. It is not a cookbook on how to port the PI
from platform to platform. It is not a rehash of the specifications. Instead, it
xx n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
tries to fit in the middle ground between specifications and cookbook. It tries
to focus on the concepts and constructs that are cross-platform and implied,
if not stated, by the architecture. It is supposed to help to get to some of the
“why” behind the specs and make the porting work make some sense.
This book is a child of its time. Both the UEFI and the PI are under
the control of the UEFI Forum, an industry-wide group in which you are
encouraged to participate. Beyond BIOS mainly focuses on the current state
of the PI and UEFI since the 2005 formation of the Forum, its working
groups, and its sub-teams. This is not to say that this is only a history book or
a simple summary of the standard. Instead, we believe it remains valuable as
an introduction to the newer versions of the specifications no matter who “has
the pen.”
The Chapters
Chapter 1 provides a description of the evolution.
This rest of the book is organized into two major sections. The earlier
chapters present an introduction to UEFI, and the later chapters cover the
Platform Initialization.
Chapter 2 provides an overview of the basic UEFI architecture. This is
a must-read for anyone seeking an understanding of the Unified Extensible
Firmware Interface (UEFI).
Chapter 3 describes the UEFI driver model. This is important for vendors
writing device drivers for output devices (such as video), input devices (such
as keyboards or mice), networking adapters, and block devices. These drivers
can be stored in the host-bus adapter, the platform ROM, or loaded from the
UEFI system partition.
Chapter 4 describes of series of commonly used UEFI protocols. This
chapter complements the earlier two chapters and includes data on additional
boot services application interfaces.
Chapter 5 includes information on the UEFI runtime operational
environment. This chapter is important for operating system vendors who
need to interact with the platform during the operating system execution.
Chapter 6 describes UEFI input and output console services. This chapter
provides details on the particular capabilities, interfaces, and relationships of
the console services.
Chapter 7 includes a list of different platforms and the Platform
Initialization-based implementations. This chapter demonstrates the flexibility
Preface n xxi
Acknowledgements
The authors recognize the efforts and contribution of the two men and a dog:
Mark Doran, Ken Reneris, and Andrew Fish, who conceived and hatched EFI.
The authors recognize and thank the other original Framework (Tiano)
architects Andrew Fish, Bob Hale, Mike Kinney, Barnes Cooper, Will Stevens,
Krithivas, ER Uber, Mahesh Natu, Rahul Khanna, Jim Ewertz, Kirk Brannock,
and others whose names are lost to time and the team’s intrepid leader, Mark
Doran. We thank Isaac Oram, John Lambino, and the entire Tiano Architecture
Team (TAT) team for fleshing out and enhancing the architecture. Thank you
to the Tiano engineering team for their patience while implementing the first
versions and to our internal and external customers. The innovation in this
book is from these fertile brains. Also, many of this team will recall over ten
years of “design discussions” at R&R.
We thank our managers, past and present, for giving us the chance and the
time to work on the architecture and this book including Doug Fisher, Richard
Wirt, Stu Goossen, Mike Richmond, Kah Loh, Jeff Griffen, Michael Greene,
Ju Lu, and Ron Story.
We acknowledge the ever-supportive marketing team: Shala, Laurie, Harry,
Fadi, Elmer, and Bailey.
No Intel Press book is published without peer review. We’d like to thank
all the reviewers for identifying errors and for providing valuable insight
and encouragement along the way. Without their help, this book would not
have been a success. From Intel, these individuals participated, at one time
or another, in the review of this project: Rob Branch, Mallik Bulusu, Brad
Davis, Michael Krau, John Suresh Kumar, Matthew Parrish, Mike Richmond,
Lee Rosenbaum, and Sudhakar Otturu. Other reviewers included Cameron
Esfahani from Apple Computer Corporation, Todd Greene from QLogic
Corporation, Penny Huang from MicroStar International Company, Limited,
Jimmy Hwang from American Megatrends, Incorporated, and Dong Wei from
Hewlett-Packard Development Company, L.P.
A book like this describes the efforts of a large number of talented
individuals. The authors would like to thank all of them for their efforts and
support. Please accept our apologies if we missed you. We can only say that
space is as limited here as it is in ROMs and time as limited here as it is in
schedules. We’ll try to fix it in the next release.
Preface n xxiii
Finally, we’d like to thank the team from Intel Press. Stuart Douglas was
the content architect for this project—his steady guidance and ability to find
resources as we needed them kept this book on track. David Clark was the
editor on the project, and helped take our engineering prose and turn it into
a real book.
xxiv n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 1
Introduction
The suddenness of the leap from hardware to software cannot but produce a
period of anarchy and collapse, especially in the developed countries.
—Marshall McLuhan
1
2 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
as a limited runtime for some application set, in lieu of loading a full, shrink-
wrapped multi-address space operating system like Microsoft Windows†, Apple
OS X†, HP-UX†, or Linux, but that is not the primary design goal.
Pre
Pre Verify
Verifier
Verifier
EFI/UEFI OS-Absent
Interfaces App
PEI
PEI
Core
Core
Transient OS
CPU
CPU Environment
Init
Init Device,
Bus, or
Chipset
Chipset Service Transient OS
Init
Init Driver Boot Loader
Not
Board
Board
OS-Present
Init
CoveredDispatcher
Init EFI Driver
EFI Driver Boot App
Manager
by EFI or UEFI
Architectural
Architectural Final OS Final OS
Protocols
Protocols Boot Loader Environment
Figure 1.1 Where EFI and UEFI Fit into the Platform Boot Flow
PI, on the other hand, should be largely opaque to the pre-OS boot
devices, operating systems, and their loaders since it covers many software
aspects of platform construction that are irrelevant to those consumers. PI
instead describes the phases of control from the platform reset and into the
success phase of operation, including an environment compatible with UEFI,
as shown in Figure 1.2. In fact, the PI DXE component is the preferred UEFI
core implementation.
Chapter 1: Introduction n 3
Pre Verify
Verifier
EFI/UEFI OS-Absent
Interfaces App
PEI
Core
Transient OS
CPU Not
Environment
Init Device,
Bus, or Covered
Chipset
Init
Service
Driver by EFI
Boot or UEFI
Transient OS
Loader
Board
Init OS-Present
EFI Driver Boot App
Dispatcher Manager
Components Covered
by Framework & PI
Figure 1.2 Where PI and Framework Fit into the Platform Boot Flow
Within the evolution of Framework to PI, some things were omitted from
inclusion in the PI specifications. As a result of these omissions, some subjects
that were discussed in the first edition of Beyond BIOS, such as the compatibility
support module (CSM), have been removed from the second edition in order
to provide space to describe the newer PI and UEFI capabilities. This omission
is both from a scope perspective, namely that the PI specification didn’t want to
codify or include the CSM, but also from a long-term perspective. Specifically,
the CSM specification abstracted booting on a PC/AT system. This requires
an x86 processor, PC/AT hardware complex (for example, 8254, 8259, RTC).
The CSM also inherited other conventional BIOS boot limitations, such as
the 2.2-TB disk limit of Master Boot Record (MBR) partition tables. For a
world of PI and UEFI, you get all of the x86 capabilities (IA-32 and x64,
4 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
respectively), ARM†, Itanium®, and future CPU bindings. Also, via the polled
driver model design, UEFI APIs, and the PI DXE architectural protocols, the
platform and component hardware details are abstracted from all consumer
software. Other minor omissions also include data hub support. The latter
has been replaced by purpose-built infrastructure to fill the role of data hub
in Framework-based implementations, such as SMBIOS table creation and
agents to log report status code actions.
What has happened in PI beyond Framework, though, includes the
addition of a multiprocessor protocol, Itanium E-SAL and MCA support, the
above-listed report-status code listener and SMBIOS protocol, an ACPI editing
protocol, and an SIO protocol. With Framework collateral that moved to PI, a
significant update was made to the System Management Mode (SMM) protocol
and infrastructure to abstract out various CPU and chipset implementations
from the more generic components. On the DXE front, small cleanup was
added in consideration of UEFI 2.3 incompatibility. Some additions occurred
in the PEI foundation for the latest evolution in buses, such as PCI Express†. In
all of these cases, the revisions of the SMM, PEI, and DXE service tables were
adjusted to ease migration of any SMM drivers, DXE drivers, and PEI module
(PEIM) sources to PI. In the case of the firmware file system and volumes,
the headers were expanded to comprehend larger file and alternate file system
encodings, respectively. Unlike the case for SMM drivers, PEIMs, and DXE
drivers, these present a new binary encoding that isn’t compatible with a pure
Framework implementation.
The notable aspect of the PI is the participation of the various members of
the UEFI Forum, which will be described below. These participants represent
the consumers and producers of PI technology. The ultimate consumer of a
PI component is the vendor shipping a system board, including multinational
companies such as Apple, Dell, HP, IBM, Lenovo, and many others. The
producers of PI components include generic infrastructure producers such as
the independent BIOS vendors (IBVs) like AMI, Insyde, Phoenix, and others.
And finally, the vendors producing chipsets, CPUs, and other hardware devices
like AMD, ARM, and Intel would produce drivers for their respective hardware.
The IBVs and the OEMs would use the silicon drivers, for example. If it were
not for this business-to-business transaction, the discoverable binary interfaces
and separate executable modules (such as PEIMs and DXE drivers) would
not be of interest. This is especially true since publishing GUID-based APIs,
marshalling interfaces, discovering and dispatching code, and so on take some
Chapter 1: Introduction n 5
overhead in system board ROM storage and boot time. Given that there’s never
enough ROM space, and also in light of the customer requirements for boot-
time such as the need to be “instantly on,” this overhead must be balanced by
the business value of PI module enabling. If only one vendor had access to all of
the source and intellectual property to construct a platform, a statically bound
implementation would be more efficient, for example. But in the twenty-first
century with the various hardware and software participants in the computing
industry, software technology such as PI is key to getting business done in light
of the ever-shrinking resource and time-to-market constraints facing all of the
UEFI forum members.
There is a large body of Framework-based source-code implementations,
such as those derived or dependent upon EDK I (EFI Developer Kit version
1), which can be found on www.tianocore.org. These software artifacts can
be recompiled into a UEFI 2.3, PI 1.2-compliant core, such as UDK2010
(the UEFI Developer Kit revision 2010), via the EDK Compatibility Package
(ECP). For new development, though, the recommendation is to build native
PI 1.2, UEFI 2.3 modules in the UDK2010 since these are the specifications
against which long-term silicon enabling and operating system support will
occur, respectively.
Terminology
The following list provides a quick overview of some of the terms that may be
encountered later in the book and have existed in the industry associated with
the BIOS standardization efforts.
■■ UEFI Forum. The industry body which produces UEFI, Platform
Initialization (PI), and other specifications.
2000 ®
Intel invented the Extensible
Firmware Interface (EFI) and
provided sample implementation
under free BSD terms.
2004 tianocore.org
Open source EFI community
launched.
UEFI Board
USWG
UCST
PIWG
UNST
UTWG
USST
ICWG
Drivers
• PIWG Specs relate to making
UEFI implementations
- Promote interoperability between firm-
ware components providers
Silicone - All interfaces and services produced
Component and consumed by firmware only
Modules
Hardware
Framework
Modular Components
Over time, these specifications have evolved. Below we enumerate the recent
history of specifications and the work associated with each:
■■ UEFI 2.1
–– Roughly one year of Specification work
■■ Builds on UEFI 2.0
–– New content area highlights:
■■ Human Interface Infrastructure
■■ Hardware Error Record Support
■■ Authenticated Variable Support
12 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Pre Verify
Verifier
UEFI OS-Absent
Interfaces App
PEI
Core
Transient OS
CPU Environment
Init Device,
Bus, or
Chipset Service Transient OS
Init Driver Boot Loader
Board
Init OS-Present
EFI Driver Boot App
Dispatcher Manager
Figure 1.6 Where PI and Framework Fit into the Platform Boot Flow
In addition, as time has elapsed, the specifications have evolved. Figure 1.7
is a time line for the specifications and the implementations associated with
them.
14 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
http://uefi.org
UEFI 2.0 UEFI 2.1 UEFI 2.2 UEFI 2.3
Specifications
PI 1.0 PI 1.1 PI 1.2
Platform Trust/Security
Recall that PI allowed for business-to-business engagements between
component providers and system builders. UEFI, on the other hand, has a
broader set of participants. These include the operating system vendors that
built the OS installers and UEFI-based runtimes; BIOS vendors who provide
UEFI implementations; platform manufacturers, such as multi-national
corporations who ship UEFI-compliant boards; independent software vendors
who create UEFI applications and diagnostics; independent hardware vendors
who create drivers for their adapter cards; and platform owners, whether a
home PC user or corporate IT, who must administer the UEFI-based system.
Chapter 1: Introduction n 15
PI differs from UEFI in the sense that the PI components are delivered under
the authority of the platform manufacturer and are not typically extensible by
third parties. UEFI, on the other hand, has a mutable file system partition, boot
variables, a driver load list, support of discoverable option ROMs in host-bus
adapters (HBAs), and so on. As such, PI and UEFI offer different issues with
respect to security. Chapter 10 treats this topic in more detail, but in general,
the security dimension of the respective domains include the following: PI must
ensure that the PI elements are only updateable by the platform manufacturer,
recovery, and PI is a secure implementation of UEFI features, including security;
UEFI provides infrastructure to authenticate the user, validate the source and
integrity of UEFI executables, network authentication and transport security,
audit (including hardware-based measured boot), and administrative controls
across UEFI policy objects, including write-protected UEFI variables.
A fusion of these security elements in a PI implementation is shown in
Figure 1.8.
16 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
UEFI-OS Legacy-OS
Bridge Bridge
FV
LPC TPM
How the Boot Process Differs between a Normal Boot and an Optimized/
Embedded Boot
Figure 1.9 indicates that between the normal boot and an optimized boot, there
are no design differences from a UEFI architecture point of view. Optimizing a
platform’s performance does not mean that one has to violate any of the design
specifications. It should also be noted that to comply with UEFI, one does not
need to encompass all of the standard PC architecture, but instead the design
can limit itself to the components that are necessary for the initialization of
the platform itself. Chapter 2 in the UEFI 2.3 specification does enumerate the
various components and conditions that comprise UEFI compliance.
18 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Are We in an Are We in an
S3 Boot Mode? S3 Boot Mode?
Yes No Yes No
Summary
We have provided some rationale in this chapter for the changes from Beyond
BIOS: Implementing the Unified Extensible Firmware Interface with Intel’s
Framework to Beyond BIOS: Developing with the Unified Extensible Firmware
Interface. These elements include the industry members’ ownership and
governance of the UEFI specification. Beyond this sea change, the chapter
describes the migration of the Framework specifications to PI specification and
the evolution of PI over the former Framework feature set. In addition, the
section describes the evolution of the UEFI specification to UEFI 2.3 from
the initial UEFI 2.0 matter in the first edition. Finally, some of the codebase
technology to help realize implementations of this technology was discussed.
So fasten your seat belt and dive into a journey through industry standard
firmware.
20 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 2
Basic UEFI
Architecture
I believe in standards. Everyone should have one.
—George Morrow
21
22 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ The UEFI System Table - the primary data structure with data
information tables and function calls to interface with the systems.
■■ Protocol services
The UEFI Boot Services and UEFI Runtime Services are accessed through the
UEFI Boot Services Table and the UEFI Runtime Services Table, respectively.
Both of these tables are data fields in the UEFI System Table. The number and
type of services that each table makes available is fixed for each revision of the
UEFI specification. The UEFI Boot Services and UEFI Runtime Services are
defined in the UEFI2.3 Specification.
Protocol services are groups of related functions and data fields that are
named by a Globally Unique Identifier (GUID), a 16-byte, statistically-
unique entity defined in Appendix A of the UEFI2.3 Specification. Typically,
protocol services are used to provide software abstractions for devices such as
consoles, disks, and networks, but they can be used to extend the number of
generic services that are available in the platform. Protocols are the mechanism
for extending the functionality of UEFI firmware over time. The UEFI 2.3
Specification defines over 30 different protocols, and various implementations
of UEFI firmware and UEFI drivers may produce additional protocols to
extend the functionality of a platform.
Handle Database
The handle database is composed of objects called handles and protocols. Handles
are a collection of one or more protocols, and protocols are data structures that
are named by a GUID. The data structure for a protocol may be empty, may
contain data fields, may contain services, or may contain both services and
data fields. During UEFI initialization, the system firmware, UEFI drivers,
and UEFI applications create handles and attach one or more protocols to the
handles. Information in the handle database is global and can be accessed by
any executable UEFI image.
The handle database is the central repository for the objects that are
maintained by UEFI-based firmware. The handle database is a list of UEFI
handles, and each UEFI handle is identified by a unique handle number that
is maintained by the system firmware. A handle number provides a database
“key” to an entry in the handle database. Each entry in the handle database
is a collection of one or more protocols. The types of protocols, named by a
24 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
GUID, that are attached to a UEFI handle determine the handle type. A UEFI
handle may represent components such as the following:
■■ Executable images such as UEFI drivers and UEFI applications
First Handle
Handle
GUID GUID
Agent Handle
Protocol Agent Handle Protocol
Controller Handle
Interface Controller Handle Interface
Attributes Attributes
Agent Handle
Controller Handle
Attributes
Handle
Figure 2.2 shows the different types of handles that can be present in the
handle database and the relationships between the various handle types. All
handles reside in the same handle database and the types of protocols that
are associated with each handle differentiate the handle type. Like file system
handles in an operating system context, the handles are unique for the session,
but the values can be arbitrary. Also, like the handle returned from an fopen
function in a C library, the value does not necessarily serve a useful purpose in a
different process or during a subsequent restart in the same process. The handle
is just a transitory value to manage state.
26 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Handles
Agent
Handles
Service
Handles
Controller Handles
Physical Virtual
Controller Controller
Handles Handles
Protocols
The extensible nature of UEFI is built, to a large degree, around protocols.
UEFI drivers are sometimes confused with UEFI protocols. Although they
are closely related, they are distinctly different. A UEFI driver is an executable
UEFI image that installs a variety of protocols of various handles to accomplish
its job.
A UEFI protocol is a block of function pointers and data structures or APIs
that have been defined by a specification. At a minimum, the specification
must define a GUID. This number is the protocol’s real name; boot services like
LocateProtocol uses this number to find his protocol in the handle database.
The protocol often includes a set of procedures and/or data structures, called
Chapter 2: Basic UEFI Architecture n 27
Sample GUID
#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \
{0x6a7a5cff, 0xe8d9, 0x4f70, 0xba, 0xda, 0x75, 0xab, 0x30,
0x25, 0xce, 0x14}
Figure 2.3 shows a single handle and protocol from the handle database
that is produced by a UEFI driver. The protocol is composed of a GUID and
a protocol interface structure. Many times, the UEFI driver that produces
a protocol interface maintains additional private data fields. The protocol
interface structure itself simply contains pointers to the protocol function.
The protocol functions are actually contained within the UEFI driver. A UEFI
driver might produce one protocol or many protocols depending on the driver’s
complexity.
28 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
First Handle
Handle
GUID
Protocol Interface EFI Driver
Function Pointer 1 GUID 1
Function Pointer 2
Function 1
Private Data
Access
Device or
Function 2
Services
Produced
by Other
EFI Drivers
GUID 2
Not all protocols are defined in the UEFI2.3 Specification. The UEFI
Developer Kit 2010 (UDK2010) includes many protocols that are not part of
the UEFI 2.3 Specification. This project can be found at http://www.tianocore.
org. These protocols provide the wider range of functionality that might be
needed in any particular implementation, but they are not defined in the
UEFI 2.3 Specification because they do not present an external interface that is
required to support booting an OS or writing a UEFI driver. The creation of
new protocols is how UEFI-based systems can be extended over time as new
devices, buses, and technologies are introduced. For example, some protocols
that are in the EDK II but not in the UEFI2.3 Specification are:
■■ Varstore – interface to abstract storage of UEFI persistent binary
objects
Chapter 2: Basic UEFI Architecture n 29
function is called, each handle returns the unique name of the driver that
owns that image handle. The EFI_COMPONENT_NAME2_PROTOCOL.
GetDriverName() function on the USB bus driver handle returns “USB
bus driver” for the English language, but on the PXE driver handle it returns
“PXE base code driver.”
Tag GUID
A protocol may be nothing more than a GUID. In such cases, the GUID is
called a tag GUID. Such protocols can serve useful purposes such as marking a
device handle as special in some way or allowing other UEFI images to easily
find the device handle by querying the system for the device handles with that
protocol GUID attached. The EDKII uses the HOT_PLUG_DEVICE_GUID
in this way to mark device handles that represent devices from a hot-plug bus
such as USB.
UEFI Images
All UEFI images contain a PE/COFF header that defines the format of the
executable code as required by the Microsoft Portable Executable and Common
Object File Format Specification (Microsoft 2008). The target for this code
can be an IA-32 processor, an Itanium® processor, x64, ARM, or a processor
agnostic, generic EFI Byte Code (EBC). The header defines the processor type
and the image type. Presently there are three processor types and the following
three image types defined:
■■ UEFI applications – images that have their memory and state
reclaimed upon exit.
■■ UEFI Boot Service drivers – images that have their memory and state
preserved throughout the pre-operating system flow. Their memory is
reclaimed upon invocation of ExitBootServices() by the OS
loader.
The value of the UEFI Image format is that various parties can create binary
executables that interoperate. For example, the operating system loader for
Microsoft Windows† and Linux for a UEFI-aware OS build is simply a UEFI
application. In addition, third parties can create UEFI drivers to abstract their
particular hardware, such as a networking interface host bus adapter (HBA)
or other device. UEFI images are loaded and relocated into memory with the
Boot Service gBS >LoadImage(). Several supported storage locations for
UEFI images are available, including the following:
■■ Expansion ROMs on a PCI card
■■ Retrieve information about where the UEFI image was loaded from
and where in memory the image was placed.
The operations that the UEFI image performs in its entry point vary depending
on the type of UEFI image. Figure 2.4 shows the various UEFI image types
and the relationships between the different levels of images.
EFI Images
Drivers
Service Drivers
EFI Driver Model Drivers
Initializing
Drivers
Bus Hybrid Device
Root Bridge
Drivers Drivers Drivers
Drivers
EFI 1.02
Drivers
Applications
OS Loaders
Device driver A driver that follows the UEFI Driver Model. This type of driver produces
one or more driver handles or driver image handles by installing one or
more instances of the Driver Binding Protocol into the handle database.
This type of driver does not create any child handles when the Start()
service of the Driver Binding Protocol is called. Instead, it only adds
additional I/O protocols to existing controller handles.
Bus driver A driver that follows the UEFI Driver Model. This type of driver produces
one or more driver handles or driver image handles by installing one or
more instances of the Driver Binding Protocol in the handle database. This
type of driver creates new child handles when the Start() service of
the Driver Binding Protocol is called. It also adds I/O protocols to these
newly created child handles.
Hybrid driver A driver that follows the UEFI Driver Model and shares characteristics
with both device drivers and bus drivers. This distinction means that the
Start() service of the Driver Binding Protocol will add I/O protocols to
existing handles and it will create child handles.
Applications
A UEFI application starts execution at its entry point, then continues execution
until it reaches a return from its entry point or it calls the Exit() boot service
function. When done, the image is unloaded from memory. Some examples
of common UEFI applications include the UEFI shell, UEFI shell commands,
flash utilities, and diagnostic utilities. It is perfectly acceptable to invoke UEFI
applications from inside other UEFI applications.
OS loader
A special type of UEFI application, called an OS boot loader, calls the
ExitBootServices() function when the OS loader has set up enough of
the OS infrastructure to be ready to assume ownership of the system resources.
At ExitBootServices(), the UEFI core frees all of its boot time services
and drivers, leaving only the run-time services and drivers.
Drivers
UEFI drivers differ from UEFI applications in that the driver stays resident in
memory unless an error is returned from the driver’s entry point. The UEFI
core firmware, the boot manager, or other UEFI applications may load drivers.
36 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ Destroy an event.
■■ Request that an event be moved from the waiting state to the signaled
state.
Because UEFI does not support interrupts, it can present a challenge to driver
writers who are accustomed to an interrupt-driven driver model. Instead, UEFI
supports polled drivers. The most common use of events by a UEFI driver is
the use of timer events that allow drivers to periodically poll a device. Figure
2.5 shows the different types of events that are supported in UEFI and the
relationships between those events.
38 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Signal
Events
Exit Boot Timer
Services Events
Events
Periodic One-Shot
Timer Timer
Events Events
Set Virtual
Address Map
Events
Wait
Events
Wait event An event whose notification function is executed whenever the event is
checked or waited upon.
Signal event An event whose notification function is scheduled for execution whenever
the event goes from the waiting state to the signaled state.
Exit Boot Services A special type of signal event that is moved from the waiting state to
event the signaled state when the UEFI Boot Service ExitBootServices()
is called. This call is the point in time when ownership of the
platform is transferred from the firmware to an operating system.
The event’s notification function is scheduled for execution when
ExitBootServices() is called.
Set Virtual Address A special type of signal event that is moved from the waiting
Map event state to the signaled state when the UEFI Runtime Service
SetVirtualAddressMap() is called. This call is the point in
time when the operating system is making a request for the runtime
components of UEFI to be converted from a physical addressing mode
to a virtual addressing mode. The operating system provides the map of
virtual addresses to use. The event’s notification function is scheduled for
execution when SetVirtualAddressMap() is called.
Timer event A type of signal event that is moved from the waiting state to the signaled
state when at least a specified amount of time has elapsed. Both periodic
and one-shot timers are supported. The event’s notification function is
scheduled for execution when a specific amount of time has elapsed.
Periodic timer event A type of timer event that is moved from the waiting state to the signaled
state at a specified frequency. The event’s notification function is
scheduled for execution when a specific amount of time has elapsed.
One-shot timer A type of timer event that is moved from the waiting state to the signaled
event state after the specified timer period has elapsed. The event’s notification
function is scheduled for execution when a specific amount of time has
elapsed.
■■ A notification function
■■ A notification context
The notification function for a wait event is executed when the state of the
event is checked or when the event is being waited upon. The notification
40 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
function of a signal event is executed whenever the event transitions from the
waiting state to the signaled state. The notification context is passed into the
notification function each time the notification function is executed. The TPL
is the priority at which the notification function is executed. Table 2.3 lists the
four TPL levels that are defined today. Additional TPLs could be added later.
An example of a compatible addition to the TPL list could include a series of
“Interrupt TPLs” between TPL_NOTIFY and TPL_HIGH_LEVEL in order
to provide interrupt-driven I/O support within UEFI.
■■ To create locks
For priority definition, you use this mechanism only when more than one event
is in the signaled state at the same time. In these cases, the application executes
the notification function that has been registered with the higher priority first.
Also, notification functions at higher priorities can interrupt the execution of
notification functions executing at a lower priority.
For creating locks, code running in normal context and code in an interrupt
context can access the same data structure because UEFI does support a single-
timer interrupt. This access can cause problems and unexpected results if the
updates to a shared data structure are not atomic. A UEFI application or UEFI
driver that wants to guarantee exclusive access to a shared data structure can
temporarily raise the task priority level to prevent simultaneous access from
both normal context and interrupt context. The application can create a lock
by temporarily raising the task priority level to TPL_HIGH_LEVEL. This
level blocks even the one-timer interrupt, but you must take care to minimize
the amount of time that the system is at TPL_HIGH_LEVEL. Since all timer-
Chapter 2: Basic UEFI Architecture n 41
based events are blocked during this time, any driver that requires periodic
access to a device is prevented from accessing its device. A TPL is similar to the
IRQL in Microsoft Windows and the SPL in various Unix implementations. A
TPL describes a prioritization scheme for access control to resources.
Summary
This chapter has introduced some of the basic UEFI concepts and object types.
These items have included events, protocols, task priority levels, image types,
handles, GUIDs, and service tables. Many of these UEFI concepts, including
images and protocols, are used extensively by other firmware technology,
including the UEFI Platform Initialization (PI) building blocks, such as the
DXE environment. These concepts will be revisited in different guises in
subsequent chapters.
42 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 3
UEFI Driver Model
Things should be made as simple as possible—but no simpler.
—Albert Einstein
43
44 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Driver Initialization
The file for a driver image must be loaded from some type of media. This could
include ROM, flash, hard drives, floppy drives, CD-ROM, or even a network
connection. Once a driver image has been found, it can be loaded into system
memory with the Boot Service LoadImage(). LoadImage() loads
a Portable Executable/Common File Format (PE/COFF) formatted image
into system memory. A handle is created for the driver, and a Loaded Image
Protocol instance is placed on that handle. A handle that contains a Loaded
Image Protocol instance is called an Image Handle. At this point, the driver has
not been started. It is just sitting in memory waiting to be started. Figure 3.1
shows the state of an image handle for a driver after LoadImage() has been
called.
Chapter 3: UEFI Driver Model n 45
Image Handle
EFI_LOADED_IMAGE_PROTOCOL
After a driver has been loaded with the Boot Service LoadImage(), it
must be started with the Boot Service StartImage(). This is true of all
types of UEFI applications and UEFI drivers that can be loaded and started on
a UEFI compliant system. The entry point for a driver that follows the UEFI
Driver Model must follow some strict rules. First, it is not allowed to touch any
hardware. Instead, it is only allowed to install protocol instances onto its own
Image Handle. A driver that follows the UEFI Driver Model is required to install
an instance of the Driver Binding Protocol onto its own Image Handle. It may
optionally install the Driver Configuration Protocol, the Driver Diagnostics
Protocol, or the Component Name Protocol. In addition, if a driver wishes to
be unloadable it may optionally update the Loaded Image Protocol to provide
its own Unload() function. Finally, if a driver needs to perform any special
operations when the Boot Service ExitBootServices()is called, it may
optionally create an event with a notification function that is triggered when
the Boot Service ExitBootServices() is called. An Image Handle that
contains a Driver Binding Protocol instance is known as a Driver Image Handle.
Figure 3.2 shows a possible configuration for the Image Handle from Figure
3.1 after the Boot Service StartImage() has been called.
46 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
EFI_LOADED_IMAGE_PROTOCOL
EFI_DRIVER_BINDING_PROTOCOL
EFI_DRIVER_CONFIGURATION_PROTOCOL
EFI_DRIVER_DIAGNOSTICS_PROTOCOL
EFI_COMPONENT_NAME2_PROTOCOL
A platform can be viewed as a set of CPUs and a set of core chip set
components that may produce one or more host buses. Figure 3.3 shows a
platform with n CPUs, and a set of core chipset components that produce m
host bridges.
Device Handle
EFI_DEVICE_PATH_PROTOCOL
EFI_PCI_HOST_BRIDGE_IO_PROTOCOL
A PCI Bus Driver could connect to this PCI Host Bridge, and create child
handles for each of the PCI devices in the system. PCI Device Drivers should
then be connected to these child handles, and produce I/O abstractions that
may be used to boot a UEFI compliant OS. The following section describes
the different types of drivers that can be implemented within the UEFI Driver
Model. The UEFI Driver Model is very flexible, so not all the possible types of
drivers are discussed here. Instead, the major types are covered that can be used
as a starting point for designing and implementing additional driver types.
Device Drivers
A device driver is not allowed to create any new device handles. Instead, it
installs additional protocol interfaces on an existing device handle. The most
common type of device driver attaches an I/O abstraction to a device handle
that has been created by a bus driver. This I/O abstraction may be used to boot
a UEFI compliant OS. Some example I/O abstractions would include Simple
Text Output, Simple Input, Block I/O, and Simple Network Protocol. Figure
3.5 shows a device handle before and after a device driver is connected to it. In
this example, the device handle is a child of the XYZ Bus, so it contains an XYZ
I/O Protocol for the I/O services that the XYZ bus supports. It also contains a
Device Path Protocol that was placed there by the XYZ Bus Driver. The Device
Path Protocol is not required for all device handles. It is only required for
device handles that represent physical devices in the system. Handles for virtual
devices do not contain a Device Path Protocol.
Chapter 3: UEFI Driver Model n 49
Device Handle
EFI_DEVICE_PATH_PROTOCOL START()
EFI_XYZ_IO_PROTOCOL
Device Handle
EFI_DEVICE_PATH_PROTOCOL
STOP()
EFI_XYZ_IO_PROTOCOL
EFI_BLOCK_IO_PROTOCOL
The device driver that connects to the device handle in Figure 3.5 must
have installed a Driver Binding Protocol on its own image handle. The Driver
Binding Protocol contains three functions called Supported(), Start(),
and Stop(). The Supported() function tests to see if the driver supports
a given controller. In this example, the driver will check to see if the device
handle supports the Device Path Protocol and the XYZ I/O Protocol. If a
driver’s Supported() function passes, then the driver can be connected
to the controller by calling the driver’s Start() function. The Start()
function is what actually adds the additional I/O protocols to a device handle.
In this example, the Block I/O Protocol is being installed. To provide symmetry,
the Driver Binding Protocol also has a Stop() function that forces the driver
to stop managing a device handle. This causes the device driver to uninstall any
protocol interfaces that were installed in Start().
50 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Bus Drivers
Bus drivers and device drivers are virtually identical from the UEFI Driver
Model’s point of view. The only difference is that a bus driver creates new
device handles for the child controllers that the bus driver discovers on its
bus. As a result, bus drivers are slightly more complex than device drivers, but
this in turn simplifies the design and implementation of device drivers. There
are two major types of bus drivers. The first creates handles for all the child
controllers on the first call to Start(). The second type allows the handles
for the child controllers to be created across multiple calls to Start(). This
second type of bus driver is very useful in supporting a rapid boot capability.
It allows a few child handles or even one child handle to be created. On buses
that take a long time to enumerate all of their children (such as SCSI), this
can lead to a very large time savings in booting a platform. Figure 3.6 shows
the tree structure of a bus controller before and after Start() is called. The
dashed line coming into the bus controller node represents a link to the bus
controller’s parent controller. If the bus controller is a Host Bus Controller,
then it does not have a parent controller. Nodes A, B, C, D, and E represent
the child controllers of the bus controller.
Chapter 3: UEFI Driver Model n 51
Stop() A B C D E
A bus driver that supports creating one child on each call to Start()
might choose to create child C first, and then child E, and then the remaining
children A, B, and D. The Supported(), Start(), and Stop()
functions of the Driver Binding Protocol are flexible enough to allow this type
of behavior.
A bus driver must install protocol interfaces onto every child handle that is
created. At a minimum, it must install a protocol interface that provides an I/O
abstraction of the bus’s services to the child controllers. If the bus driver creates
a child handle that represents a physical device, then the bus driver must also
install a Device Path Protocol instance onto the child handle. A bus driver
may optionally install a Bus Specific Driver Override Protocol onto each child
handle. This protocol is used when drivers are connected to the child controllers.
A new Boot Service ConnectController() uses architecturally defined
precedence rules to choose the best set of drivers for a given controller. The Bus
Specific Driver Override Protocol has higher precedence than a general driver
search algorithm, and lower precedence than platform overrides. An example
of a bus specific driver selection occurs with PCI. A PCI Bus Driver gives
a driver stored in a PCI controller’s option ROM a higher precedence than
drivers stored elsewhere in the platform. Figure 3.7 shows an example child
device handle that has been created by the XYZ Bus Driver that supports a bus
specific driver override mechanism.
52 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
EFI_XYZ_IO_PROTOCOL
Optional
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
Platform Components
Under the UEFI Driver Model, the act of connecting and disconnecting
drivers from controllers in a platform is under the platform firmware’s
control. This will typically be implemented as part of the UEFI Boot
Manager, but other implementations are possible. The new Boot Services
ConnectController() and DisconnectController() can be
used by the platform firmware to determine which controllers get started and
which ones do not. If the platform wishes to perform system diagnostics or
install an operating system, then it may choose to connect drivers to all possible
boot devices. If a platform wishes to boot a preinstalled operating system, it
may choose to only connect drivers to the devices that are required to boot the
selected operating system. The UEFI Driver Model supports both of these modes
of operation through the new Boot Services ConnectController() and
DisconnectController(). In addition, since the platform component
that is in charge of booting the platform has to work with device paths for
console devices and boot options, all of the services and protocols involved in
the UEFI Driver Model are optimized with device paths in mind.
Chapter 3: UEFI Driver Model n 53
The platform may also choose to produce an optional protocol named the
Platform Driver Override Protocol. This is similar to the Bus Specific Driver
Override Protocol, but it has higher priority. This gives the platform firmware
the highest priority when deciding which drivers are connected to which
controllers. The Platform Driver Override Protocol is attached to a handle in
the system. The new Boot Service ConnectController() will make use
of this protocol if it is present in the system.
These mechanisms include looking at the controller handle in the first example
and examining the device path in the second example.
//
// Use the DriverImageHandle to get the Driver Binding
Protocol
// instance
//
Status = gBS->OpenProtocol (
DriverImageHandle,
&gEfiDriverBindingProtocolGuid,
&DriverBinding,
gMyImageHandle,
NULL,
EFI_OPEN_PROTOCOL_HANDLE_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// EXAMPLE #1
//
// Use the Driver Binding Protocol instance to test to see
if
// the driver specified by DriverImageHandle supports the
// controller specified by ControllerHandle
//
Status = DriverBinding->Supported (
DriverBinding,
ControllerHandle,
NULL
);
if (!EFI_ERROR (Status)) {
Status = DriverBinding->Start (
DriverBinding,
ControllerHandle,
Chapter 3: UEFI Driver Model n 55
NULL
);
}
return Status;
//
// EXAMPLE #2
//
// The RemainingDevicePath parameter can be used to
initialize
// only the minimum devices required to boot. For example,
// maybe we only want to initialize 1 hard disk on a SCSI
// channel. If DriverImageHandle is a SCSI Bus Driver, and
// ControllerHandle is a SCSI Controller, and we only want
to
// create a child handle for PUN=3 and LUN=0, then the
// RemainingDevicePath would be SCSI(3,0)/END. The
following
// example would return EFI_SUCCESS if the SCSI driver
supports
// creating the child handle for PUN=3, LUN=0. Otherwise
it
// would return an error.
//
Status = DriverBinding->Supported (
DriverBinding,
ControllerHandle,
RemainingDevicePath
);
if (!EFI_ERROR (Status)) {
Status = DriverBinding->Start (
DriverBinding,
ControllerHandle,
RemainingDevicePath
);
}
return Status;
Pseudo Code
The algorithms for the Start() function for three different types of drivers
are presented here. How the Start() function of a driver is implemented can
56 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Device Driver
Bus Driver that Creates All of Its Child Handles on the First Call to Start()
Bus Driver that Is Able to Create All or One of Its Child Handles on Each Call to
Start():
EXCLUSIVE. It must use the same Attribute value that was used
in Supported().
2. If any of the calls to OpenProtocol() in Step 1 returned
an error, then close all of the protocols opened in Step 1 with
CloseProtocol(), and return the status code from the call to
OpenProtocol() that returned an error.
3. Initialize the device specified by ControllerHandle. If
an error occurs, close all of the protocols opened in Step 1 with
CloseProtocol(), and return EFI_DEVICE_ERROR.
4. IF RemainingDevicePath is not NULL, THEN
5. C is the child device specified by RemainingDevicePath.
6. Allocate and initialize all of the data structures that this driver
requires to manage the child device C. This would include space
for public protocols and space for any additional private data
structures that are related to the child device C. If an error occurs
allocating the resources, then close all of the protocols opened
in Step 1 with CloseProtocol(), and return EFI_OUT_
OF_RESOURCES.
7. If the bus driver creates device paths for the child devices, then
create a device path for the child C based upon the device path
attached to ControllerHandle.
8. Initialize the child device C.
9. Create a new handle for C, and install the protocol interfaces for
child device C. This may include the EFI_DEVICE_PATH_
PROTOCOL.
10. Call OpenProtocol() on behalf of the child C with an
Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_
CONTROLLER.
11. ELSE
12. Discover all the child devices of the bus controller specified by
ControllerHandle.
60 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
13. If the bus requires it, allocate resources to all the child devices of
the bus controller specified by ControllerHandle.
14. FOR each child C of ControllerHandle
15. Allocate and initialize all of the data structures that this
driver requires to manage the child device C. This would
include space for public protocols and space for any
additional private data structures that are related to the
child device C. If an error occurs allocating the resources,
then close all of the protocols opened in Step 1 with
CloseProtocol(), and return EFI_OUT_OF_
RESOURCES.
16. If the bus driver creates device paths for the child devices,
then create a device path for the child C based upon the
device path attached to ControllerHandle.
17. Initialize the child device C.
18. Create a new handle for C, and install the protocol
interfaces for child device C. This may include the EFI_
DEVICE_PATH_PROTOCOL.
19. Call OpenProtocol() on behalf of the child C with
an Attribute of EFI_OPEN_PROTOCOL_BY_
CHILD_CONTROLLER.
20. END FOR
21. END IF
22. Return EFI_SUCCESS.
Chapter 3: UEFI Driver Model n 61
Listed below is sample code of the Start() function of the device driver
for a device on the XYZ bus. The XYZ bus is abstracted with the EFI_XYZ_
IO_PROTOCOL. This driver does allow the EFI_XYZ_IO_PROTOCOL to
be shared with other drivers, and just the presence of the EFI_XYZ_IO_
PROTOCOL on ControllerHandle is enough to determine if this driver
supports ControllerHandle. This driver installs the EFI_ABC_IO_
PROTOCOL on ControllerHandle. The gBS and gMyImageHandle
variables are initialized in this driver’s entry point.
The following code sequence provides a generic example of what a driver
can do in its start routine in the hope of particularizing the guidance listed
above.
extern EFI_GUID gEfiXyzIoProtocol;
extern EFI_GUID gEfiAbcIoProtocol;
EFI_BOOT_SERVICES_TABLE *gBS;
EFI_HANDLE gMyImageHandle;
EFI_STATUS
AbcStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
OPTIONAL
)
{
EFI_STATUS Status;
EFI_XYZ_IO_PROTOCOL *XyzIo;
EFI_ABC_DEVICE AbcDevice;
//
// Open the Xyz I/O Protocol that this driver consumes
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiXyzIoProtocol,
&XyzIo,
gMyImageHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
62 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
//
// Allocate and zero a private data structure for the Abc
// device.
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_ABC_DEVICE),
&AbcDevice
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
ZeroMem (AbcDevice, sizeof (EFI_ABC_DEVICE));
//
// Initialize the contents of the private data structure
for
// the Abc device. This includes the XyzIo protocol
instance
// and other private data fields and the EFI_ABC_IO_
PROTOCOL
// instance that will be installed.
//
AbcDevice->Signature = EFI_ABC_DEVICE_SIGNATURE;
AbcDevice->XyzIo = XyzIo;
AbcDevice->PrivateData1 = PrivateValue1;
AbcDevice->PrivateData1 = PrivateValue2;
. . .
AbcDevice->PrivateData1 = PrivateValueN;
AbcDevice->AbcIo.Revision = EFI_ABC_IO_PROTOCOL_
REVISION;
AbcDevice->AbcIo.Func1 = AbcIoFunc1;
AbcDevice->AbcIo.Func2 = AbcIoFunc2;
. . .
AbcDevice->AbcIo.FuncN = AbcIoFuncN;
AbcDevice->AbcIo.Data1 = Value1;
AbcDevice->AbcIo.Data2 = Value2;
. . .
AbcDevice->AbcIo.DataN = ValueN;
//
Chapter 3: UEFI Driver Model n 63
return EFI_SUCCESS;
ErrorExit:
//
// When there is an error, the provate data structures
need
// to be freed and the protocols that were opened need
to be
// closed.
//
if (AbcDevice != NULL) {
gBS->FreePool (AbcDevice);
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiXyzIoProtocolGuid,
gMyImageHandle,
ControllerHandle
);
return Status;
}
Additional Innovations
In addition to the basic capabilities for booting, such as support for the various
buses, there are other classes of feature drivers that provide capabilities to the
platform. Some examples of these feature drivers include security, manageability,
and networking.
64 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Security
In addition to the bus driver-based architecture, the provenance of the UEFI
driver may be a concern for some vendors. Specifically, if the UEFI driver is
loaded from a host-bus adapter (HBA) PCI card or from the UEFI system
partition, the integrity of the driver could be called into question. As such, the
UEFI 2.3 Specification describes a means by which to enroll signed UEFI drivers
and applications. The particular signature format is Authenticode, which is a
well-known usage of X509V2 certificates and PKCS#7 signature formats. The
use of a well-known embedded signature format in the PE/COFF images of
the UEFI drivers allows for interoperable trust, including the use of Certificate
Authorities (CAs), such as Verisign, to sign the executables and distribute the
credentials. More information on the enrollment can be found in Chapter
27 of the UEFI 2.3 Specification. Information on the Windows Authenticode
Portable Executable Signature Format can be found at http://www.microsoft.
com/whdc/winlogo/drvsign/Authenticode_PE.mspx.
Other security featuers in UEFI 2.3 include the User Identity (UID)
infrastructure. The UID allows for the inclusion of credential provider drivers,
such as biometric devices, smart cards, and other authentication methods,
into a user manager framework. This framework will allow for combining the
factors from the various credential providers and assigning rights to different
UEFI users. One use case could include only the administrator having access to
the USB devices in the pre-OS, whereas other users could only access the boot
loader on the UEFI system partition. More information on UID can be found
in Chapter 31 of the UEFI 2.3 Specification.
Manageability
The UEFI driver model has also introduced the Driver Health Protocol. The
Driver Health Protocol exposes additional capabilities that a boot manager
might use in concert with a device. These capabilities include EFI_DRIVER_
HEALTH_PROTOCOL.GetHealthStatus() and EFI_DRIVER_HEALTH_
PROTOCOL.Repair() services. The former will allow the boot manager to
ascertain the state of the device, and the latter API will allow for the invocation
of some recovery operation. An example of the usage may include a large solid-
state disk cache or redundant array of inexpensive disks (RAID). If the system
were powered down during operating system runtime in an inconsistent state,
say not having the RAID5 parity disk fully updated, the driver health protocol
Chapter 3: UEFI Driver Model n 65
would allow for exposing the need to synchronize the cache or RAID during
the pre-OS without “disappearing” for a long period during this operation
and making the user believe the machine had failed. More information on
the Driver Health Protocol can be found in Chapter 10 of the UEFI 2.3
Specification.
Networking
The UEFI driver model has also evolved to support complex device hierarchies,
such as a dual IPV4 and IPV6 modular network stack. Figure 3.8 is a picture
of the Internet Small Computer Systems Interface (iSCSI) network application
atop both the IPV4 and IPV6 network stack.
66 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
iSCSI
DHCP4 DHCP6
IP4CONFIG_SB
DHCP4_SB IP6CONFIG_SB
TCP4_SB DHCP6_SB By Child
UDP_SB TCP6_SB
IP4_SB UDP6_SB
ARP_SB IP6_SB
NIC MNP_SB
Summary
This chapter has introduced the UEFI driver model and some sample drivers.
The UEFI driver model allows for support of modern bus architectures in
addition to the lazy activation of devices needed by boot for today’s platforms
and designs in the future. The support for buses is key because most of the
storage, console, and networking devices are attached via an industry-standard
bus like USB, PCI, and SCSI. The architecture described is general enough to
support these and future evolutions in platform hardware. In addition to access
to boot devices, though, there are other features and innovations that need
to be surfaced in the platform. UEFI drivers are the unit of delivery for these
types of capabilities, and examples of networking, security, and management
feature drivers were reviewed.
68 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 4
Protocols You
Should Know
Common sense ain’t common.
—Will Rogers
T his chapter describes protocols that everyone who is working with the
Unified Extensible Firmware Interface (UEFI), whether creating device
drivers, UEFI pre-OS applications, or platform firmware, should know.
The protocols are illustrated by a few examples, beginning with the most
common exercise from any programming text, namely “Hello world.” The test
application listed here is the simplest possible application that can be written.
It does not depend upon any UEFI Library functions, so the UEFI Library is
not linked into the executable that is generated. This test application uses the
SystemTable that is passed into the entry point to get access to the UEFI
console devices. The console output device is used to display a message using
the OutputString() function of the SIMPLE_TEXT_OUTPUT_
INTERFACE protocol, and the application waits for a keystroke from the
user on the console input device using the WaitForEvent() service with
the WaitForKey event in the SIMPLE_INPUT_INTERFACE protocol.
Once a key is pressed, the application exits.
/*++
Module Name:
helloworld.c
69
70 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Abstract:
This is a simple module to display behavior of a basic UEFI
application.
Author:
Waldo
Revision History
--*/
#include “efi.h”
EFI_STATUS
InitializeHelloApplication (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN Index;
//
// Send a message to the ConsoleOut device.
//
SystemTable->ConOut->OutputString (
SystemTable->ConOut,
L”Hello application started\n\r”);
//
// Wait for the user to press a key.
//
SystemTable->ConOut->OutputString (
SystemTable->ConOut,
L”\n\r\n\r\n\rHit any key to exit\n\r”);
SystemTable->BootServices->WaitForEvent (
1,
&(SystemTable->ConIn->WaitForKey),
&Index);
SystemTable->ConOut->OutputString (
SystemTable->ConOut,L”\n\r\n\r”);
Chapter 4: Protocols You Should Know n 71
//
// Exit the application.
//
return EFI_SUCCESS;
}
To execute a UEFI application, type the program’s name at the UEFI Shell
command line. The following examples show how to run the test application
described above from the UEFI Shell. The application waits for the user to
press a key before returning to the UEFI Shell prompt. It is assumed that
hello.efi is in the search path of the UEFI Shell environment.
Example
Shell> hello
EFI OS Loaders
This section discusses the special considerations that are required when writing
an OS loader. An OS loader is a special type of UEFI application responsible for
transitioning a system from a firmware environment into an OS environment.
To accomplish this task, several important steps must be taken:
1. The OS loader must determine from where it was loaded. This
determination allows an OS loader to retrieve additional files from
the same location.
2. The OS loader must determine where in the system the OS exists.
Typically, the OS resides on a partition of a hard drive. However,
the partition where the OS exists may not use a file system that is
recognized by the UEFI environment. In this case, the OS loader
can only access the partition as a block device using only block I/O
operations. The OS loader will then be required to implement or load
the file system driver to access files on the OS partition.
72 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Operating System
Legacy OS Loader EFI OS Loader EFI API
Memory
(Other)
Timer
Drivers
SMBIOS
Protocols +
ACPI
Handlers
INTERFACES
FROM OTHER
REQUIRED PLATFORM SPECIFIC FIRMWARE
SPECS
PLATFORM HARDWARE
EFI System OS
Motherboard Partition Partition
ROM/FLASH Option ROM
EFI 1.10 Drivers
EFI 1.10 EFI 1.10
EFI OS Loader
Drivers Drivers
The next section of the output shows the first block of several block devices.
The first one is the first block of the floppy drive with a FAT12 file system. The
second one is the Master Boot Record (MBR) from the hard drive. The third
one is the first block of a large FAT32 partition on the same hard drive, and
the fourth one is the first block of a smaller FAT16 partition on the same hard
drive.
The final step shows the pointers to all the system configuration tables, the
system’s current memory map, and a list of all the system’s environment variables.
The very last step shown is the OS loader calling ExitBootServices().
74 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
BS->HandleProtocol(
ImageHandle,
&LoadedImageProtocol,
LoadedImage
);
BS->HandleProtocol(
LoadedImage->DeviceHandle,
&DevicePathProtocol,
&DevicePath
);
Print (
L”Image device : %s\n”,
DevicePathToStr (DevicePath)
);
Print (
L”Image file : %s\n”,
DevicePathToStr (LoadedImage->FilePath)
);
Print (
L”Image Base : %X\n”,
LoadedImage->ImageBase
);
Print (
L”Image Size : %X\n”,
LoadedImage->ImageSize
);
Chapter 4: Protocols You Should Know n 75
BS->HandleProtocol(
LoadedImage->DeviceHandle,
&FileSystemProtocol,
&Vol
);
Vol->OpenVolume (
Vol,
&RootFs
);
CurDir = RootFs;
The next step is to build a file path to OSKERNEL.BIN that exists in the
same directory as the OS loader image. Once the path is built, the file handle
CurDir can be used to call Open(), Close(), Read(), and Write()
on the OSKERNEL.BIN file. The following code fragment builds a file path,
opens the file, reads it into an allocated buffer, and closes the file.
StrCpy(FileName,DevicePathToStr(LoadedImage->FilePath));
for(i=StrLen(FileName);i>=0 && FileName[i]!=’\\’;i--);
FileName[i] = 0;
StrCat(FileName,L”\\OSKERNEL.BIN”);
CurDir->Open (CurDir, &FileHandle, FileName, EFI_FILE_
MODE_READ, 0);
76 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Size = 0x00100000;
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
FileHandle->Close(FileHandle);
NoHandles = 0;
HandleBuffer = NULL;
LibLocateHandle(ByProtocol, &BlockIoProtocol, NULL,
&NoHandles, &HandleBuffer);
for(i=0;i<NoHandles;i++) {
BS->HandleProtocol (
HandleBuffer[i],
&DevicePathProtocol,
&DevicePath
);
BS->HandleProtocol (
HandleBuffer[i],
&BlockIoProtocol,
&BlkIo
);
Chapter 4: Protocols You Should Know n 77
LibGetSystemConfigurationTable(
&AcpiTableGuid,&AcpiTable
);
LibGetSystemConfigurationTable(
&SMBIOSTableGuid,&SMBIOSTable
);
LibGetSystemConfigurationTable(
&SalSystemTableGuid,&SalSystemTable
);
LibGetSystemConfigurationTable(
&MpsTableGuid,&MpsTable
78 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
);
Print(
L” ACPI Table is at address :
%X\n”,AcpiTable
);
Print(
L” SMBIOS Table is at address :
%X\n”,SMBIOSTable
);
Print(
L” Sal System Table is at address :
%X\n”,SalSystemTable
);
Print(
L” MPS Table is at address :
%X\n”,MpsTable
);
MemoryMap = LibMemoryMap(
&NoEntries,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
Print(
L”Memory Descriptor List:\n\n”
);
Print(
L” Type Start Address End Address Attributes
\n”
);
Print(
L” ========== ================ ================
================\n”);
MemoryMapEntry = MemoryMap;
for(i=0;i<NoEntries;i++) {
Print(L” %s %lX %lX %lX\n”,
OsLoaderMemoryTypeDesc[MemoryMapEntry->Type],
MemoryMapEntry->PhysicalStart,
MemoryMapEntry->PhysicalStart +
LShiftU64(
MemoryMapEntry->NumberOfPages,
PAGE_SHIFT)-1,
MemoryMapEntry->Attribute
);
MemoryMapEntry = NextMemoryDescriptor(
MemoryMapEntry,
DescriptorSize
);
}
VariableName[0] = 0x0000;
VendorGuid = NullGuid;
Print(
L”GUID Variable Name
Value\n”);
Print(
L”= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
========\n”);
do {
VariableNameSize = 256;
Status = RT->GetNextVariableName(
&VariableNameSize,
VariableName,
&VendorGuid
);
if (Status == EFI_SUCCESS) {
VariableValue = LibGetVariable(
VariableName,
&VendorGuid
);
Print(
L”%.-35g %.-20s
%X\n”,&VendorGuid,VariableName,VariableValue
);
}
} while (Status == EFI_SUCCESS);
Transitioning to an OS Kernel
A single call to ExitBootServices() terminates all the UEFI Boot
Services that the UEFI environment provides. From that point on, only the
UEFI Runtime Services may be used. Once this call is made, the OS loader
needs to prepare for the transition to the OS kernel. It is assumed that the OS
kernel has full control of the system and that only a few firmware functions are
required by the OS kernel. These functions are the UEFI Runtime Services.
The OS loader must pass the SystemTable to the OS kernel so that the
OS kernel can make the Runtime Services calls. The exact mechanism that is
used to transition from the OS loader to the OS kernel is implementation-
dependent. It is important to note that the OS loader could transition to the
OS kernel prior to calling ExitBootServices(). In this case, the OS
Chapter 4: Protocols You Should Know n 81
Summary
This chapter has provided an overview of some common protocols and their
demonstration via a sample operating system loader application. Given that
UEFI has been primarily designed as an operating system loader environment,
this is a key chapter for demonstrating the usage and capability of the UEFI
service set.
82 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 5
UEFI Runtime
Adding manpower to a late software project makes it later.
—Brook’s Law
T his chapter describes the fundamental services that are made available in
a UEFI-compliant system. The services are defined by interface functions
that may be used by code running in the UEFI environment. Such code may
include protocols that manage device access or extend platform capabilities.
In this chapter, the runtime services will be the focus of discussion. These
runtime services are functions that are available both during UEFI operation
and when the OS has been launched and running.
During boot, system resources are owned by the firmware and are
controlled through a variety of system services that expose callable APIs. In
UEFI there are two primary types of services:
■■ Boot Services – Functions that are available prior to the launching
of the boot target (such as the OS), and prior to the calling of the
ExitBootServices() function.
83
84 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Reset Exposed
Vectpr Runtime OS-Absent
Interface App
CPU
Init
Chipset
Transient OS
Init
Environment
Device,
Board Bus, or
Init Service
Driver
Transient OS
Boot Loader
OS-Present
App
Boot Manager
Final OS
Boot Loader
Final OS
Environment ?
In Figure 5.1, it is clearly evident that the two previously mentioned forms
of services (Boot Services and Runtime Services) are available during the early
launch of the UEFI infrastructure and only the runtime services are available
after the remainder of the firmware stack has relinquished control to an OS
loader. Once an OS loader has loaded enough of its own environment to take
control of the system’s continued operation it can then terminate the boot
services with a call to ExitBootServices().
In principle, the ExitBootServices() call is intended for use by
the operating system to indicate that its loader is ready to assume control
of the platform and all platform resource management. Thus boot services
are available up to this point to assist the OS loader in preparing to boot
the operating system. Once the OS loader takes control of the system and
completes the operating system boot process, only runtime services may be
called. Code other than the OS loader, however, may or may not choose to call
Chapter 5: UEFI Runtime n 85
Mnemonic Description
EfiPalCode Address space reserved by the firmware for code that is part of the
processor.
Table 5.1 lists memory types and their corresponding usage prior to
launching a boot target (such as an OS). The memory types that would be used
by most runtime drivers would be those with the keyword “runtime” in them.
However, to better illustrate how these memory types are used in the runtime
phase of the platform evolution, Table 5.2 illustrates how these UEFI Memory
types are used after the OS loader has called ExitBootServices() to
indicate the transition from the pre-boot, to the runtime phase of operations.
Chapter 5: UEFI Runtime n 87
Mnemonic Description
In Table 5.2, one can see how the runtime memory types are preserved, and
the BootServices type of memory is available for the OS to reclaim as its own.
88 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
.
.
GUID X, *Pointer X'
GUID Y, *Pointer Y'
GUID Z, *Pointer Z'
typedef struct {
*FunctionPointerTBD,
*FunctionPointerTBD2,
*FunctionPointerTBD3,
*etc
} EFI_SYSTEM_ERROR_LOG_PROTOCOL
Protocol/API Definition
Figure 5.2 Interactions between the UEFI Configuration Table and a Function
Prototype
Time Services
This section describes the core UEFI definitions for time-related functions that
are specifically needed by operating systems at runtime to access underlying
hardware that manages time information and services. The purpose of these
interfaces is to provide runtime consumers of these services an abstraction for
hardware time devices, thereby relieving the need to access legacy hardware
devices directly. The functions listed in Table 5.3 reside in the UEFI Runtime
Services table.
90 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
GetTime Runtime Returns the current time and date, and the time-
keeping capabilities of the platform.
SetTime Runtime Sets the current local time and date information.
GetWakeupTime Runtime Returns the current wakeup alarm clock setting.
SetWakeupTime Runtime Sets the system wakeup alarm clock time.
Get Time
Even though this function is called “GetTime”, it is intended to return the
current time as well as the date information along with the capabilities of
the current underlying time-based hardware. This service is not intended to
provide highly accurate timings beyond certain described levels. During the
Boot Services phase of platform initialization, there are other means by which
to do accurate time stall measurements (for example, see the Stall() boot
services function in the UEFI specification).
Even though Figure 5.3 shows the smallest granularity of time measurement
in nanoseconds, this by no means is intended as an indication of the accuracy
of the time measurement of which the function is capable. The only thing
Chapter 5: UEFI Runtime n 91
that is guaranteed by the call to this function is that it returns a time that was
valid during the call to the function. This guarantee is more understandable
when one thinks about the processing time for the call to traverse various
levels of code between the caller and the service function actually talking to the
hardware device and this data then being passed back to the caller. Since this
is a call initiated during the runtime phase of platform operations, the highly
accurate timers that are needed for small granularity timing events would be
provided by alternate (likely OS-based) solutions.
//*******************************************************
//EFI_TIME
//*******************************************************
// This represents the current time information
typedef struct {
UINT16 Year; // 1998 – 20XX
UINT8 Month; // 1 – 12
UINT8 Day; // 1 – 31
UINT8 Hour; // 0 – 23
UINT8 Minute; // 0 – 59
UINT8 Second; // 0 – 59
UINT8 Pad1;
UINT32 Nanosecond; // 0 – 999,999,999
INT16 TimeZone; // -1440 to 1440 or 2047
UINT8 Daylight;
UINT8 Pad2;
} EFI_TIME;
Set Time
This function provides the ability to set the current time and date information
on the platform.
ConvertPointer
The ConvertPointer function is used by a UEFI component during the
SetVirtualAddressMap() operation. When the platform has passed
control to an OS loader and it in turn calls SetVirtualAddressMap(),
a function is called in most runtime drivers that responds to the virtual address
change event that is triggered. This function uses the ConvertPointer service to
convert the current physical pointer to an appropriate virtual address pointer.
All pointers that the component has allocated should be updated using this
mechanism.
94 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Variable Services
Variables are defined as key/value pairs that consist of identifying information,
attributes, and some quantity of data. Variables are intended for use as a means
to store data that is passed between the UEFI environment implemented in the
platform and UEFI OS loaders and other applications that run in the UEFI
environment.
Although the implementation of variable storage is not specifically defined
for a given platform, variables must be able to persist across reboots of the
platform. This implies that the UEFI implementation on a platform must
arrange it so that variables passed in for storage are retained and available for
use each time the system boots, at least until they are explicitly deleted or
overwritten. Provision of this type of nonvolatile storage may be very limited
on some platforms, so variables should be used sparingly in cases where other
means of communicating information cannot be used. Table 5.5 lists the
variable services functions that UEFI provides.
GetVariable
This function returns the value of a given UEFI variable. Since a fully qualified
UEFI variable name is composed of both a human-readable text value paired
with a GUID, a vendor can create and manage its own variables without the
risk of name conflicts by using its own unique GUID value. For instance, one
can easily have three variables named “Setup” that are wholly unique assuming
that each of these “Setup” variables has a different numeric GUID value.
One of the key items to note in the definition of a UEFI variable is that
each one has some attributes associated with it. These attributes are treated as
a bit field, which implies that none, any, or all of the bits can be activated at
any given time. In the case of UEFI variables, however, there are three defined
attribute bits to be aware of:
Chapter 5: UEFI Runtime n 95
■■ Runtime – a variable that has this attribute activated must also have
the BootService attribute activated. With this, the variable is accessible
during all phases of the platform evolution.
GetNextVariableName
Since the UEFI variable repository is very similar in concept to a file system,
the ability to parse the repository is provided by the GetNextVariableName
service. This service enumerates the current variable names in the platform,
and with each subsequent call to the service the previous results can be passed
into the interface, and on output the interface returns the next variable name
data. Once the entire list of variables has been returned, a subsequent call
into the service providing the previous “last” variable name will provide the
equivalent of a “Not Found” error.
It should be noted that this service is affected by the phase of platform
operations. Variables that do not have the runtime attribute activated are
allocated typically from some type of BootServices memory. Since this is the
case, once ExitBootServices() is performed to signify the transition
into the runtime phase, these variables will no longer show up in the search list
that GetNextVariableName provides.
One other behavior that should be noted is that one might conceive that
if a variable has the ability to be named the same human-readable name (such
as “Setup”) and the only thing that differs is the GUID, one could seed the
search mechanism for this service by walking a common GUID-based list of
variables. This is not the case. The usage of this service is typically initiated
96 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
with a call that starts with a pointer to a Null Unicode string as the human-
readable name; the GUID is ignored. Instead, the entire list of variables must
be retrieved, and the caller may act as a filter if you choose to have it do so.
SetVariable
UEFI variables are often used to provide a means by which to save platform-
based context information. For instance, when the platform initializes the I/O
infrastructure and has probed for all known console output devices, it will
likely construct a ConOutDev global variable. These global variables have a
unique purpose in the platform since they have a specific architectural role
to play with a specific purpose. Table 5.6 shows some of the defined global
variables.
LangCodes BS, RT The language codes that the firmware supports. This
value is deprecated.
Lang NV, BS, RT The language code that the system is configured for.
This value is deprecated.
Timeout NV, BS, RT The firmware’s boot managers timeout, in seconds,
before initiating the default boot selection.
PlatformLangCodes BS, RT The language codes that the firmware supports.
PlatformLang NV, BS, RT The language code that the system is configured for.
ConIn NV, BS, RT The device path of the default input console.
ConOut NV, BS, RT The device path of the default output console.
ErrOut NV, BS, RT The device path of the default error output device.
ConInDev BS, RT The device path of all possible console input devices.
ConOutDev BS, RT The device path of all possible console output devices.
ErrOutDev BS, RT The device path of all possible error output devices.
The examples in Table 5.6 show some of the common global variables, their
descriptions, and their attributes. Some of the noted differences are the presence
or absence of the NV (nonvolatile) attribute. This simply means that the values
associated with these variables are not persistent across platform resets and their
values are determined during the initialization phase of platform operations.
Chapter 5: UEFI Runtime n 97
Miscellaneous Services
This section contains the remaining function definitions for runtime services
that were not talked about in previous sections but are required to complete
a compliant implementation of a UEFI environment. The services that are in
this section are as listed in Table 5.7.
Reset System
This service provides a caller the ability to reset the entire platform including all
processors and devices, and reboots the system. This service provides the ability
to stipulate three types of resets:
■■ Cold Reset – A call to the ResetSystem() service stipulating a
cold reset will cause a system-wide reset. This sets all circuitry within
the system to its initial state. This type of reset is asynchronous to
system operation and operates without regard to cycle boundaries.
This is tantamount to a system power cycle.
UpdateCapsule
This runtime function allows a caller to pass information to the firmware.
UpdateCapsule is commonly used to update the firmware FLASH or for an
operating system to have information persist across a system reset. Other usage
models such as updating platform configuration are also possible depending on
the underlying platform support.
A capsule is simply a contiguous set of data that starts with an EFI_
CAPSULE_HEADER. The CapsuleGuid field in the header defines the format
of the capsule.
The capsule contents are designed to be communicated from an OS-present
environment to the system firmware. To allow capsules to persist across system
reset, a level of indirection is required for the description of a capsule, since the
OS primarily uses virtual memory and the firmware at boot time uses physical
memory. This level of abstraction is accomplished via the EFI_CAPSULE_
BLOCK_DESCRIPTOR. The EFI_CAPSULE_BLOCK_DESCRIPTOR
allows the OS to allocate contiguous virtual address space and describe this
address space to the firmware as a discontinuous set of physical address ranges.
The firmware is passed both physical and virtual addresses and pointers to
describe the capsule so the firmware can process the capsule immediately or
defer processing of the capsule until after a system reset.
Chapter 5: UEFI Runtime n 101
QueryCapsuleCapabilities
This runtime function allows a caller to check whether or not a particular capsule
can be supported by the platform prior to sending it to the UpdateCapsule
routine. Many of these checks are based on the type of capsule being passed
and their associated flag values contained within the capsule header.
Summary
This chapter has introduced some of the basic UEFI runtime capabilities. These
are unique in that they are the few aspects of the firmware that will reside in the
system even when the target software (such as the operating system) is running.
These are the functions that can be leveraged any time during the platform’s
evolution from pre-OS through the runtime phases.
102 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 6
UEFI Console
Services
Never test for an error condition you don’t know how to handle.
—Steinbach’s Guideline for Systems Programming
103
104 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
The UEFI console is built out of two primary protocols: UEFI Simple
Text Input and UEFI Simple Text Output. These two protocols implement a
basic text-based console that allows platform firmware, UEFI applications, and
UEFI OS loaders to present information to and receive input from a system
administrator. The UEFI console consists of 16-bit Unicode characters, a
simple set of input control characters known as scan codes, and a set of output-
oriented programmatic interfaces that give functionality equivalent to an
intelligent terminal. In the UEFI 2.1 specification, an extension to the Simple
Text Input protocol was introduced (now referred to as Simple Text Input Ex),
which greatly expanded the supportable keys as well as state information that
can be retrieved from the keyboard. This text-based set of interfaces does not
inherently support pointing devices on input or bitmaps on output.
To ensure greatest interoperability, the UEFI Simple Text Output
protocol is recommended to support at least the printable basic Latin Uni-
code character set to enable standard terminal emulation software to be used
with a UEFI console. The basic Latin Unicode character set implements a
superset of ASCII that has been extended to 16-bit characters. This provides
the maximum interoperability with external terminal emulations that might
otherwise require the conversion of text encoding to be down-converted to a
set of ASCII equivalents.
UEFI has a variety of system-wide references to consoles. The UEFI System
Table contains six console-related entries:
■■ ConsoleInHandle – The handle for the active console input
device. This handle must support the UEFI Simple Text Input
protocol and the UEFI Simple Text Input Ex protocol.
■■ ConInDev – The UEFI global variable that contains the device path
of all possible console input devices.
■■ ConOut – The UEFI global variable that contains the device path of
the default output console.
■■ ErrOut – The UEFI global variable that contains the device path of
the default error console.
EFI
System Table
ConIn/ConOut/StdErr
Application/Driver
EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEST_OUT
Text I/O
Abstraction EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEST_OUT
Video
Device
HW Device is discovered and Device is discovered and
Abstraction the device driver is launched. the device's option
ROM/driver is launched.
■■ Scan Code - The input stream supports UEFI scan codes in addition
to Unicode characters. If the scan code is set to 0x00 then the Unicode
character is valid and should be used. If the UEFI scan code is set to
a value other than 0x00, it represents a special key as defined in Table
6.2.
0x80000000 If high bit is on, then the state value is valid. For devices that are not
capable of producing shift state values, this value will be off.
0x01 Right Shift key is pressed.
0x02 Left Shift key is pressed.
0x04 Right Control key is pressed.
0x08 Left Control key is pressed.
0x10 Right Alt key is pressed.
0x20 Left Alt key is pressed.
0x40 Right logo key is pressed.
0x80 Left logo key is pressed.
0x100 Menu key is pressed.
0x200 System Request (SysReq) key is pressed.
0x80 If high bit is on, then the state value is valid. For devices that are not
capable of representing toggle state values, this value will be off.
0x01 Scroll Lock is active.
0x02 Num Lock is active.
0x04 Caps Lock is active.
StdOut device. In addition, the minimum supported text mode of such devices
is at least 80 × 25 characters.
A video device that supports only graphics mode is required to emulate text
mode functionality. Output strings themselves are not allowed to contain any
control codes other than those defined in Table 6.1. Positional cursor placement
is done only via the SetCursorPosition() function. It is highly
recommended that text output to the StdErr device be limited to sequential
string outputs. That is, it is not recommended to use ClearScreen() or
SetCursorPosition() on output messages to StdErr, so that this
data can be clearly captured or viewed.
The Simple Text Output protocol also has a pointer to some mode data,
as shown in Figure 6.2. This mode data is used to determine what the current
text settings are for the given device. Much of this information is used to
determine what the current cursor position is as well as the given foreground
and background color. In addition, one can stipulate whether a cursor should
be visible or not.
typedef struct {
INT32 MaxMode;
// current settings
INT32 Mode;
INT32 Attribute;
INT32 CursorColumn;
INT32 CursorRow;
BOOLEAN CursorVisible;
}SIMPLE_TEXT_OUTPUT_MODE;
Figure 6.2 Mode Structure for UEFI Simple Text Output Protocol
The Simple Text Output protocol also has a variety of text output related
functions; however, this chapter focuses on some of the most commonly used
ones:
■■ OutputString – Provides the ability to write a NULL-terminated
Unicode string to the output device and have it displayed. All
output devices must also support some of the basic Unicode drawing
characters listed in the UEFI 2.1 Specification. This is the most basic
output mechanism on an output device. The string is displayed at
the current cursor location on the output device(s) and the cursor is
advanced according to the rules listed in Table 6.5.
112 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Null U+0000 Ignore the character, and do not move the cursor.
BS U+0008 If the cursor is not at the left edge of the display, then move the
cursor left one column.
LF U+000A If the cursor is at the bottom of the display, then scroll the display
one row, and do not update the cursor position. Otherwise,
move the cursor down one row.
CR U+000D Move the cursor to the beginning of the current row.
Other U+XXXX Print the character at the current cursor position and move the
cursor right one column. If this moves the cursor past the right
edge of the display, then the line should wrap to the beginning
of the next line. This is equivalent to inserting a CR and an LF.
Note that if the cursor is at the bottom of the display, and the
line wraps, then the display will be scrolled one line.
Table 6.6 Sample Conversion Table for UEFI Scan Codes to other Terminal Formats
Table 6.7 shows some of the PC ANSI and ANSI X3.64 control sequences
for adjusting display/text display attributes for text displays.
Table 6.7 Example Control Sequences that Can Be Used in Console Drivers
Figure 6.3 illustrates the software layering for a remote serial interface with
Text I/O abstractions. The primary difference between this illustration and one
that exhibits the same Text I/O abstractions on local devices is that this one
has one additional layer of software drivers. In the former examples, the local
device was discovered by an agent, launched, and it in turn would establish
a set of Text I/O abstractions. In the remote case, the local device is a serial
device, which has a console driver that is layered onto it, and it in turn would
establish a set of Text I/O abstractions.
EFI
System Table
ConIn/ConOut/StdErr
Application/Driver
EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEST_OUT
Text I/O
Abstraction EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEST_OUT
Remote System
HW Device is discovered and the
Abstraction Serial I/O Interface is installed
Console Splitter
The ability to describe a variety of console devices poses interesting new
possibilities. In previous generations of firmware, one had a single means by
which one could describe what the Text I/O sources and targets were. Now
the UEFI variables that specify the active consoles are specified by a device
path. In this case, these device paths are multi-instance, meaning that more
than one target device could be the active input or output. For instance, if one
wanted to be able to have an application print text to the local screen as well as
to the screen of a remote terminal, it would be highly impractical for anyone
to customize their software to accommodate that particular scenario. In the
solution that UEFI provides with its console splitting/merging capability, an
application can simply use the standard text interfaces that UEFI provides and
the console splitter routes the text requests to the appropriate target or targets.
This works for both input as well as output streams.
The way this works is that when the UEFI-compliant platform initializes,
the console splitter installs itself in the UEFI System Table as the primary active
console. In doing so, it can then proceed to monitor the platform as other
UEFI text interfaces get installed as protocols and the console splitter keeps a
running tally of the user selected devices for a given console variable, such as
ConOut, ConIn, or ErrOut.
Figure 6.4 illustrates a scenario where an application is calling UEFI text
interfaces, which in turn calls the UEFI System Table console interfaces. These
interfaces belong to the console splitter, and the console splitter then sends the
text I/O requests from the application to the platform-configured consoles.
Chapter 6: UEFI Console Services n 117
EFI ConIn/
System Table ConOut/StdErr
Application/Driver
EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEXT_OUT
EFI
System Table
EFI_SIMPLE_TEXT_OUT
Console driver translates I/O to and
from a terminal type and EFI
semantics. This driver proxies it
to the physical device abstraction.
Data is Sent to the Data is Received from the
Target Video Device Keyboard Device
Device
LShif t B0* B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 RShif t 1 2 3
Enter
0 .
LCtr l A0 LAlt Space Bar A2 A3 A4 RCtr l
Local Devices
Remote System
Serial Terminal
Connections
Through a
Serial Connection
Network Consoles
UEFI also provides the ability to establish data connections with remote
platforms across a network. Given the appropriate installed drivers, one
could also enable a UEFI-compliant platform to support a text I/O set of
abstractions. Similar to previously discussed concepts where the hardware
interface (for example, serial device, keyboard, video, network interface card)
has an abstraction, other components build on top of this hardware abstraction
to provide a working software stack.
Some network components that UEFI might include are as follows:
■■ Network Interface Identifier – This is an optional protocol that is
produced by the Universal Network Driver Interface (UNDI) and is
used to produce the Simple Network Protocol. This protocol is only
required if the underlying network interface is a 16-bit UNDI, 32/64-
bit software UNDI, or hardware UNDI. It is used to obtain type and
revision information about the underlying network interface.
EFI
System Table
ConIn/ConOut/StdErr
Application/Driver
EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEST_OUT
Text I/O
Abstraction EFI_SIMPLE_TEXT_IN EFI_SIMPLE_TEST_OUT
Transport TCP/IP
Layer Stack
Simple Network
Protocol SNP
HW UNDI
Abstraction
NIC
Summary
In conclusion, UEFI provides a very robust means of describing the various
possible input and output console possibilities. It can also support console
representations through a gamut of protocols such as terminal emulators
(such as ANSI/VT100) as well as remote network consoles leveraging wider
variations of the underlying UEFI network stack.
Chapter 7
Different Types of
Platforms
Variety’s the very spice of life, That gives it all its flavor.
—William Cowper
121
122 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
CPU Cores
Memory Memory
Direct Video
Controller Modules
SM Bus
Disk
South PCI
USB Bridge PCI-e Bus Slots
SPI Bus
LAN
Super
I/O FLASH
Audio
0xFFFF_FFFF
System FLASH ( 1MB ) UEFI PI Code and
Data Stored Here
0xFF00_0000
Temp Memory CPU SEC Maps Unused
0xFEF0_0000 Region as Temporary
Local APIC Memory
0xFEE0_0000
0xFED0_0000
I/O APIC
0xFEC0_0000
0xZZZ0_0000
PCI Resources
0xYYY0_0000
Handheld PC
System Flash
Desktop/Server PC
Figure 7.4 shows a series of non-PCs, such as tablets and smart phones.
The former includes a touch screen and integrated peripherals, such as 3G,
Wi-Fi† and LTE/WiMAX† radios. The latter devices, namely the smart
phones, are highly integrated devices with GPS, several radios, touch screens,
accelerometers, and some NAND storage. Within all of these devices, an Intel
Chapter 7: Different Types of Platforms n 125
Now let’s examine the components for the PC in Figure 7.1 in greater
detail. The PEI phase of execution runs immediately after a restart event, such
as a power-on reset, resume from hibernate, and so on. The PEI modules
execute in place from the flash store, at least until the main memory complex
(such as DRAM) has been initialized.
Figure 7.5 displays the collection of PEIMs for the PC platform. Different
business interests would supply the modules. For example, in the platform
codenamed Lakeport, Intel would provide the Intel® Core™ i7 CPU with an
integrated Memory Controller Hub Memory Controller PEIM and the PCH
(Platform Controller Hub) PEIM. The PCH is also known as the “South
Bridge.” In addition, for the SMBUS (System management bus) attached to the
PCH, there would be a PCH-specific SMBUS PEIM. The status code PEIM
would describe a platform-specific means by which to emit debug information,
such as an 8-bit code emitted to I/O port 80-hex.
126 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
The SMBUS PEIM for the PCH listed in Figure 7.5 provides a standard
interface, or PEIM-to-PEIM interface (PPI), as shown in Figure 7.6. This
allows the memory controller PEIM to use the SMBUS read command in
order to get information regarding the dual-inline memory module (DIMM)
Serial Presence Detect (SPD) data on the memory. The SPD data includes
the size, timing, and other details about the memory modules. The memory
initialization PEIM will use the EFI_PEI_SMBUS_PPI so that the GMCH-
specific memory initialization module does not need to know which component
provides the SMBUS capability. In fact, many integrated super I/O (SIO)
components also provide an SMBUS controller, so this platform could have
replaced the PCH SMBUS PEIM with an SIO SMBUS PEIM without having
to modify the memory controller PEIM.
Chapter 7: Different Types of Platforms n 127
typedef
EFI_STATUS
(EFIAPI *PEI_SMBUS_PPI_EXECUTE_OPERATION) (
IN EFI_PEI_SERVICE **PeiServices,
IN struct EFI_PEI_SMBUS_PPI *This,
IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
IN EFI_SMBUS_DEVICE_COMMAND Command,
IN EFI_SMBUS_OPERATION Operation,
IN BOOLEAN PecCheck,
IN OUT UINTN *Length,
IN OUT VOID *Buffer
);
typedef struct {
PEI_SMBUS_PPI_EXECUTE_OPERATION Execute;
PEI_SMBUS_PPI_ARP_DEVICE ArpDevice;
} EFI_PEI_SMBUS_PPI;
EFI_PEI_SERVICES *PeiServices;
SMBUS_PRIVATE_DATA *Private;?
UINT8 Index, BlockCount *Length;
UINT8 *Buffer;
BlockCount = Private->CpuIo.IoRead8 (
*PeiServices,Private->CpuIo,SMBUS_R_HD0);
if (*Length < BlockCount) {
return EFI_BUFFER_TOO_SMALL;
} else {
for (Index = 0; Index < BlockCount; Index++) {
Buffer[Index] = Private->CpuIo.IoRead8 (
*PeiServices,Private->CpuIo,SMBUS_R_HBD);
}
}
Beyond the PEI phase, the DXE core requires a series of platform-, CPU-,
and chipset-specific drivers in order to provide a fully-instantiated set of DXE/
EFI services. Figure 7.8 lists the collection of architectural protocols that are
necessary for the PC platform under study.
Chapter 7: Different Types of Platforms n 129
The fact that the DXE Foundation does not presume anything about the
timekeeping logic, interrupt controller, instruction set, and so on, means that
the DXE Foundation C code can be retargeted for a large class of platforms
without reengineering the Foundation code itself. Instead, a different collection
of the architectural protocols (APs) can affect the Foundation port.
One aspect of the system that needs to be abstracted is the management
of time. The timekeeping hardware on a PC/AT compatible chipset, such as
the 8254 timer, differs from the CPU-integrated timer-counter (ITC) on the
Itanium processor or the timekeeping logic specific to the Intel Atom processor.
As such, in order to have a single implementation of the DXE Foundation
watchdog-timer logic, the access to CPU/chipset-specific timing hardware
is implemented via the Timer Architectural Protocol. This AP has a series of
services, such as getting and setting the time period. The setting of the time
period will be reviewed across our reference class of platforms.
To begin, Figure 7.9 provides an instance of the set timer service for the
NT32 platform. NT32 is a virtual PI platform that executes upon a 32-bit
Microsoft Windows system as a user-mode process. It is a “soft” platform
in that the platform capabilities are abstracted through Win32 services. As
such, the implementation of this AP service doesn’t access an I/O controller
or chipset control/status registers. Instead, the AP invokes a series of Win32
services to provide mutual exclusion and an operating system thread to emulate
the timer action.
130 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
EFI_STATUS
TimerDriverSetTimerPeriod (
IN EFI_TIMER_ARCH_PROTOCOL *This,
IN UINT64 TimerPeriod
)
{
. . .
gWinNt->EnterCriticalSection (&mNtCriticalSection);
mTimerPeriod = TimerPeriod;
mCancelTimerThread = FALSE;
gWinNt->LeaveCriticalSection (&mNtCriticalSection);
mNtLastTick = gWinNt->GetTickCount ();
mNtTimerThreadHandle = gWinNt->CreateThread (
NULL,
0,
NtTimerThread,
&mTimer,
0,
&NtThreadId);
. . .
}
EFI_STATUS
TimerDriverSetTimerPeriod (
IN EFI_TIMER_ARCH_PROTOCOL *This,
IN UINT64 TimerPeriod
)
{
UINT64 Count;
UINT32 Data;
. . .
Count = DivU64x32 (MultU64x32 (TimerPeriod, OST_CRYSTAL_FREQ) + 5000000,
10000000, NULL);
mCpuIo->Mem.Read (mCpuIo,EfiWidthUint32,OSCR_BASE_PHYSICAL,1,&Data);
Data += (UINT32)Count;
mCpuIo->Mem.Write (mCpuIo,EfiWidthUint32,OSMR0_BASE_PHYSICAL,1,&Data);
mCpuIo->Mem.Read (mCpuIo,EfiWidthUint32,OIER_BASE_PHYSICAL,1,&Data);
Data |= (UINT32)1;
mCpuIo->Mem.Write (mCpuIo,EfiWidthUint32,OIER_BASE_PHYSICAL,1,&Data);
mCpuIo->Mem.Read (mCpuIo,EfiWidthUint32,ICMR_PHYSICAL,1,&Data);
Data |= (UINT32)(1 << SA_OST0_IRQ_No);
mCpuIo->Mem.Write (mCpuIo,EfiWidthUint32,ICMR_PHYSICAL,1,&Data);
. . .
}
Finally, for the PC/AT and the circa mid-1980s ISA I/O hardware, there
is an additional implementation of the AP service. Figure 7.11 shows the same
set timer service when accessing the 8254 timer-counter and then registering
an interrupt with the 8259 Programmable Interrupt Controller (PIC). This is
often referred to as a PC/AT version of the AP since all PCs since the PC-XT
have supported these hardware interfaces. For the PC example in this chapter,
these ISA I/O resources are supported by the PCH component, versus discrete
components in the original PC.
132 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
EFI_STATUS
TimerDriverSetTimerPeriod (
IN EFI_TIMER_ARCH_PROTOCOL *This,
IN UINT64 TimerPeriod
)
{
UINT64 Count;
UINT8 Data;
. . .
Count = DivU64x32 (MultU64x32(119318, (UINTN) TimerPeriod) + 500000,
1000000, NULL);
Data = 0x36;
mCpuIo->Io.Write(mCpuIo,EfiCpuIoWidthUint8,TIMER_CONTROL_PORT, 1, &Data);
mCpuIo->Io.Write(mCpuIo,EfiCpuIoWidthFifoUint8,TIMER0_COUNT_PORT,2,&Count);
mLegacy8259->EnableIrq (mLegacy8259, Efi8259Irq0, FALSE);
. . .
}
PCI Root Bridge PCI Host Bridge Resource ISA ACPI Protocol
I/O Protocol Allocation Protocol
In order to build out this stack, the boot-device selection (BDS) or the
UEFI shell provides an application or command line interface (CLI) to the
user. The Simple Input and output protocols are published via a console driver
that layers upon the Serial I/O protocol. For the PCI-based PC, a PCI root
bridge protocol allows access to the serial port control and status registers; for
the Intel Atom platform with an internally-integrated UART/serial port, an
alternate low-level protocol may exist to access these same registers.
For this platform layering, the components listed in Figure 7.13 describe
the DXE and UEFI components needed to build out this console stack. Just
as in the case of the PEI modules, different interests can deliver the DXE and
UEFI drivers. For example, the Super I/O vendor may deliver the ISA ACPI
driver, the silicon vendor PCI root bridge (such as the GMCH in this PC), a
platform console driver, and then a set of reusable components based upon the
PC/AT ISA hardware.
134 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Beyond the console components, several other PEI modules and DXE
components need to be included into the firmware volume. These other
components, listed in Figure 7.14, provide for other capabilities. These include
the platform-specific means by which to store UEFI variables, platform policy
for security, and configuration.
Chapter 7: Different Types of Platforms n 135
The UEFI variables can be stored in various regions of the flash part (or
a service processor on a server), so a driver needs to abstract this store. For
security, the vendor may demand that field component updates be signed or
that modules dispatched be hash-extended into a Trusted Platform Module
(TPM). The security driver will abstract these security capabilities.
A final feature to describe the component layering of DXE drivers is support
for the disk subsystem, namely the Integrated Device Electronics (IDE) and
a UEFI file system. The protocol layering for the disk subsystem up to the file
system instance are shown in Figure 7.15.
136 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
PCI Root Bridge PCI Host Bridge Resource IDE Controller Init
I/O Protocol Allocation Protocol
The same UEFI shell or BDS resides at the top of the protocol layering.
Instances of the simple file system (FS) protocol provide the read/write/open/
close capability to applications. The FS protocols layer atop disk I/O protocol.
A disk I/O provides byte-level access to a sector-oriented block device. As such,
disk I/O is a software-only driver that provides this mapping from hardware-
specific block I/O abstractions. The disk I/O layer binds to a series of block
I/O instances. The block I/O protocol is published by the block device interest,
such as the PCH driver in DXE that abstracts the Serial AT-Attachment (SATA)
disk controller in the PCH. The disk driver uses the PCI Block I/O protocol to
access the control and status registers in the PCH component.
The components that provide these capabilities in the file system stack
can be found in Figure 7.16. The file system components include the File
Allocation Table (FAT) driver, a driver that provides FAT12/16/32 support.
FAT is the original file system for MS-DOS on the original PC that has been
Chapter 7: Different Types of Platforms n 137
This same console stack for the serial port and file system stack for the
SATA controller only depends upon the PCH components, a PCI abstraction,
and appropriate support components. As such, putting this same PCH, or a
logically-equivalent version of this chip integrated into another application-
specific integrated circuit (ASIC), will admit reusage of these same binaries
on other like systems (such as an x64 desktop to an x64 server). Beyond this
binary reuse across IA32 and x64 platform classes, the C code allows for reuse.
The use of this PCH, whether the literal component or the aforementioned
logical integration, on the Itanium Processor, can occur via a recompilation of
the component C code with the Itanium Processor as the target for the binary.
138 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Summary
This chapter has provided an overview of some platforms that are based
upon UEFI and PI firmware technology. The power of the abstractions
of the interfaces comes into play as the firmware can be implemented on a
PC/AT system, Itanium, and non-PC/AT system on a chip (SoC). In addition
to the portability of the abstractions, this chapter has also shown how various
modules are integrated in order to provide a full console and storage stack.
It is through these detailed platform realizations that the composition of the
industry APIs and their interoperation comes into light.
Chapter 8
DXE Basics: Core,
Dispatching, and
Drivers
I do not fear computers. I fear the lack of them.
—Isaac Asimov
139
140 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ DXE Core
■■ DXE Dispatcher
■■ DXE Drivers
The DXE Core produces a set of Boot Services, Runtime Services, and DXE
Services. The DXE Dispatcher is responsible for discovering and executing DXE
drivers in the correct order. The DXE drivers are responsible for initializing
the processor, chipset, and platform components as well as providing software
abstractions for console and boot devices. These components work together
to initialize the platform and provide the services required to boot an OS.
The DXE and Boot Device Selection (BDS) phases work together to establish
consoles and attempt the booting of operating systems. The DXE phase is
terminated when an OS successfully begins its boot process—that is, when the
BDS phase starts. Only the runtime services provided by the DXE Core and
services provided by runtime DXE drivers are allowed to persist into the OS
runtime environment. The result of DXE is the presentation of a fully formed
UEFI interface.
Figure 8.1 shows the phases that a platform with UEFI compatible firmware
goes through on a cold boot. This chapter covers the following:
■■ Transition from the PEI to the DXE phase
Pre
Verifier
Exposed OS-Absent Previously
API App Exposed
PEI
CPU Framework
Core
Init APIs
Now
Transient OS Limited
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Boot OS-Present
DXE App
Dispatcher Dispatcher
Driver Boot
Pre-EFI Execution Device Transient After-
Security Runtime life
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL) (AL)
DXE Core
The DXE Core is designed to be completely portable with no processor, chipset,
or platform dependencies. This portability is accomplished by incorporating
several features:
■■ The DXE Core depends only upon a HOB list for its initial state. This
single dependency means that the DXE Core does not depend on any
services from a previous phase, so all the prior phases can be unloaded
once the HOB list is passed to the DXE Core.
■■ The DXE Core does not contain any hard-coded addresses. As a result,
the DXE Core can be loaded anywhere in physical memory, and it
142 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
PHIT
HOB HOB HOB HOB HOB .. HOB
DXE Drivers
DXE DXE
Drivers Drivers
Architectural Protocols
DXE Foundation
HOB List
Figure 8.2 Early Initialization Illustrating a Handoff between PEI and DXE
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 143
The DXE Core produces the EFI System Table and its associated set of
EFI Boot Services and EFI Runtime Services. The DXE Core also contains the
DXE Dispatcher, whose main purpose is to discover and execute DXE drivers
stored in firmware volumes. The order in which DXE drivers are executed is
determined by a combination of the optional a priori file (see the section on
the DXE dispatcher) and the set of dependency expressions that are associated
with the DXE drivers. The firmware volume file format allows dependency
expressions to be packaged with the executable DXE driver image. DXE drivers
utilize a PE/COFF image format, so the DXE Dispatcher must also contain a
PE/COFF loader to load and execute DXE drivers.
The DXE Core must also maintain a handle database. A handle database
is a list of one or more handles, and a handle is a list of one or more unique
protocol GUIDs. A protocol is a software abstraction for a set of services. Some
protocols abstract I/O devices, and other protocols abstract a common set of
system services. A protocol typically contains a set of APIs and some number of
data fields. Every protocol is named by a GUID, and the DXE Core produces
services that allow protocols to be registered in the handle database. As the
DXE Dispatcher executes DXE drivers, additional protocols are added to the
handle database including the DXE Architectural Protocols that are used to
abstract the DXE Core from platform-specific details.
example shows the different types of system resources that can be described in
a HOB list. The most important ones to the DXE Core are the HOBs that
describe system memory and the HOBs that describe firmware volumes. A
HOB list is always terminated by an end-of-list HOB. The one additional
HOB type that is not shown in Figure 8.3 is the GUID extension HOB that
allows a PEIM to pass private data to a DXE driver. Only the DXE driver
that recognizes the GUID value in the GUID extension HOB can understand
the data in that HOB. The HOB entries are all designed to be position-
independent. This independence allows the DXE Core to relocate the HOB
list to a different location if it is not suitable to the DXE Core.
PHIT
HOB HOB HOB HOB HOB ..... HOB
DXE DXE
Drivers Drivers
The DXE Core is passed a HOB list that must contain a description of
some amount of system memory and at least one firmware volume. The system
memory descriptors in the HOB list are used to initialize the UEFI services that
require only memory to function correctly. The system is also guaranteed to be
running on only one processor in flat physical mode with interrupts disabled.
The firmware volume is passed to the DXE Dispatcher, which must contain a
read-only FFS driver to search for the a priori file and any DXE drivers in the
firmware volumes. When a driver is discovered that needs to be loaded and
executed, the DXE Dispatcher uses a PE/COFF loader to load and invoke the
DXE driver. The early DXE drivers produce the DXE Architectural Protocols,
so the DXE Core can produce the full complement of EFI Boot Services and
EFI Runtime Services. Figure 8.4 shows the HOB list being passed to the
DXE Core. The DXE Core consumes the services of the DXE Architectural
Protocols shown in the figure and then produces the EFI System Table, EFI
Boot Services Table, and the EFI Runtime Services Table.
146 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
PHIT DXE
HOB HOB HOB HOB HOB ..... HOB
Drivers
Hardware
Figure 8.4 shows all the major components present in the DXE phase.
The EFI Boot Services Table and DXE Services Table shown on the left are
allocated from UEFI boot services memory. This allocation means that the EFI
Boot Services Table and DXE Services Table are freed when the OS runtime
phase is entered. The EFI System Table and EFI Runtime Services Table on
the right are allocated from EFI Runtime Services memory, and they do persist
into the OS runtime phase.
The DXE Architectural Protocols shown on the left in Figure 8.4 are used
to produce the EFI Boot Services. The DXE Core, DXE Dispatcher, and
the protocols shown on the left are freed when the system transitions to the
OS runtime phase. The DXE Architectural Protocols shown on the right are
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 147
used to produce the EFI Runtime Services. These services persist in the OS
runtime phase. The Runtime Architectural Protocol in the middle is special.
This protocol provides the services that are required to transition the runtime
services from physical mode to virtual mode under the direction of an OS.
Once this transition is complete, these services can no longer be used.
The following is a brief summary of the DXE Architectural Protocols:
■■ Security Architectural Protocol: Allows the DXE Core to authenticate
files stored in firmware volumes before they are used.
EFI
System
Table
Handle Database …
SAL System Table
Protocol Interface
The DXE Core produces the EFI Boot Services, EFI Runtime Services,
and DXE Services with the aid of the DXE Architectural Protocols. The EFI
System Table provides access to all the active console devices in the platform
and the set of EFI Configuration Tables. The EFI Configuration Tables are
150 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ Real Time Clock Services: Provides services to get and set the current
time and date. It also provides services to get and set the time and date
of an optional wakeup timer. These services depend on the Real Time
Clock Architectural Protocol.
The GCD Services can be broken up into two groups. The first manages
the memory resources visible to the boot processor, and the second manages
the I/O resources visible to the boot processor. Not all processor types support
I/O resources, so the management of I/O resources may not be required.
However, since system memory resources and memory-mapped I/O resources
are required to execute the DXE environment, the management of memory
resources is always required.
■■ AllocateMemorySpace()
■■ FreeMemorySpace()
■■ RemoveMemorySpace()
■■ SetMemorySpaceAttributes()
The GCD Services used to retrieve the GCD memory space map include the
following:
■■ GetMemorySpaceDescriptor()
■■ GetMemorySpaceMap()
The GCD memory space map is initialized from the HOB list that is passed
to the entry point of the DXE Core. One HOB type describes the number
of address lines that are used to access memory resources. This information
is used to initialize the state of the GCD memory space map. Any memory
regions outside this initial region are unavailable to any of the GCD Services
that are used to manage memory resources. The GCD memory space map is
designed to describe the memory address space with as many as 64 address
lines. Each region in the GCD memory space map can begin and end on a byte
boundary. Additional HOB types describe the location of system memory, the
location memory mapped I/O, the location of firmware devices, the location
154 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ System memory
■■ Memory-mapped I/O
■■ Reserved memory
These memory regions can be allocated and freed by DXE drivers executing
in the DXE environment. In addition, a DXE driver can attempt to adjust
the caching attributes of a memory region. Figure 8.6 shows the possible state
transitions for each byte of memory in the GCD memory space map. The
transitions are labeled with the GCD Service that can move the byte from
one state to another. The GCD services are required to merge similar memory
regions that are adjacent to each other into a single memory descriptor, which
reduces the number of entries in the GCD memory space map.
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 155
SetAttributes
Allocated
MMIO
Allocate Free
Allocated Allocated
Reserved MMIO System Memory
Add Add
Free Allocate
SetAttributes
Allocated
Non Existent
■■ AllocateIoSpace()
■■ FreeIoSpace()
■■ RemoveIoSpace()
The GCD Services used to retrieve the GCD I/O space map include the
following:
■■ GetIoSpaceDescriptor()
■■ GetIoSpaceMap()
The GCD I/O space map is initialized from the HOB list that is passed to the
entry point of the DXE Core. One HOB type describes the number of address
lines that are used to access I/O resources. This information is used to initialize
the state of the GCD I/O space map. Any I/O regions outside this initial
region are not available to any of the GCD Services that are used to manage
I/O resources. The GCD I/O space map is designed to describe the I/O address
space with as many as 64 address lines. Each region in the GCD I/O space map
can begin and end on a byte boundary.
An I/O region described by the GCD I/O space map can be in several
different states. These include nonexistent I/O, I/O, and reserved I/O. These
I/O regions can be allocated and freed by DXE drivers executing in the DXE
environment. Figure 8.7 shows the possible state transitions for each byte of
I/O in the GCD I/O space map. The transitions are labeled with the GCD
Service that can move the byte from one state to another. The GCD Services
are required to merge similar I/O regions that are adjacent to each other into
a single I/O descriptor, which reduces the number of entries in the GCD I/O
space map.
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 157
Allocated Allocated
Reserved I/O
Add Add
Free Allocate
Allocated
Non Existent
DXE Dispatcher
After the DXE Core is initialized, control is handed to the DXE Dispatcher.
The DXE Dispatcher is responsible for loading and invoking DXE drivers
found in firmware volumes. The DXE Dispatcher searches for drivers in the
firmware volumes described by the HOB list. As execution continues, other
firmware volumes might be located. When they are, the DXE Dispatcher
searches them for drivers as well.
158 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
When a new firmware volume is discovered, a search is made for its a priori
file. The a priori file has a fixed file name and contains the list of DXE drivers
that should be loaded and executed first. There can be at most one a priori file
per firmware volume, although it is acceptable to have no a priori file at all.
Once the DXE drivers from the a priori file have been loaded and executed, the
dependency expressions of the remaining DXE drivers in the firmware volumes
are evaluated to determine the order in which they will be loaded and executed.
The a priori file provides a strongly ordered list of DXE drivers that are not
required to use dependency expressions. The dependency expressions provide
a weakly ordered execution of the remaining DXE drivers. Before each DXE
driver is executed, it must be authenticated with the Security Architectural
Protocol. This authentication prevents DXE drivers with unknown origins
from being executed.
Control is transferred from the DXE Dispatcher to the BDS Architectural
Protocol after the DXE drivers in the a priori file and all the DXE drivers whose
dependency expressions evaluate to TRUE have been loaded and executed.
The BDS Architectural Protocol is responsible for establishing the console
devices and attempting the boot of operating systems. As the console devices
are established and access to boot devices is established, additional firmware
volumes may be discovered. If the BDS Architectural Protocol is unable to
start a console device or gain access to a boot device, it reinvokes the DXE
Dispatcher. This invocation allows the DXE Dispatcher to load and execute
DXE drivers from firmware volumes that have been discovered since the last
time the DXE Dispatcher was invoked. Once the DXE Dispatcher has loaded
and executed all the DXE drivers it can, control is once again returned to
the BDS Architectural Protocol to continue the OS boot process. Figure 8.8
illustrates this basic flow between the Dispatcher, its launched drivers, and the
BDS.
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 159
HOB List
DXE Foundation
DXE Dispatcher
DXE Drivers
H
AS
FL
Figure 8.8 The Handshake between the Dispatcher and Other Components.
160 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Dependency Grammar
A DXE driver is stored in a firmware volume as a file with one or more
sections. One of the sections must be a PE/COFF image. If a DXE driver has a
dependency expression, then it is stored in a dependency section. A DXE driver
may contain additional sections for compression and security wrappers. The
DXE Dispatcher can identify the DXE drivers by their file type. In addition,
the DXE Dispatcher can look up the dependency expression for a DXE driver
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 161
Opcode Description
DXE Drivers
DXE drivers have two subclasses:
■■ DXE drivers that execute very early in the DXE phase
■■ The DXE Dispatcher does not have any more DXE drivers to load
and execute. This condition occurs only when all the a priori files
from all the firmware volumes have been processed and all the DXE
drivers whose dependency expression have evaluated to TRUE have
been loaded and executed.
The BDS Architectural Protocol locates and loads various applications that
execute in the pre-boot services environment. Such applications might
represent a traditional OS boot loader or extended services that might run
instead of or prior to loading the final OS. Such extended pre-boot services
might include setup configuration, extended diagnostics, flash update support,
OEM services, or the OS boot code.
Vendors such as IBVs, OEMs, and ISVs may choose to use a reference
implementation, develop their own implementation based on the reference, or
develop an implementation from scratch.
The BDS phase performs a well-defined set of tasks. The user interface and
user interaction that occurs on different boots and different platforms may
vary, but the boot policy that the BDS phase follows is very rigid. This boot
policy is required so OS installations will behave predictably from platform to
platform. The tasks include the following:
■■ Initialize console devices based on the ConIn, ConOut, and
StdErr environment variables.
Console Devices
Console devices are abstracted through the Simple Text Output and Simple
Input Protocols. Any device that produces one or both of these protocols may
be used as a console device on a UEFI-based platform. Several types of devices
are capable of producing these protocols, including the following:
■■ VGA Adapters: These adapters can produce a text-based display that
is abstracted with the Simple Text Output Protocol.
■■ Serial Terminal: A serial terminal device can produce both the Simple
Input and Simple Text Output Protocols. Serial terminals are very
flexible, and they can support a variety of wire protocols such as PC
ANSI, VT-100, VT-100+, and VTUTF8.
Chapter 8: DXE Basics: Core, Dispatching, and Drivers n 165
■■ Telnet: A telnet session can produce both the Simple Input and
Simple Text Output Protocols. Like the serial terminal, a variety of
wire protocols can be supported including PC ANSI, VT-100, VT-
100+, and VTUTF8.
Boot Devices
Several types of boot devices are supported in UEFI:
■■ Devices that produce the Block I/O Protocol and are formatted with
a FAT file system
Summary
In conclusion, the DXE phase encompasses the establishing of the entire
infrastructure necessary for UEFI compliant components to operate. This
includes the establishment of the service tables and other requisite architectural
protocols. As the DXE phase completes and passes control to the BDS, the
platform then proceeds to complete any initialization required to launch of
boot target.
Chapter 9
Some Common
UEFI and PI Functions
Never let the future disturb you. You will meet it, if you have to, with the
same weapons of reason which today arm you against the present.
—Marcus Aurelius Antoninus
U EFI provides a variety of functions that are used for drivers and
applications to communicate with the underlying UEFI components.
Many of the designs for interfaces have historically been short-sighted due
to their inability to predict changes in technology. An example of such
shortsightedness might be where a disk interface assumed that a disk might
never have more than 8 gigabytes of space available. It is often hard to predict
what changes technology might provide. Many famous statements have been
made that fret about how a personal computer might never be practical, or
assure readers that 640 kilobytes of memory would be more than anyone
would ever need. With these poor past predictions in mind, one can attempt
to learn from such mistakes and design interfaces that are robust enough for
common practices today, and make the best attempt at predicting how one
might use these interfaces years from today.
This chapter describes a selection of common interfaces that show up in
UEFI as well as the PI specifications:
■■ Architectural Protocols: These are a set of protocols that abstract the
platform hardware from the UEFI drivers and applications. They are
unusual only in that they are the protocols that are going to be used
167
168 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ Disk I/O: This protocol is used to abstract the block accesses of the
Block I/O protocol to a more general offset-length protocol. The
firmware is responsible for adding this protocol to any Block I/O
interface that appears in the system that does not already have a Disk
I/O protocol. File systems and other disk access code utilize the Disk
I/O protocol. This interface was introduced for UEFI, and would be
present in both UEFI and PI implementations.
■■ Simple File System: This protocol allows code running in the EFI
Boot Services environment to obtain file-based access to a device.
The Simple File System protocol is used to open a device volume and
return an EFI_FILE handle that provides interfaces to access files on
a device volume. This interface was introduced for UEFI, and would
be present in both UEFI and PI implementations.
and are the only agents in the system that would typically talk directly to the
hardware in the pre-boot environment. Everything else in the system would
communicate with a core service to communicate any sort of requests to the
hardware. Figure 9.1 illustrates this high level software handshake.
DXE Drivers
Architectural Protocols
Core Services
DXE
Applications
Boot Device
Driver Execution Environment (DXE) Selection
(BDS)
Platform Initialization O/S Boot
To show more clearly how some of these architectural protocols are designed
and how they operate, several key examples will be examined in further detail.
Note that the following examples are not the full set of architectural protocols
but are used to illustrate some of their functionality. For the full set, please refer
to the appropriate DXE specifications.
170 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
be modified, and if they can, the GCD memory space map will be updated
accordingly.
The CPU Architectural Protocol uses the following protocol definition:
OS
Booted
EFI
OS Loader
Boot Code
Failure
St d d
Standard Drivers
Di andd Boot
B t from
f
firmware applications ordered list
platform loaded of EFI operating
initialization iteratively system loaders
and SetVariable() fields of the EFI Runtime Services Table. See the
section “Variable Services” in Chapter 5 for details on these services. After
the three fields of the EFI Runtime Services Table have been initialized, the
driver must install the Variable Architectural Protocol on a new handle with
a NULL interface pointer. The installation of this protocol informs the DXE
Foundation that the read-only and the volatile environment variable related
services are now available and that the DXE Foundation must update the
32-bit CRC of the EFI Runtime Services Table. The full complement of
environment variable services is not available until both this protocol and
Variable Write Architectural Protocol are installed. DXE drivers that require
read-only access or read/write access to volatile environment variables must
have this architectural protocol in their dependency expressions. DXE drivers
that require write access to nonvolatile environment variables must have the
Variable Write Architectural Protocol in their dependency expressions.
PCI Protocols
This section describes a series of protocols that are all related to abstracting
various aspects of PCI related interaction such as resource allocation and I/O.
details. This design allows system designers to make changes to the host bridge
hardware without impacting a platform independent PCI bus driver.
Figure 9.3 shows a platform with a set of processors (CPUs) and a set
of core chipset components that produce n host bridges. Most systems with
one PCI host bus controller contain a single instance of the PCI Host Bridge
Allocation Protocol. More complex systems may contain multiple instances of
this protocol.
Figure 9.4 shows how the PCI Host Bridge Resource Allocation Protocol
is used to identify the associated PCI root bridges. After the steps shown in
Figure 9.4 are completed, the PCI Host Bridge Resource Allocation Protocol
can then be queried to identify the device handles of the associated PCI root
bridges.
Chapter 9: Some Common UEFI and PI Functions n 179
Protocol is placed on
the device handle
corresponding to the
PCI host bridge.
Figure 9.4 Producing the PCI Host Bridge Resource Allocation Protocol
PCI RB PCI RB
PCI RB PCI RB
Figure 9.8 Sample Server System with Two PCI Host Buses
Figure 9.8 shows a server system with two PCI host buses and one PCI root
bridge (RB) per PCI host bus. Like the server system with 2 PCI segments,
this system supports up to 512 PCI buses, but the following resources are not
shared between the two PCI root bridges:
■■ PCI I/O space
} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;
■■ Mem – Allows reads and writes for memory mapped I/O space.
■■ Configuration – Gets the current resource settings for this PCI root
bridge.
PCI I/O
The interfaces provided in the PCI I/O Protocol are for performing basic
operations to memory, I/O, and PCI configuration space. The system
provides abstracted access to basic system resources to allow a driver to have a
programmatic method to access these basic system resources. The main goal of
this protocol is to provide an abstraction that simplifies the writing of device
drivers for PCI devices. This goal is accomplished by providing the following
features:
■■ A driver model that does not require the driver to search the PCI
busses for devices to manage. Instead, drivers are provided the location
of the device to manage or have the capability to be notified when a
PCI controller is discovered.
■■ The Device Path for the PCI device can be obtained from the same
device handle that the PCI I/O Protocol resides.
186 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ The PCI Segment, PCI Bus Number, PCI Device Number, and PCI
Function Number of the PCI device if they are required. The general
idea is to abstract these details away from the PCI device driver.
However, if these details are required, then they are available.
■■ Access to the PCI Root Bridge I/O Protocol for the PCI Host Bus for
which the PCI device is a member.
■■ Mem – Allows BAR relative reads and writes for PCI memory space.
■■ Io – Allows BAR relative reads and writes for PCI I/O space.
■■ Pci – Allows PCI controller relative reads and writes for PCI
configuration space.
Block I/O
The Block I/O Protocol is used to abstract mass storage devices to allow code
running in the UEFI boot services environment to access them without specific
knowledge of the type of device or controller that manages the device. Functions
are defined to read and write data at a block level from mass storage devices as
well as to manage such devices in the UEFI boot services environment.
The Block interface constructs a logical abstraction of the storage device.
Figure 9.9 shows how a typical device that has multiple partitions will have
a variety of Block interfaces constructed on it. For example, a partition that
is a logical designation of how a disk might be apportioned will have a block
interface for it. It should be noted that a particular storage device will have a
block interface that has a scope that spans the entire storage device, and the
logical partitions will have a scope that is a subset of the device. For instance,
in the example shown in Figure 9.8, Block I/O #1 has access to the entire disk,
while Block I/O #2 has its first LBA starting at the physical location of the
partition it is associated with.
Chapter 9: Some Common UEFI and PI Functions n 189
#2 #1 #3
Block I/O
DISK
Partition Partition
Partition Partition
Pointers to Pointers to
partitions partitions
EFI_BLOCK_IO_MEDIA *Media;
EFI_BLOCK_RESET Reset;
EFI_BLOCK_READ ReadBlocks;
EFI_BLOCK_WRITE WriteBlocks;
EFI_BLOCK_FLUSH FlushBlocks;
} EFI_BLOCK_IO_PROTOCOL;
BOOLEAN LogicalPartition;
BOOLEAN ReadOnly;
BOOLEAN WriteCaching;
UINT32 BlockSize;
UINT32 IoAlign;
EFI_LBA LastBlock;
} EFI_BLOCK_IO_MEDIA;
Disk I/O
The Disk I/O protocol is used to abstract the block accesses of the Block I/O
protocol to a more general offset-length protocol. The firmware is responsible
for adding this protocol to any Block I/O interface that appears in the system
that does not already have a Disk I/O protocol. File systems and other disk
access code utilize the Disk I/O protocol.
The disk I/O functions allow I/O operations that need not be on the
underlying device’s block boundaries or alignment requirements. This is done
by copying the data to/from internal buffers as needed to provide the proper
requests to the block I/O device. Outstanding write buffer data is flushed by
using the Flush() function of the Block I/O protocol on the device handle.
Chapter 9: Some Common UEFI and PI Functions n 191
The firmware automatically adds a Disk I/O interface to any Block I/O
interface that is produced. It also adds file system, or logical block I/O,
interfaces to any Disk I/O interface that contains any recognized file system
or logical block I/O devices. UEFI compliant firmware must automatically
support the following required formats:
■■ The UEFI FAT12, FAT16, and FAT32 file system type.
■■ The legacy master boot record partition block. (The presence of this
on any block I/O device is optional, but if it is present the firmware is
responsible for allocating a logical device for each partition).
■■ Revision – The revision to which the disk I/O interface adheres. All
future revisions must be backwards compatible. If a future version is
not backwards compatible, it is not the same GUID.
Block I/O
DISK
Partition Partition
Partition Partition
FAT 32
Pointers to Pointers to
partitions partitions
■■ Revision – The version of the EFI Simple File System Protocol. The
version specified by this specification is 0x00010000. All future
revisions must be backward compatible. If a future version is not
backward compatible, it is not the same GUID.
■■ Flush – Flushes all modified data associated with the file to the device.
Configuration Infrastructure
The modern UEFI configuration infrastructure that was first described in the
UEFI 2.1 specification is known as the Human Interface Infrastructure (HII).
HII includes the following set of services:
■■ Database Services. A series of UEFI protocols that are intended to
be an in-memory repository of specialized databases. These database
services are focused on differing types of information:
–– Database Repository – This is the interface that drivers interact
with to manipulate configuration related contents. It is most
often used to register data and update keyboard layout related
information.
Chapter 9: Some Common UEFI and PI Functions n 195
the device by both local and remote agents as well as BIOS and OS-
present components.
1
HII
Database
EFI
Image Handle Loaded Image Protocol
3
Driver Binding Protocol
2
Configuration Access Protocol 4
EFI I/O Controller
Device Handle
Device Path Protocol
Figure 9.11 A Single Driver that Is Registering Its Configuration Data and
Establishing Its Environment in a Recommended Fashion
3 1
n MB file
data
Download configuration
Provisioning Scenario
Figure 9.13 Remote Interaction Occurs with a Target System; the System in Turn
Accesses the Configuration Abstractions Associated with a Device or
Set of Devices
Summary
In conclusion, this chapter describes a series of the common protocols one
would encounter in a UEFI enabled platform, and also highlights the common
scenarios where one would leverage their use. With these protocols, one should
be armed well for the future environments (both hardware and software) that
will be encountered as the platform ecosystem evolves.
204 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 10
Platform Security
and Trust
We will bankrupt ourselves in the vain search for absolute security.
—Dwight D. Eisenhower
205
206 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Trust Overview
We begin the discussion of trusted platforms with some background on trust—
specifically, the definition of trust, and some related concepts, measurement and
security:
■■ Trust. An entity can be trusted if it always behaves in the expected
manner for the intended purpose.
Reliability
Safety
Confidentiality
Integrity
Availability
Where should the solution reside, given the problems to be solved and
some of the capabilities like security, trust, and measurement to help effect the
solution?
In fact, the implementation of trust and security entail a security architecture
that spans the entire system, starting at the base with hardware and spanning
all of the way to the end-user application.
Figure 10.2 shows all of the layers of a security architecture. The network
layer is broken out with a few examples, such as protocols (SSL, IPSec);
this chapter does not delve too deeply into this layer. The firmware layer is
highlighted to show that a single-layer of security is not sufficient.
Security Architecture
Hum
man U
m User
GUI
App
plicatttion
p on
n
Lib
brari
brarie
riie
riees
e
Driver
Dr
Dri
D riverrrs
Ne
etw
etwo
worrk
wo SSL, IPsec, etc.
O
OS
Firrrmwa
are
a Single Layer “Security”
Ha
ardwa
a are
a
In fact, the scope of this chapter largely treats firmware. Some description
of hardware elements and interaction are provided. Figure 10.3 highlights the
area that this chapter discusses in more depth.
208 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Human User
GUI
Application
Libraries
Drivers
Network
OS
Firmware
Hardware
As seen in Figure 10.3, all layers are important, but if you do not have
firmware/hardware assurance, you cannot have a security architecture. As
the logicians would say, it’s “necessary but not sufficient” to have appropriate
design in these layers. And as will be described later, the layer of hardware and
firmware provide a “root of trust” for the rest of the security architecture.
So now that we have trust, security, measurement, and a layered picture of
the security architecture, the goals of the security architecture and assets that
are protected are as follows.
The first security goal is integrity, and this entails the protection of content
and information from unauthorized modification. The next goal is authenticity,
and this provides guarantee or assurance in the source of the code or data.
Another important goal is availability, or the ability to ensure behavior and
the responsiveness of the system. Availability also protects from destruction or
denial of access. And finally, another goal is confidentiality, or the protection of
information from unauthorized access.
Through the subsequent discussion of trusted platforms and UEFI, some
of these integrity, authenticity, and availability goals will be discussed in more
detail.
Chapter 10: Platform Security and Trust n 209
TPM must carry out in service of the host. Figure 10.4 shows some of the
specifications that describe the TPM and its integration into the platform.
Common
Evaluation
PC Platform Server Mobile Phone Other Methodology
Specification Specification Specification Platform
PC Platform
atfor
om Server
Serve
Se Mobile Phone Other
lia
aEFI
ance
ncePlatform
Compliance Compli
Comp& lil a
Compliance Compliance Compliance
Protocol
Specifications
ISO-15408 Common Criteria
Protection Profiles
Figure 10.6 is a picture of the elements that are typically found within a
TPM. The protected execution and storage of the TPM allow for hosting the
RSA asymmetric key pairs, such as the endorsement key (EK), the attestation
identity key (AIK), and storage root keys (SRKs). Recall that in RSA
cryptography, the public key can be known to all, but the private key must
be shrouded from users. The TPM and its isolated execution can both host
the key-pairs and keep the private RSA keys away from attacks/errant agents
on the host. In today’s platforms without a TPM, only a custom hardware
security module (HSM) or other additional hardware can be used for hosting
key-pairs. But in these latter solutions, there is no guarantee on construction
of platform, surety of the host interface, and so on. The Trusted Computing
Group attempts to both describe the requirements on the TPM and the binding
into the platform in order to have a trusted building block (TBB) via design
guides, protection profiles, conformance tests, and so on.
212 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
I/O
Opt-In
Volatile
Storage
SHA-1
Platform RNG
Configuration RSA Key
Register (PCR) Engine Generation
AIK
Packaging
■■ SRTM
–– Static root of trust for measurement
–– CRTM (CRTM) + platform firmware measuring all code and
data prior to boot
–– Records information into non-resettable or “static” PCRs (0-15);
Described by TCG BIOS and UEFI specifications
■■ DRTM
–– Dynamic root of trust for measurement
–– Initiate the measurement later in boot. Includes resettable PCRs
16 and above; these resettable PCRs zeroed upon initiation of the
DRTM launch
■■ Physical presence
–– Administrative model of the TPM. Assertion by operator of
presence in order to perform privacy or administrative activities
with the TPM.
In general, a hardware instantiation of the trusted platform module (TPM) is
a passive hardware device on the system board. It serves as the root of trust for
storage (RTS) and root of trust for reporting (RTR). The former is the use of
the storage root key (SRK) and the Platform Configuration Registers (PCRs).
Figure 10.7 shows the synthesis of the various roots in the platform.
Chapter 10: Platform Security and Trust n 215
The active agent on the platform is the root of trust for measurement
(RTM). The RTM can be either static or dynamic (SRTM versus DRTM,
respectively). The SRTM, on the other hand, entails the creation of a trust
chain from the platform reset vector going forward.
The definition of the SRTM for UEFI is defined in the UEFI TCG
Protocol Specification and the TCG UEFI Platform Specification. The flow of
the SRTM into the operating system is shown in Figure 10.8.
216 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Static RTM
RTS / Measurement and execution of
RTR Framework/EFI, BIOS, Option
(TPM) ROM, IPL, etc.
S
Static
OS
There need to be UEFI APIs available so that the UEFI OS loader can
continue to measure the operating system kernel, pass commands to the
TPM to possibly unseal a secret, and perform other TPM actions prior to the
availability of the OS TPM driver. In addition, this API can be installed at
the beginning of DXE to enable measurement of the DXE and UEFI images.
Figure 10.9 shows where the UEFI TCG APIs would appear relative to the
other interfaces.
Chapter 10: Platform Security and Trust n 217
OPERATING SYSTEM
TCG API
Compatibility UEFI BOOT SERVICES UEFI
RUNTIME
Boot
Driver
Memory
Devices SERVICES
Timer
Protocols +
Handlers
(OTH
(O
(OTHER)
THER
ER))
SMBIOS
SMBI
SM BIOS
OS
ACPI
ACPI PLATFORM INITIALIZATION FIRMWARE (BIOS/SAL/PIWG)
Interfaces
From
Other PLATFORM HARDWARE
Required
Specs
The UEFI specifications are cross-listed in the TCG PC and Server Working
Groups such that both consumer and enterprise-class operating systems can
participate in this boot flow behavior.
The UEFI TCG Platform specification describes which objects to measure
in a UEFI system, such as the images, on-disk data structures, and UEFI
variables. Figure 10.10 shows which objects in a UEFI system correspond to
measures in PCRs.
218 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
PCR8
+ OPERATING SYSTEM
PLATFORM HARDWARE
PCR5
Prior to the UEFI phase of platform execution, the PI describe the PEI
and DXE phases. In these phases the CRTM is mapped to the PEI phase and
what is thought of as BIOS POST is mapped to DXE. There are interfaces
in PEI (namely, the PEIM-to-PEIM interface, or PPI) to allow for fine-grain
measurement in that phase of execution, too. Figure 10.11 shows one possible
PEI-based CRTM and the flow into the operating system.
Chapter 10: Platform Security and Trust n 219
OS Environment
TPM Init
OpROM Scan ASL Code
Measure
SHA1 Algo FV_MAIN
Measure ROMs Legacy Boot,
Measure IPL,
Physical Update PCR4,
PCR, Event Update PCR2,
Presence Log Events, etc.
Log Log Event.
FV_MAIN
SEC FV_REC
PEI DXE BDS OS
S-CRTM
in the chapter we’ll talk about additional practices to complement the SDL
that address domain-specific issues with platform firmware.
With all these elements of security and protections in place how the
CRTM is updated becomes critical and much more challenging. Since the
CRTM is the root, and is itself inherently trusted, it must be a very controlled
and secure process. The TCG describes CRTM maintenance in the Trusted
Building Block (TBB) protection profile. Either the CRTM is immutable, or
never changed in the field, or appropriate cryptographic techniques need to be
employed in order to update the CRTM.
Regarding the cryptographic-based update, Figure 10.12 shows a possible
implementation where the firmware volume (FV) update is enveloped using
an RSA-2048/SHA-256-based update. This is just one possible UEFI PI
implementation that leverages the UEFI PI-based firmware volume construct
and the WIN_CERT that can be found in the UEFI 2.0 specification.
Today’s
Capsule
Capsule FV
FV to be
Updated
Capsule
WIN_CERT w/
Signature of Capsule FV
Signature of the FV
GUID of the
Capsule Update
Operating System
UEFI Shell
Boot Manager
UEFI Services
Platform Initialization
UEFI
Executable
To
Verifier
UEFI Hash Signing Digital
Hash Result
Executable Function Function Signature
Private Key
Public Key
UEFI Networking
Another element that appears in UEFI entails additional network security,
including IPsec support. Trusted hardware like the TPM can be used to help
store the IPsec credentials, but to be stronger, assurance around the UEFI
firmware implementation of the IPsec cryptography and the networking code
will need to follow the guidelines in the preceding portion of this chapter. IPsec
can be used for platform network boot to harden scenarios such as ISCSI-based
provisioning.
Figure 10.16 shows the EFI IPsec implementation using the UEFI IPsec
protocol and IPV6 network stack, including a pre-deployed security association
(SA).
Chapter 10: Platform Security and Trust n 225
EFI Drivers
EFI_IP6_PROTOCOL
TCP6 Driver UDP6 Driver
IP6_CONFIG_PROTOCOL
By Child By Child EFI_IPSEC_CONFIG
Outbound Packet
Update
IP6 Driver Find SA, and Encapsulate AH/ESP
SPD/SAD DB ND MLD Header per SA Info
IPsec DB ICMPV6
SPD, SAD AH/ESP
Find SA, and Process AH/ESP
Header
Inbound Packet
By Proto
By Child
MNP Crypto Driver
IPsec in the platform will allow for performing both an IPV4 and IPV6-
based iSCSI boot and provisioning. Figure 10.17 shows an iSCSI layering on
top of the UEFI network stack, for example.
226 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
iSCSI
DHCP4 DHCP6
IP4CONFIG_SB
DHCP4_SB IP6CONFIG_SB
TCP4_SB DHCP6_SB By Child
UDP_SB TCP6_SB
IP4_SB UDP6_SB
ARP_SB IP6_SB
NIC MNP_SB
Beyond the IP6 and IPsec UEFI interfaces, the wire-protocol for network
booting has commensurate evolution to the UEFI APIs. Specifically, in the
DHCPv6 extensions for IPV6 network booting, the boot file information is
sent as a Uniform Resource Locator (URL); the network boot option details
are described in both the UEFI 2.3 specification and in IETF Request For
Comment (RFC) 5970. As such, the UEFI client machine and the boot server
Chapter 10: Platform Security and Trust n 227
can negotiate various types of downloads, including TFTP, FTP, HTTP, NFS,
or iSCSI. This allows the network capabilities to track the needs of the market
and the machine’s firmware capabilities.
Operating System
Fingerpint Sensor
User Identity
Boot Manager Password
Manager
Smart Card
UEFI Services
Platform Initialization
Implementation of these UEFI features would also build upon and require
the assurance/best practices in firmware discussed earlier. More information on
the UEFI-based features can be found in the UEFI main specification.
228 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
INT
PCR PCR 19 PCR Boot PCR OS PCR VMM PCR
CRTM Ext Ext BIOS MBR Ext Ext Ext Ext
end end end Loader end Loader end Loader end
Platform
Reset D-RTM (Late Launch)
Platform Manufacturer
There are several terms that will be introduced in order to facilitate the following
discussion. The first includes the entity that produces the final system board
that includes the collection of UEFI and PI modules shown in Figure 10.20.
This will be called the platform manufacturer or PM. The authority to perform
updates or changes to the configuration of the UEFI and PI modules that
ship from the factory are mediated by PM_AUTH or Platform Manufacturer
Authority. PM_AUTH essentially describes the administrative roles that an
entity who authenticates or proves itself to be the PM or delegate of the PM
can perform. These actions can include but are not limited to the update of
modules, firmware, or early PI settings. PM_AUTH typically is used to ensure
the integrity of the PI and UEFI modules, and this integrity, or ensuring that the
modules came from the manufacturer, can be accomplished via cryptographic
updates of modules or signed UEFI capsules, for example.
As noted above, integrity forms one of the key security goals of the
platform. If a third party can replace or impersonate a PI module without the
PM’s knowledge, there is an opportunity to introduce a vulnerability into the
system.
230 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Temp UEFI
Startup Ram Interfaces
&
Boundary OS-Absent
PEI for PM_AUTH
Core App
CPU
Init UEFI Shell
Device,
Chipset Bus, or
Init Service
Driver Transient OS
Boot Loader
Board
Init
Boot OS-Present
EFI Driver App
Dispatcher Manager
Final OS Final OS
Architectural Boot Loader Environment
Protocols
Driver Boot
Security Pre-EFI Execution Device Transient Run Time
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL)
or upgrade, or a PC/AT option ROM from a host bus adapter plugged into a
system.
So for this model of integrity analysis, PM_AUTH = {SEC, PEI Core,
PEIMs, DXE core, DXE drivers, firmware volumes, UEFI variables used only
by PEI + DXE, BDS, PMI, SMM, UEFI runtime, ACPI tables, SMBIOS
tables}.
Non-PM_AUTH is non-signed UEFI drivers from a host-bus adapter
(HBA), non-signed UEFI OS loaders.
Vulnerability Classification
There are several terms that will be introduced in this section. These include
spoofing, tampering, repudiation, information disclosure, denial of service,
and elevation of privilege.
In order to talk about platform security, some terms will be introduced.
Specifically, a vulnerability in a software or firmware product can subject the
computer on which it is running to various attacks. Attacks may be grouped in
the following categories:
■■ Spoofing. An attacker pretends that he is someone else, perhaps in order
to inflict some damage on the person or organization impersonated.
Roots of Trust/Guards
When discussing integrity, a more formal model helps define some of the
terms. A popular commercial integrity model includes that defined by Clark-
Wilson (CW). In the CW model, there are controlled data items (CDIs) and
uncontrolled data items (UDIs). The former must have some administrative
control for changes, whereas the latter do not.
An example of a UDI can include a UEFI variable like the language code,
whereas a CDI can include an authenticated variable such as the signature
data base used for managing the x509V3 certificates. Figure 10.21 shows an
example of a CDI, such as UEFI variables, and the Guard. Typically the caller
would be a UEFI or OS application, the “request” would be the “set variable,”
the Guard would be the UEFI implementation of the variable services, and
the variable itself could include the EFI_VARIABLE_AUTHENTICATED_
WRITE_ACCESS bit set.
Summary
This chapter has reviewed the static root of trust for measurement, or trusted
boot, and the associated trusted computing hardware, including the TPM. It
then described other preventive security technology, such as UEFI secure boot.
Chapter 10: Platform Security and Trust n 233
U EFI has over time evolved a very basic paradigm for establishing a
firmware policy engine. The concept was developed from the concept
of a single boot manager whose sole purpose was exercising the policy
established by some architecturally defined global NVRAM variables. As the
firmware design evolved, and several distinct boot phases such as SEC, PEI,
DXE, BDS, Runtime, and Afterlife were defined, the BDS (Boot Device
Selection) phase became a distinct boot manager-like phase. In this chapter,
the architectural components that steer the policy of the boot manager are
reviewed. This content forms the architectural basis for what eventually
became the BDS phase.
In fact, the differences between what is known as the boot manager in
earlier firmware designs and what is known as the BDS in PI-based solutions
is easy to illustrate. Figure 11.1 shows the software flow in an early firmware
design environment, and Figure 11.2 shows one that is PI-compatible.
235
236 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Reset
Vector Exposed
Runtime OS-Absent
Interface App
PEI
CPU
Core
Init
Chipset Transient OS
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Boot OS-Present
Manager App
Final OS Final OS
Boot Loader Environment ?
Pre
Verifier Exposed
Platform OS-Absent
Interfaces App
PEI
CPU
Core
Init
Transient OS
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Boot OS-Present
EFI Driver App
Dispatcher Manager
Driver Boot
Pre-EFI Execution Device Transient After-
Security Runtime life
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL) (AL)
As you can see from comparing the two figures, there is much overlap.
The BDS phase subsumes the direction described in this chapter and is further
explained in Chapter 8.
The UEFI boot manager is a firmware policy engine that can be configured
by modifying architecturally defined global NVRAM variables. The boot
manager attempts to load UEFI drivers and UEFI applications (including
UEFI OS boot loaders) in an order defined by the global NVRAM variables.
The platform firmware must use the boot order specified in the global NVRAM
variables for normal boot. The platform firmware may add extra boot options
or remove invalid boot options from the boot order list.
The platform firmware may also implement value-added features in the
boot manager if an exceptional condition is discovered in the firmware boot
process. One example of a value-added feature would be not loading a UEFI
driver if booting failed the first time the driver was loaded. Another example
238 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ The variable also contains a pointer to the hardware device and to a file
on that hardware device that contains the UEFI image to be loaded.
■■ The variable might also contain paths to the OS partition and di-
rectory along with other configuration-specific directories.
The NVRAM can also contain load options that are passed directly to the
UEFI image. The platform firmware has no knowledge of what is contained
in the load options. The load options are set by higher level software when it
writes to a global NVRAM variable to set the platform firmware boot policy.
This information could be used to define the location of the OS kernel if it was
different than the location of the UEFI OS loader.
that comprise all of the published load options among the UEFI environment
variables. By using the SetVariable() function the data that contain
these environment variables can be modified.
Each load option entry resides in a Boot#### variable or a Driver####
variable where the #### is replaced by a unique option number in printable
hexadecimal representation using the digits 0–9, and the uppercase versions
of the characters A–F (0000–FFFF). The #### must always be four digits,
so small numbers must use leading zeros. The load options are then logically
ordered by an array of option numbers listed in the desired order. There are
two such option ordering lists. The first is DriverOrder that orders the
Driver#### load option variables into their load order. The second is
BootOrder that orders the Boot#### load options variables into their
load order.
For example, to add a new boot option, a new Boot#### variable would
be added. Then the option number of the new Boot#### variable would be
added to the BootOrder ordered list and the BootOrder variable would
be rewritten. To change boot option on an existing Boot####, only the
Boot#### variable would need to be rewritten. A similar operation would
be done to add, remove, or modify the driver load list.
If the boot via Boot#### returns with a status of EFI_SUCCESS the
boot manager stops processing the BootOrder variable and presents a boot
manager menu to the user. If a boot via Boot#### returns a status other
than EFI_SUCCESS, the boot has failed and the next Boot#### in the
BootOrder variable will be tried until all possibilities are exhausted.
The boot manager may perform automatic maintenance of the database
variables. For example, it may remove unreferenced load option variables,
any unparseable or unloadable load option variables, and rewrite any ordered
list to remove any load options that do not have corresponding load option
variables. In addition, the boot manager may automatically update any ordered
list to place any of its own load options where it desires. The boot manager can
also, based on its platform-specific behavior, provide for manual maintenance
operations as well. Examples include choosing the order of any or all load
options, activating or deactivating load options, and so on.
The boot manager is required to process the Driver load option entries
before the Boot load option entries. The boot manager is also required to
initiate a boot of the boot option specified by the BootNext variable as
240 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
the first boot option on the next boot, and only on the next boot. The boot
manager removes the BootNext variable before transferring control to the
BootNext boot option. If the boot from the BootNext boot option fails
the boot sequence continues utilizing the BootOrder variable. If the boot
from the BootNext boot option succeeds by returning EFI_SUCCESS the
boot manager will not continue to boot utilizing the BootOrder variable.
The boot manager must call LoadImage(), which supports at least
SIMPLE_FILE_PROTOCOL and LOAD_FILE_PROTOCOL for resolving
load options. If LoadImage() succeeds, the boot manager must enable the
watchdog timer for 5 minutes by using the SetWatchdogTimer() boot
service prior to calling StartImage(). If a boot option returns control to
the boot manager, the boot manager must disable the watchdog timer with an
additional call to the SetWatchdogTimer() boot service.
If the boot image is not loaded via LoadImage(), the boot manager
is required to check for a default application to boot. Searching for a default
application to boot happens on both removable and fixed media types. This
search occurs when the device path of the boot image listed in any boot option
points directly to a SIMPLE_FILE_SYSTEM device and does not specify the
exact file to load. The file discovery method is explained in the section “Default
Behavior for Boot Option Variables” later in this chapter. The default media
boot case of a protocol other than SIMPLE_FILE_SYSTEM is handled by the
LOAD_FILE_PROTOCOL for the target device path and does not need to be
handled by the boot manager.
The boot manager must also support booting from a short-form device path
that starts with the first element being a hard drive media device path. The boot
manager must use the GUID or signature and partition number in the hard
drive device path to match it to a device in the system. If the drive supports
the GPT partitioning scheme the GUID in the hard drive media device path is
compared with the UniquePartitionGuid field of the GUID Partition
Entry. If the drive supports the PC-AT MBR scheme the signature in the hard
drive media device path is compared with the UniqueMBRSignature in the
Legacy Master Boot Record. If a signature match is made, then the partition
number must also be matched. The hard drive device path can be appended to
the matching hardware device path and normal boot behavior can then be used.
If more than one device matches the hard drive device path, the boot manager
picks one arbitrarily. Thus the operating system must ensure the uniqueness of
the signatures on hard drives to guarantee deterministic boot behavior.
Chapter 11: Boot Device Selection n 241
UINT32 Attributes;
UINT16 FilePathListLength;
CHAR16 Description[];
EFI_DEVICE_PATH FilePathList[];
UINT8 OptionalData[];
■■ Attributes – The attributes for this load option entry. All unused bits
must be zero and are reserved by the UEFI specification for future
growth. See “Related Definitions.”
■■ Description – The user readable description for the load option. This
field ends with a Null Unicode character.
Related Definitions
The load option attributes are defined by the values below.
//
// Attributes
//
#define LOAD_OPTION_ACTIVE 0x00000001
#define LOAD_OPTION_FORCE_RECONNECT 0x00000002
Globally-Defined Variables
This section defines a set of variables that have architecturally defined meanings.
In addition to the defined data content, each such variable has an architecturally
defined attribute that indicates when the data variable may be accessed. The
variables with an attribute of NV are nonvolatile. This means that their values
are persistent across resets and power cycles. The value of any environment
variable that does not have this attribute will be lost when power is removed
from the system and the state of firmware reserved memory is not otherwise
preserved. The variables with an attribute of BS are only available before
Chapter 11: Boot Device Selection n 243
#define EFI_GLOBAL_VARIABLE \
{8BE4DF61-93CA-11d2-AA0D-00E098032B8C}
second logical boot option, and so on. The BootOrder order list is used by
the firmware’s boot manager as the default boot order.
The BootNext variable is a single UINT16 that defines the Boot####
option that is to be tried first on the next boot. After the BootNext boot
option is tried the normal BootOrder list is used. To prevent loops, the boot
manager deletes this variable before transferring control to the preselected boot
option.
The BootCurrent variable is a single UINT16 that defines the
Boot#### option that was selected on the current boot.
Each Driver#### variable contains an EFI_LOAD_OPTION.
Each load option variable is appended with a unique number, for example
Driver0001, Driver0002, and so on.
The DriverOrder variable contains an array of unsigned 16 bit values
that make up an ordered list of the Driver#### variable. The first element
in the array is the value for the first logical driver load option, the second
element is the value for the second logical driver load option, and so on. The
DriverOrder list is used by the firmware’s boot manager as the default load
order for UEFI drivers that it should explicitly load.
boots. The platform firmware may also decide to recover or set to a known set
of boot options.
Boot Mechanisms
UEFI can boot from a device using the SIMPLE_FILE_SYSTEM protocol
or the LOAD_FILE protocol. A device that supports the SIMPLE_FILE_
SYSTEM protocol must materialize a file system protocol for that device to be
bootable. If a device does not support a complete file system it may produce
a LOAD_FILE protocol that allows it to create an image directly. The boot
manager will attempt to boot using the SIMPLE_FILE_SYSTEM protocol
first. If that fails, then the LOAD_FILE protocol will be used.
format architecture. Each file only contains one UEFI image type, and a system
may support booting from one or more images types. Table 11.2 lists the UEFI
image types.
Network Booting
Network booting is described by the Preboot eXecution Environment (PXE)
BIOS Support Specification that is part of the Wired for Management Baseline
specification. PXE specifies UDP, DHCP, and TFTP network protocols
that a booting platform can use to interact with an intelligent system load
server. UEFI defines special interfaces that are used to implement PXE. These
interfaces are contained in the PXE_BASE_CODE protocol defined in the
UEFI specification.
Summary
In conclusion, this chapter indicates the mechanism by which a UEFI compliant
system determines what the boot target(s) is and in what order such execution
would occur. This methodology also provides a cooperative mechanism that is
highly extensible and that third parties (such as an OS vendor) can use for their
own installation and execution.
Chapter 12
Boot Flows
Two roads diverged in a wood….
—Robert Frost, “The Road Less Taken”
249
250 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Pre
Verifier
Exposed OS-Absent Previously
API App Exposed
PEI
CPU Framework
Core
Init APIs Now
Limited
Transient OS
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Boot OS-Present
DXE App
Dispatcher Dispatcher
Driver Boot
Pre-EFI Execution Device Transient After-
Security Runtime life
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL) (AL)
The PEI Foundation is unaware of the boot path required by the system.
It relies on the PEIMs to determine the boot mode and to take appropriate
action depending on the mode. To implement this determination of the boot
mode, each PEIM has the ability to manipulate the boot mode using the PEI
Service SetBootMode() described in the discussion of PEI in Chapter 13.
Note that the PEIM does not change the order in which PEIMs are dispatched
depending on the boot mode.
1. BOOT_IN_RECOVERY_MODE
2. BOOT_ON_FLASH_UPDATE
3. BOOT_ON_S3_RESUME
4. BOOT_WITH_MINIMAL_CONFIGURATION
5. BOOT_WITH_FULL_CONFIGURATION
6. BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
7. BOOT_WITH_FULL_CONFIGURATION_PLUS_
DIAGNOSTICS
8. BOOT_WITH_DEFAULT_SETTINGS
9. BOOT_ON_S4_RESUME
10. BOOT_ON_S5_RESUME
11. BOOT_ON_S2_RESUME
252 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Special PEIM
Warm/Cold Start Detect
PEI_SPECIAL_BOOT_MODE_PEIM_PPI
S3 Detect
PEI_S_STATE_BOOT_MODE_PEIM_PPI
Master/Special PEIM
PEI_MASTER_BOOT_MODE_PEIM_PPI
Any PEIMs
that need different
behavior on
Other PEIM 1 Other PEIM N Boot Mode
Table 12.1 lists the assumptions that can and cannot be made about the
system for each sleep state.
authentication, the SEC phase of UEFI PI is still responsible for locating the
PEI Foundation and verifying its authenticity.
In an Itanium-based system, it is also imperative that the firmware modules
in the BFV be organized such that at least the PAL-A is contained in the fault-
tolerant regions. This processor-specific PAL-A authenticates the PAL-B code,
which is usually contained in the regions of the firmware system that do not
support fault-tolerant updates. The PAL-A and PAL-B binary components are
always visible to all the processors in a node at the time of power-on; the system
fabric should not need to be initialized.
Non-Power-on Resets
Non-power-on resets can occur for many reasons. Some PEI and DXE sys-
tem services reset and reboot the entire platform, including all processors and
devices. It is important to have a standard variant of this boot path for cases
such as the following:
■■ Resetting the processor to change frequency settings
The architecture for multiple boot paths presented here has several benefits:
■■ The PEI Foundation is not required to be aware of system-specific
requirements such as multi-processor capability and various power
states. This lack of awareness allows for scalability and headroom for
future expansion.
■■ Supporting the various paths only minimally impacts the size of the
PEI Foundation.
■■ The PEIMs required to support the paths scale with the complexity
of the system.
Note that the Boot Mode Register becomes a variable upon transition to the
DXE phase. The DXE phase can have additional modifiers that affect the boot
path more than the PEI phase. These additional modifiers can indicate if the
system is in manufacturing mode, chassis intrusion, or AC power loss or if
silent boot is enabled.
In addition to the boot path types, modifier bits might be present. The
recovery-needed modifier is set if any PEIM detects that it has become
corrupted.
■■ Platform hardware
For example, a closed system or one that has detected a chassis intrusion could
support a boot path that assumes no configuration changes from last boot
option, thus allowing a very rapid boot time. Unsupported variations default
to basic S0 operation. The following are the defined variations to the basic boot
path:
256 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ Boot with full configuration plus diagnostics: This path also causes any
diagnostics to be executed.
■■ Boot with default settings: This path uses a known set of safe values for
programming hardware.
Recovery Paths
All of the previously described boot paths can be modified or aborted if the
system detects that recovery is needed. Recovery is the process of reconstituting
a system’s firmware devices when they have become corrupted. The corruption
can be caused by various mechanisms. Most firmware volumes on nonvolatile
storage devices (flash, disk) are managed as blocks. If the system loses power
while a block, or semantically bound blocks, are being updated, the storage
might become invalid. On the other hand, the device might become corrupted
by an errant program or by errant hardware. The system designers must
determine the level of support for recovery based on their perceptions of the
probabilities of these events occurring and their consequences.
The following are some reasons why system designers may choose not to
support recovery:
■■ A system’s firmware volume storage media might not support
modification after being manufactured. It might be the functional
equivalent of ROM.
Discovery
Discovering that recovery is required may be done using a PEIM (for example,
by checking a “force recovery” jumper) or the PEI Foundation itself. The PEI
Foundation might discover that a particular PEIM has not validated correctly
or that an entire firmware has become corrupted.
■■ Read a copy of the data that was lost from chosen peripherals.
have contained a PEIM or not? It seems that the PEI Foundation may discover
most corruption as an incidental result of its search for PEIMs. In this case, if
the PEI Foundation completes its dispatch process without discovering enough
static system memory to start DXE, then it should go into recovery mode.
■■ Capsule update: This boot mode can be an INIT, S3, or some other
means by which to restart the machine. If it is an S3, for example,
the capsule cause will supersede the S3 restart. It is incumbent upon
platform code, such as a memory initialization PEIM, to determine
the exact cause and perform the correct behavior—that is, S3 state
restoration versus INIT behavior.
The processor INIT and MCA are two asynchronous events that start up
the SEC code/dispatcher in an Itanium-based system. The UEFI PI security
module is transparent during all the code paths except for the recovery check
call that happens during a cold boot. The PEIMs or DXE drivers that handle
these events are architecture-aware and do not return the control to the core
dispatcher. They call their respective architectural handlers in the OS.
PowerGood
RESET
All Processors
run PAL-A
Rec. Mode
First Phase Done Second Phase Done
Check PEIM
A M A DXE
Figure 12.4 Intel® Itanium® Processor Boot Flow (MP versus UP on Other CPUs)
262 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
In Intel Itanium architecture, the microcode starts up the first layer of the
PAL code, provided by the processor vendor, that resides in the Boot Firmware
Volume (BFV). This code minimally initializes the processor and then finds
and authenticates the second layer of PAL code (called PAL-B). The location
of both PAL-A and PAL-B can be found by consulting either the architected
pointers in the ROM near the 4-gigabyte region or by consulting the Firmware
Interface Table (FIT) pointer in the ROM. The PAL layer communicates with
the OEM boot firmware using a single entry point called SALE_ENTRY.
The Intel Itanium architecture defines the initialization described above.
In addition, however, Itanium-based systems that use the UEFI PI architecture
must do the following:
■■ A “special” PEIM must be resident in the BFV to provide information
about the location of the other firmware volumes.
The PEI Foundation will be located at the SALE_ENTRY point on
the BFV. The Intel Itanium architecture PEIMs may reside in the BFV
or other firmware volumes, but a special PEIM must be resident in the
BFV to provide information about the location of the other firmware
volumes.
■■ The BFV of a particular node must be accessible by all the processors
running in that node.
All the processors in each node start up and execute the PAL code and
subsequently enter the PEI Foundation. The BFV of a particular node
must be accessible by all the processors running in that node. This
distinction also means that some of the PEIMs in the Intel Itanium
architecture boot path will be multi-processor-aware.
■■ Firmware modules in a BFV must be organized such that PAL-A, PAL-B,
and FIT binaries are always visible to all the processors in a node at the
time of power-on.
These binaries must be visible without any initialization of the system
fabric.
Chapter 12: Boot Flows n 263
//*******************************************************
// EFI_BOOT_MODE
//*******************************************************
typedef UINT32 EFI_BOOT_MODE;
#define
BOOT_WITH_FULL_CONFIGURATION 0x00
#define BOOT_WITH_MINIMAL_CONFIGURATION 0x01
#define
BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02
#define
BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03
#define
BOOT_WITH_DEFAULT_SETTINGS 0x04
#define
BOOT_ON_S4_RESUME 0x05
#define
BOOT_ON_S5_RESUME 0x06
#define
BOOT_ON_S2_RESUME 0x10
#define
BOOT_ON_S3_RESUME 0x11
#define
BOOT_ON_FLASH_UPDATE 0x12
#define
BOOT_IN_RECOVERY_MODE 0x20
Table 12.2 lists the values and descriptions of the boot modes.
Recovery
This section describes platform firmware recovery. Recovery is an option to
provide higher RASUM (Reliability, Availability, Usability, Manageability) in
the field. Recovery is the process of reconstituting a system’s firmware devices
when they have become corrupted. The corruption can be caused by various
mechanisms. Most firmware volumes (FVs) in nonvolatile storage (NVS)
devices (flash or disk, for example) are managed as blocks. If the system loses
power while a block, or semantically bound blocks, are being updated, the
storage might become invalid. On the other hand, an errant program or
hardware could corrupt the device. The system designers must determine the
level of support for recovery based on their perceptions of the probabilities of
these events occurring and the consequences.
Discovery
Discovering that recovery is required may be done using a PEIM (for example,
by checking a “force recovery” jumper) or the PEI Foundation itself. The PEI
Foundation might discover that a particular PEIM has not validated correctly
or that an entire firmware has become corrupted.
Note At this point a physical reset of the system has not occurred.
The PEI Dispatcher has only cleared all state information and
restarted itself.
It is possible that a PEIM could be built to handle the portion of the
recovery that would initialize the recovery peripherals (and the buses they reside
on) and then to read the new images from the peripherals and update the FVs.
It is considered far more likely that the PEI will transition to DXE be-
cause DXE is designed to handle access to peripherals. This has the additional
benefit that, if DXE then discovers that a device has become corrupted, it may
institute recovery without transferring control back to the PEI.
Since the PEI Foundation does not have a list of what to dispatch, how
does it know if an area of invalid space in an FV should have contained a PEIM
or not? The PEI Foundation should discover most corruption as an incidental
result of its search for PEIMs. In this case, if the PEI Foundation completes
its dispatch process without discovering enough static system memory to start
DXE, then it should go into recovery mode.
266 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Summary
This chapter has described the various boot modes that the UEFI PI firmware
can support. This concept is important to understand as both a provider of
PEI modules and DXE drivers, along with platform integrators. The former
constituency needs to design their code to handle the boot modes appropriately,
whereas the latter group of engineers needs to understand how to compose a
set of modules and drivers for the respective boot paths of a resultant system.
Chapter 13
Pre-EFI Initialization
(PEI)
Small is Beautiful
—E.F. Schumacher
267
268 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Scope
The PEI phase is responsible for initializing enough of the system to provide
a stable base for subsequent phases. It is also responsible for detecting and
recovering from corruption of the firmware storage space and providing the
restart reason (boot-mode).
Today’s PC generally starts execution in a very primitive state, from the
perspective of the boot firmware, such as BIOS or the UEFI PI. Processors
might need updates to their internal microcode; the chipset (the chips that
provide the interface between processors and the other major components of the
system) require considerable initialization; and RAM requires sizing, location,
and other initialization. The PEI phase is responsible for initializing these basic
subsystems. The PEI phase is intended to provide a simple infrastructure by
which a limited set of tasks can easily be accomplished to transition to the more
advanced DXE phase. The PEI phase is intended to be responsible for only a
very small subset of tasks that are required to boot the platform; in other words,
it should perform only the minimal tasks that are required to start DXE. As
improvements in the hardware occur, some of these tasks may migrate out of
the PEI phase of execution.
Rationale
The design for PEI is essentially a miniature version of DXE that addresses
many of the same issues. The PEI phase consists of several parts:
■■ A PEI Foundation
has been initialized. As such, PEI does not have the rich feature set that DXE
does. The following are the most obvious examples of this difference:
■■ DXE has a rich database of loaded images and protocols bound to
those images.
■■ PEI lacks a rich module hierarchy such as the DXE driver model.
Overview
The PEI phase consists of some Foundation code and specialized drivers known
as PEIMs that customize the PEI phase operations to the platform. It is the
responsibility of the Foundation code to dispatch the plug-ins in a sequenced
order and provide basic services. The PEIMs are analogous to DXE drivers and
generally correspond to the components being initialized. It is expected that
common practice will be that the vendor of the component will provide the
PEIM, possibly in source form so the customer can quickly debug integration
problems.
The implementation of the PEI phase is more dependent on the processor
architecture than any other UEFI PI phase. In particular, the more resources
that the processor provides at its initial or near initial state, the richer the PEI
environment will be. As such, several parts of the following discussion note
requirements for the architecture but are otherwise left less completely defined
because they are specific to the processor architecture.
PEI can be viewed from both temporal and spatial perspectives. Figure 13.1
provides the overall UEFI PI boot phase. The spatial view of PEI can be found
in Figure 13.2. This picture describes the layering of the UEFI PI components.
This figure has often been referred to as the “H”. PEI compromises the lower
half of the “H”. The temporal perspective entails “when” the PEI foundation
and its associated modules execute. Figure 13.3 highlights the portions of
Figure 13.1 that include PEI.
270 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Pre
Verifier Exposed
Platform OS-Absent
Interface App
PEI
CPU
Core
Init
Transient OS
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Boot OS-Present
EFI Driver App
Dispatcher Manager
Final OS Final OS
Intrinsic
Boot Loader Environment ?
Services
Security
Driver Boot
Pre-EFI Execution Device Transient After-
Security Run Time life
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL) (AL)
EFI Driver
EFI Driver
EFI Driver
EFI Driver
EFI Driver
EFI Driver
Architecture Specification
EFI Driver
EFI Driver
EFI Driver
EFI Driver
EFI Driver
Driver
Driver
Driver
EFI
EFI
EFI
Driver Execution Environment (DXE) Spec
Legend
API
Driver
Driver
DXE
EFI
DXE Driver
DXE Driver
EFI Driver
Architecture Specification
DXE Driver
DXE Driver
EFI Driver
Driver
Driver
DXE
EFI
CSM
Driver
Driver
Driver
DXE
DXE
EFI
Driver Execution Environment (DXE) Spec
Pre
Verifier Exposed
Platform OS-Absent
Interface App
PEI
CPU
Core
Init
Transient OS
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Boot OS-Present
EFI Driver App
Dispatcher Manager
Final OS Final OS
Intrinsic
Boot Loader Environment ?
Services
Security
Figure 13.3 Portion of the Overall Boot Flow and Components for PEI
Chapter 13: Pre-EFI Initialization (PEI) n 273
Phase Prerequisites
The following sections describe the prerequisites necessary for the successful
completion of the PEI phase.
Temporary RAM
The PEI Foundation requires that the SEC phase initializes a minimum amount
of scratch pad RAM that can be used by the PEI phase as a data store until
system memory has been fully initialized. This scratch pad RAM should have
access properties similar to normal system RAM—through memory cycles on
the front side bus, for example. After system memory is fully initialized, the
temporary RAM may be reconfigured for other uses. Typical provision for the
temporary RAM is an architectural mode of the processor’s internal caches.
Security Primitives
The SEC phase provides an interface to the PEI Foundation to perform
verification operations. To continue the root of trust, the PEI Foundation will
use this mechanism to validate various PEIMs.
Concepts
The following sections describe the concepts in the PEI phase design.
PEI Foundation
The PEI Foundation is a single binary executable that is compiled to function
with each processor architecture. It performs two main functions:
■■ Dispatching PEIMs
■■ A minimum amount of temporary RAM that the PEI phase can use.
Chapter 13: Pre-EFI Initialization (PEI) n 275
PPI
GUID Pointer PPI Descriptor Ptr A
Descriptor
PPI Pointer PPI Descriptor Ptr B
Flags PPI Descriptor Ptr C1
PPI Descriptor Ptr D
PPI Descriptor Ptr C2
PPI
NULL
The PEI Dispatcher consists of a single phase. It is during this phase that
the PEI Foundation examines each file in the firmware volumes that contain
files of type PEIM. It examines the dependency expression (depex) within
each firmware file to decide if a PEIM can run. A dependency expression is
code associated with each driver that describes the dependencies that must be
satisfied for that driver to run. The binary encoding of dependency expressions
for PEIMs is the same as that of dependency expressions associated with a DXE
driver.
276 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
PEI Services
The PEI Foundation establishes a system table named the PEI Services Table
that is visible to all PEIMs in the system. A PEI service is defined as a function,
command, or other capability that is manifested by the PEI Foundation when
that service’s initialization requirements are met. Because the PEI phase has no
permanent memory available until nearly the end of the phase, the range of
services created during the PEI phase cannot be as rich as those created during
later phases. Because the location of the PEI Foundation and its temporary
RAM is not known at build time, a pointer to the PEI Services Table is passed
into each PEIM’s entry point and also to part of each PPI. The PEI Foundation
provides the following classes of services:
■■ PPI Services: Manages PPIs to facilitate intermodule calls between
PEIMs. Interfaces are installed and tracked on a database maintained
in temporary RAM.
■■ Boot Mode Services: Manages the boot mode (S3, S5, normal boot,
diagnostics, and so on) of the system.
■■ Notifications
PPI services allow a PEIM to provide functions or data for another PEIM to
use. PPI notifications allow a PEIM to register for a callback when another PPI
is registered with the PEI Foundation.
Simple Heap
The PEI Foundation uses temporary RAM to provide a simple heap store
before permanent system memory is installed. PEIMs may request allocations
from the heap, but no mechanism exists to free memory from the heap. Once
permanent memory is installed, the heap is relocated to permanent system
memory, but the PEI Foundation does not fix up existing data within the heap.
278 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Therefore, a PEIM cannot store pointers in the heap when the target is other
data within the heap, such as linked lists.
PHIT
HOB HOB HOB HOB HOB ..... HOB
DXE DXE
Drivers Drivers
Operation
PEI phase operation consists of invoking the PEI Foundation, dispatching all
PEIMs in an orderly manner, and discovering and invoking the next phase,
as illustrated in Figure 13.6. During PEI Foundation initialization, the PEI
Foundation initializes the internal data areas and functions that are needed to
provide the common PEI services to PEIMs. During PEIM dispatch, the PEI
Dispatcher traverses the firmware volume(s) and discovers PEIMs according to
the flash file system definition. The PEI Dispatcher then dispatches PEIMs if
the following criteria are met:
■■ The PEIM has not already been invoked.
After dispatching a PEIM, the PEI Dispatcher continues traversing the firmware
volume(s) until either all discovered PEIMs have been invoked or no more
PEIMs can be invoked because the requirements listed above cannot be met for
any PEIMs. Once this condition has been reached, the PEI Dispatcher’s job is
complete and it invokes an architectural PPI for starting the next phase of the
UEFI PI, the DXE Initial Program Load (IPL) PPI.
FV(s)
PEI
Core Services
Core BFV
T-RAM
Memory Services
Handoff Blocks
Initialization
PPI Database
Status Code
R/O FW Vol
Boot Mode
System
Memory
Core Dispatcher
DXE
PPI(s) PPI(s) PPI(s) PPI(s)
IPL
PEIM PEIM PEIM PEIM PEIM
Dependency Expressions
The sequencing of PEIMs is determined by evaluating a dependency expression
associated with each PEIM. This Boolean expression describes the requirements
that are necessary for that PEIM to run, which imposes a weak ordering on
Chapter 13: Pre-EFI Initialization (PEI) n 281
the PEIMs. Within this weak ordering, the PEIMs may be initialized in any
order. The GUIDs of PPIs and the GUIDs of file names are referenced in the
dependency expression. The dependency expression is a representative syntax of
operations that can be performed on a plurality of dependencies to determine
whether the PEIM can be run. The PEI Foundation evaluates this dependency
expression against an internal database of run PEIMs and registered PPIs.
Operations that may be performed on dependencies are the logical operators
AND, OR, and NOT and the sequencing operators BEFORE and AFTER.
Verification/Authentication
The PEI Foundation is stateless with respect to security. Instead, security
decisions are assigned to platform-specific components. The two components
of interest that abstract security include the Security PPI and a Verification
PPI. The purpose of the Verification PPI is to check the authentication status
of a given PEIM. The mechanism used therein may include digital signature
verification, a simple checksum, or some other OEM-specific mechanism. The
result of this verification is returned to the PEI Foundation, which in turn
conveys the result to the Security PPI. The Security PPI decides whether to
defer execution of the PEIM or to let the execution occur. In addition, the
Security PPI provider may choose to generate an attestation log entry of the
dispatched PEIM or provide some other security exception.
PEIM Execution
PEIMs run to completion when invoked by the PEI Foundation. Each PEIM
is invoked only once and must perform its job with that invocation and install
other PPIs to allow other PEIMs to call it as necessary. PEIMs may also register
for a notification callback if it is necessary for the PEIM to get control again
after another PEIM has run.
Memory Discovery
Memory discovery is an important architectural event during the PEI phase.
When a PEIM has successfully discovered, initialized, and tested a contiguous
range of system RAM, it reports this RAM to the PEI Foundation. When that
PEIM exits, the PEI Foundation migrates PEI usage of the temporary RAM to
real system RAM, which involves the following two tasks:
282 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ The PEI Foundation must switch PEI stack usage from temporary
RAM to permanent system memory.
events. The buffer also holds some important variables needed by the start-up
code to make decisions during these special hardware events.
Recovery
Recovery is the process of reconstituting a system’s firmware devices when they
have become corrupted. The corruption can be caused by various mechanisms.
Most firmware volumes on nonvolatile storage devices are managed as blocks.
If the system loses power while a block or semantically bound blocks are being
updated, the storage might become invalid. On the other hand, the device
might become corrupted by an errant program or by errant hardware. Assuming
PEI lives in a fault-tolerant block, it can support a recovery mode dispatch.
A PEIM or the PEI Foundation itself can discover the need to do recovery.
A PEIM can check a “force recovery” jumper, for example, to detect a need for
recovery. The PEI Foundation might discover that a particular PEIM does not
validate correctly or that an entire firmware volume has become corrupted.
The concept behind recovery is that enough of the system firmware is
preserved so that the system can boot to a point that it can read a copy of the
data that was lost from chosen peripherals and then reprogram the firmware
volume with that data.
Preservation of the recovery firmware is a function of the way the firmware
volume store is managed. In the UEFI PI flash file system, PEIMs required
for recovery are marked as such. The firmware volume store architecture must
then preserve marked items, either by making them unalterable (possibly with
hardware support) or protect them using a fault-tolerant update process.
Until recovery mode has been discovered, the PEI Dispatcher proceeds as
normal. If the PEI Dispatcher encounters PEIMs that have been corrupted
(for example, by receiving an incorrect hash value), it must change the boot
mode to recovery. Once set to recovery, other PEIMs must not change it to one
of the other states. After the PEI Dispatcher has discovered that the system is
in recovery mode, it will restart itself, dispatching only those PEIMs that are
required for recovery. It is also possible for a PEIM to detect a catastrophic
condition or to be a forced-recovery detect PEIM and to inform the PEI
Dispatcher that it needs to proceed with a recovery dispatch. The recovery
dispatch is completed when a PEIM finds a recovery firmware volume on a
recovery media and the DXE Foundation is started from that firmware volume.
Drivers within that DXE firmware volume can perform the recovery process.
284 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
S3 Resume
The PEI phase on S3 resume (save-to-RAM resume) differs in several
fundamental ways from the PEI phase on a normal boot. The differences are
as follows:
■■ The memory subsection is restored to its presleep state rather than
initialized.
■■ The PEIM that would normally dispatch the DXE phase instead uses
a special Hardware Save Table to restore fundamental hardware back
to a boot configuration. After restoring the hardware, the PEIM passes
control to the OS-supplied resume vector.
■■ The DXE and later phases during a normal boot save enough
information in the UEFI PI reserved memory or a firmware volume
area for hardware to be restored to a state that the OS can use to restore
devices. This saved information is located in the Hardware Save Table.
the Terse Executable (TE) image format was designed. The TE image format
is a strict subset of the Portable Executable/Common File Format (PE/COFF)
image used by UEFI applications, UEFI drivers, and DXE drivers.
The advantages of having TE as a subset of PE include the ability to
use standard, available tools, such as linkers, which can be used during the
development process. Only during the final phases of the FV image creation
does the tool chain need to convert the PE image into a TE. This similarity
extends to the headers and the relocation records. In order to have an in-situ
agent, such as a debugger nub, distinguish between the PE and TE images, the
signature field has been slightly modified. For the PE the signature is “MZ” for
Mark Zbikowski, the designer of the Microsoft DOS† image format, the origin
of the PE/COFF image. For the TE image, the signature is “VZ”, as found at
the end of Volume 1 of the UEFI PI specification:
#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // “VZ”
This one character difference allows for sharing of debug scripts and code that
only need to distinguish between the PE and TE via this one character of
the signature field. Although the development and design team eschewed use
of proper names in code or the resultant binaries, the “VZ” and “Vincent
Zimmer” association appeared harmless, especially given the interoperability
advantages.
In addition to the TE image, the “temporary memory” used during PEI is
another innovation on Intel architecture platforms. Recall that the goal of PEI
is to provide a basic system fabric initialization and some subset of memory that
will be available throughout DXE, UEFI, and the operating system runtime.
In order to program a modern CPU, memory controller, and interconnect,
thousands of lines of C code may be required. In the spirit of using standard
tools to write this code, though, some memory store prior to the permanent
Dynamic RAM (DRAM) needed to be found.
Other approaches to this challenge in the past include the Coreboot use of
the read-only-memory C compiler (romcc), or a compiler that uses processor
registers as the “temporary memory.” This approach has proven difficult to
maintain and entails a custom compiler. The other approach is to have dedicated
memory on the platform immediately available after reset. Given the economics
of modern systems and the transitory usage of this store, the use of discrete
memory as a scratchpad has proven difficult to provide in anything other
than the high-end system or extremely low-end, nontraditional systems. The
approach taken for the bulk of Intel architecture systems is to use the processor
286 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Example System
All of the concepts regarding PEI can be synthesized when reviewing a
specific platform. The following list represents an 865 system with all of the
associated system components. This same system is also shown in Figure
13.7, which includes the actual silicon components. Figure 13.8 provides an
idealized version of this same system. The components in the latter figure have
corresponding PEIMs to abstract both the initialization of and services by the
components. For each of these components, one to several PEI Modules can be
delivered that abstract the specific component’s behavior. An example of these
components can include:
■■ Pentium® 4 processor PEIM: Initialization and CPU I/O service
Processor
Front-Side Bus
Hub
Interface
SMBus
USB
IDE ICH5 PCI Bus
LAN
PCI Slots
Audio Codec
AC97 FWH LPC I/F
KBC/SIO
Modem Codec
Processor
AGP Slot
IDE
South PCI Bus
USB Bridge PCI Slots
LPC Bus
LAN
FLASH
Audio
Super I/O
typedef
EFI_STATUS
(EFIAPI *PEI_SMBUS_PPI_EXECUTE_OPERATION) (
IN EFI_PEI_SERVICE **PeiServices,
IN struct EFI_PEI_SMBUS_PPI *This,
IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
IN EFI_SMBUS_DEVICE_COMMAND Command,
IN EFI_SMBUS_OPERATION Operation,
IN BOOLEAN PecCheck,
IN OUT UINTN *Length,
IN OUT VOID *Buffer
);
typedef struct {
PEI_SMBUS_PPI_EXECUTE_OPERATION Execute;
PEI_SMBUS_PPI_ARP_DEVICE ArpDevice;
} EFI_PEI_SMBUS_PPI;
What is notable about a PPI is that it is like an EFI protocol in that it has
member services and/or static data. The PPI is named by a GUID and can
have several instances. The SMBUS PPI, for example, could be implemented
for SMBUS controllers in the ICH, in another vendor’s integrated Super I/O
(SIO), or other component. Figure 13.10 illustrates an instance of an SMBUS
PPI for an Intel ICH.
#define SMBUS_R_HD0 0xEFA5
#define SMBUS_R_HBD 0xEFA7
EFI_PEI_SERVICES *PeiServices;
SMBUS_PRIVATE_DATA *Private;
UINT8 Index, BlockCount *Length;
UINT8 *Buffer;
BlockCount = Private->CpuIo.IoRead8 (
*PeiServices,Private->CpuIo,SMBUS_R_HD0);
if (*Length < BlockCount) {
return EFI_BUFFER_TOO_SMALL;
} else {
for (Index = 0; Index < BlockCount; Index++) {
Buffer[Index] = Private->CpuIo.IoRead8 (
*PeiServices,Private->CpuIo,SMBUS_R_HBD);
}
}
Summary
This chapter has provided an overview of the PEI phase of the UEFI PI
environment. PEI provides a unique combination of software modularity so
that various business interests can provide modules, while at the same time have
purpose-built technologies to support the robustness and resource constraints
of such an early phase of machine execution. Aspects of PEI discussed in this
chapter include the concept of temporary memory, the PEI Core services,
PEI relative to other UEFI PI components, recovery, and some sample PEI
modules.
290 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 14
Putting It All Together—
Firmware Emulation
An expert is a man who has made all the mistakes which can be made in
a very narrow field.
—Niels Bohr
without the need of a real hardware debugger. Of course, this emulation has
its limitations, since some components of the firmware must talk to hardware.
It is much more difficult to emulate such components, though later in this
chapter, some possibilities are discussed to alleviate some of this issue. Figure
14.1 shows an example of a firmware emulation environment running the
UEFI shell within an operating system context.
Virtual Platform
This NT32 platform can be described as a hardware-agnostic platform in that
it uses operating system APIs for its primary hardware abstractions. Figure
14.2 shows how the firmware emulation environment gets launched. It is part
of a normal boot process, and will essentially launch a firmware emulation
environment as an application running from the operating system. For
most developers, this simply means launching a standard platform, loading
an operating system, and then building and executing the NT32 emulation
environment as a native operating system application. This application
effectively executes the firmware that was built, and emulates the launch of a
new system.
Chapter 14: Putting It All Together—Firmware Emulation n 293
Pre
Verifier
Exposed OS-Absent Previously
API App Exposed
PEI
CPU Framework
Core
Init APIs Now
Limited
Transient OS
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Emulation
OS-Present
DXE Boot Environment
Dispatcher App
Dispatcher
Driver Boot
Pre-EFI Execution Device Transient After-
Security Runtime life
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL) (AL)
Figure 14.2 The Normal Boot Process Launching an Operating System that Will
Launch the Emulation Environment
Pre
Verifier
Exposed OS-Absent
API App
PEI
CPU
Core
Init
Transient OS
Verify
Chipset
Init Environment
Device,
Bus, or
Board Service
Init Driver Transient OS
Boot Loader
Driver Boot
Pre-EFI Execution Device Transient After-
Security Runtime life
(SEC) Initialization Environment Selection System Load (RT)
(PEI) (DXE) (BDS) (TSL) (AL)
//
// Win32 Process APIs
//
WinNtGetProcAddress GetProcAddress;
WinNtGetTickCount GetTickCount;
WinNtLoadLibraryEx LoadLibraryEx;
WinNtFreeLibrary FreeLibrary;
WinNtSetPriorityClass SetPriorityClass;
WinNtSetThreadPriority SetThreadPriority;
WinNtSleep Sleep;
WinNtSuspendThread SuspendThread;
WinNtGetCurrentThread GetCurrentThread;
WinNtGetCurrentThreadId GetCurrentThreadId;
WinNtGetCurrentProcess GetCurrentProcess;
WinNtCreateThread CreateThread;
WinNtTerminateThread TerminateThread;
WinNtSendMessage SendMessage;
WinNtExitThread ExitThread;
WinNtResumeThread ResumeThread;
WinNtDuplicateHandle DuplicateHandle;
//
// Wint32 Mutex primitive
//
WinNtInitializeCriticalSection InitializeCriticalSection;
WinNtEnterCriticalSection EnterCriticalSection;
WinNtLeaveCriticalSection LeaveCriticalSection;
WinNtDeleteCriticalSection DeleteCriticalSection;
WinNtTlsAlloc TlsAlloc;
WinNtTlsFree TlsFree;
WinNtTlsSetValue TlsSetValue;
WinNtTlsGetValue TlsGetValue;
WinNtCreateSemaphore CreateSemaphore;
WinNtWaitForSingleObject WaitForSingleObject;
WinNtReleaseSemaphore ReleaseSemaphore;
//
// Win32 Console APIs
//
WinNtCreateConsoleScreenBuffer CreateConsoleScreenBuffer;
WinNtFillConsoleOutputAttribute FillConsoleOutputAttribute;
WinNtFillConsoleOutputCharacter FillConsoleOutputCharacter;
296 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
WinNtGetConsoleCursorInfo GetConsoleCursorInfo;
WinNtGetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents;
WinNtPeekConsoleInput PeekConsoleInput;
WinNtScrollConsoleScreenBuffer ScrollConsoleScreenBuffer;
WinNtReadConsoleInput ReadConsoleInput;
WinNtSetConsoleActiveScreenBuffer SetConsoleActiveScreenBuffer;
WinNtSetConsoleCursorInfo SetConsoleCursorInfo;
WinNtSetConsoleCursorPosition SetConsoleCursorPosition;
WinNtSetConsoleScreenBufferSize SetConsoleScreenBufferSize;
WinNtSetConsoleTitleW SetConsoleTitleW;
WinNtWriteConsoleInput WriteConsoleInput;
WinNtWriteConsoleOutput WriteConsoleOutput;
//
// Win32 File APIs
//
WinNtCreateFile CreateFile;
WinNtDeviceIoControl DeviceIoControl;
WinNtCreateDirectory CreateDirectory;
WinNtRemoveDirectory RemoveDirectory;
WinNtGetFileAttributes GetFileAttributes;
WinNtSetFileAttributes SetFileAttributes;
WinNtCreateFileMapping CreateFileMapping;
WinNtCloseHandle CloseHandle;
WinNtDeleteFile DeleteFile;
WinNtFindFirstFile FindFirstFile;
WinNtFindNextFile FindNextFile;
WinNtFindClose FindClose;
WinNtFlushFileBuffers FlushFileBuffers;
WinNtGetEnvironmentVariable GetEnvironmentVariable;
WinNtGetLastError GetLastError;
WinNtSetErrorMode SetErrorMode;
WinNtGetStdHandle GetStdHandle;
WinNtMapViewOfFileEx MapViewOfFileEx;
WinNtReadFile ReadFile;
WinNtSetEndOfFile SetEndOfFile;
WinNtSetFilePointer SetFilePointer;
WinNtWriteFile WriteFile;
WinNtGetFileInformationByHandle GetFileInformationByHandle;
WinNtGetDiskFreeSpace GetDiskFreeSpace;
WinNtGetDiskFreeSpaceEx GetDiskFreeSpaceEx;
WinNtMoveFile MoveFile;
WinNtSetFileTime SetFileTime;
WinNtSystemTimeToFileTime SystemTimeToFileTime;
//
// Win32 Time APIs
//
WinNtFileTimeToLocalFileTime FileTimeToLocalFileTime;
WinNtFileTimeToSystemTime FileTimeToSystemTime;
Chapter 14: Putting It All Together—Firmware Emulation n 297
WinNtGetSystemTime GetSystemTime;
WinNtSetSystemTime SetSystemTime;
WinNtGetLocalTime GetLocalTime;
WinNtSetLocalTime SetLocalTime;
WinNtGetTimeZoneInformation GetTimeZoneInformation;
WinNtSetTimeZoneInformation SetTimeZoneInformation;
WinNttimeSetEvent timeSetEvent;
WinNttimeKillEvent timeKillEvent;
//
// Win32 Serial APIs
//
WinNtClearCommError ClearCommError;
WinNtEscapeCommFunction EscapeCommFunction;
WinNtGetCommModemStatus GetCommModemStatus;
WinNtGetCommState GetCommState;
WinNtSetCommState SetCommState;
WinNtPurgeComm PurgeComm;
WinNtSetCommTimeouts SetCommTimeouts;
WinNtExitProcess ExitProcess;
WinNtSprintf SPrintf;
WinNtGetDesktopWindow GetDesktopWindow;
WinNtGetForegroundWindow GetForegroundWindow;
WinNtCreateWindowEx CreateWindowEx;
WinNtShowWindow ShowWindow;
WinNtUpdateWindow UpdateWindow;
WinNtDestroyWindow DestroyWindow;
WinNtInvalidateRect InvalidateRect;
WinNtGetWindowDC GetWindowDC;
WinNtGetClientRect GetClientRect;
WinNtAdjustWindowRect AdjustWindowRect;
WinNtSetDIBitsToDevice SetDIBitsToDevice;
WinNtBitBlt BitBlt;
WinNtGetDC GetDC;
WinNtReleaseDC ReleaseDC;
WinNtRegisterClassEx RegisterClassEx;
WinNtUnregisterClass UnregisterClass;
WinNtBeginPaint BeginPaint;
WinNtEndPaint EndPaint;
WinNtPostQuitMessage PostQuitMessage;
WinNtDefWindowProc DefWindowProc;
WinNtLoadIcon LoadIcon;
WinNtLoadCursor LoadCursor;
WinNtGetStockObject GetStockObject;
WinNtSetViewportOrgEx SetViewportOrgEx;
WinNtSetWindowOrgEx SetWindowOrgEx;
WinNtMoveWindow MoveWindow;
WinNtGetWindowRect GetWindowRect;
298 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
WinNtGetMessage GetMessage;
WinNtTranslateMessage TranslateMessage;
WinNtDispatchMessage DispatchMessage;
WinNtGetProcessHeap GetProcessHeap;
WinNtHeapAlloc HeapAlloc;
WinNtHeapFree HeapFree;
} EFI_WIN_NT_THUNK_PROTOCOL;
Figure 14.4 Thunk Protocol that Associates Some Firmware Names with Operating
System APIs
//
// Example of reading from a file
//
Result = WinNtThunk->ReadFile (
NtHandle,
Buffer,
(DWORD)*BufferSize,
&BytesRead,
NULL
);
//
// Example of resetting a serial device
//
WinNtThunk->PurgeComm (
NtHandle,
PURGE_TXCLEAR | PURGE_RXCLEAR
);
//
// Example of getting local time components
//
WinNtThunk->GetLocalTime (&SystemTime);
WinNtThunk->GetTimeZoneInformation (&TimeZone);
In summary, Figure 14.7 shows the software logic contained within the
operating system, firmware emulation component, and their associated
interaction logic. It should be noted that this logical software flow has three
primary components:
■■ Firmware component under development
Operating System
Firmware Environment
(EFI or Framework Code-Base)
Hardware
Hardware Pass-Through
As is evident through the previous examples, the underlying firmware can
enable calling to several operating system APIs. However, since the firmware
emulation environment is essentially an operating system application, certain
functions are not going to be available. This is true since most operating systems
have the concept of separating a user space from a more privileged kernel space
to prevent applications from inadvertently crashing the entire operating system.
Using this type of separation allows for the operating system to detect an error
Chapter 14: Putting It All Together—Firmware Emulation n 301
and simply kill the user session without perturbing the remaining portions of
the operating system.
It is possible to introduce several extensions to what is currently defined in
the sample implementations that enable even further capabilities. An operating
system kernel driver could be constructed to facilitate access to even more
functions than would otherwise be available. This of course circumvents some
of the inherent safety of the operating system and can introduce inadvertent
crashes when care is not taken. By constructing a kernel driver that can
reserve certain hardware resources and is able to advertise an interface that the
emulation environment can call, the emulation environment can allow for an
enhanced penetration into the hardware.
Figure 14.8 shows the logic flow associated with the various components
and how they interact.
302 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Operating System
Firmware Environment
(EFI or Converted Legacy Code-Base)
Hardware
Summary
This chapter shows how the majority of the UEFI code can be run in an
emulated environment so that development can occur on some modules even
in absence of physical hardware that would otherwise have been necessary. This
emulation, which is publicly available, advances the accessibility of the overall
UEFI programming infrastructure. It can also facilitate a wider distribution
of its use due to the relative simplicity of establishing such a development
environment.
Chapter 15
Reducing Platform
Boot Times
All problems are either kernel or BIOS problems depending on which
context you are running in!
—Rothman’s Axiom
303
304 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Reset Vector
Flush cache and jump into main initialization
routine in the ROM.
PEI Dispatcher
Loads a series of PEI modules (PEIM) based on a series of criterion. Dispatching starts
with modules which have no prerequisites and proceed through other modules which have more
complex dependencies. This is typically a loop which is exhausted when there are no further
modules that need dispatching and there are no newly discovered modules.
Architectural
Protocols DXE Dispatcher
Some of the key The dispatcher is tasked with the job of discovering the FV
drivers needed for (firmware volume) components that are available and processing
the core to operate. them. Each of the discovered drivers within the FV is scheduled
Some of these are to be launched if and when their dependencies are met. Once
the BDS, CPU, a driver is scheduled to run, the dispatcher
Timer, etc. will proceed to launch the scheduled drivers and continue to do so
until there are no more scheduled drivers.
No
Yes
Hand-off to the Boot Target
Are there
more boot options Yes Load new boot option
to try?
Platform Policy
When no viable boot options exist, the platform will
have some built-in boot behavior that is specific
to the manufacturer of the platform.
Proof of Concept
In the proof of concept for this chapter, the overall performance numbers used
are measured in microseconds and the total boot time is described in seconds.
Total boot time is measured as the time between the CPU first having power
applied and the transferring of control to the boot target (which is typically
the OS). This chapter does not focus on the specifics of the hardware design
itself since the steps that are described are intended to be platform-agnostic.
However, for those who absolutely must know from what type of platform
some of the numbers are derived, they are:
■■ 1.8-GHz Intel® Atom™-based netbook design
■■ 1 GB DDR2 memory
■■ 2 MB flash
■■ Intel® Solid State Drive X25-E (Intel® X25E SSD) (in optimized
configuration)
It should also be noted that this proof of concept was intended to emulate
real-world expectations of a BIOS, meaning that nothing was done to achieve
results that could not reasonably be expected in a mass-market product design.
The steps that were taken for this effort should be easily portable to other
designs and should largely be codebase-independent .
Figure 15.4 shows the performance numbers achieved while maintaining
all of the various platform/marketing requirements for this particular system.
Chapter 15: Reducing Platform Boot Times n 309
SEC Phase Duration: 26342 (us) SEC Phase Duration: 26419 (us)
PEI Phase Duration: 1230905 (us) PEI Phase Duration: 763315 (us)
DXE Phase Duration: 998234 (us) DXE Phase Duration: 443021 (us)
BDS Phase Duration: 7396050 (us) BDS Phase Duration: 766778 (us)
The next several sections detail the various decisions that were made for
this proof of concept and how they improved the boot performance.
Marketing Requirements
Admittedly, marketing requirements are not the first thing that comes to mind
when an engineer sits down to optimize a BIOS’s performance. However, the
reality is that marketing requirements form the practical limits for how the
technical solution can be adjusted.
The highlighted requirements are the pivot points in which an engineer can
make decisions that ultimately affect performance characteristics of the system.
Since this section details the engineering responses to marketing-oriented
requirements, it does not provide a vast array of code optimization “tricks.”
Unless there is a serious set of implementation bugs in a given codebase,
the majority of boot speed improvements are achieved from following the
guidelines provided in this section. Not to worry though, there are codebase
independent “tricks” included that provide additional help.
or limit some of these expectations is where the platform policy can greatly
affect the resulting performance characteristics.
Platform Policy
One of the first considerations when looking at a BIOS and the corresponding
requirements are whether or not an engineer can limit the number of variables
associated with what the user can do “to” the system. For instance, it might be
reasonable to presume that in a platform with no add-in slots, a user will not
be able to boot from a RAID controller since the user cannot physically plug
one in.
This is where a designer enters the zone of platform policy. Even though a
platform may not expose a slot, the platform might expose a USB connection.
A conscious decision needs to be made for how and when these components
are used. A good general performance optimization statement would be:
“If you can put off doing something in BIOS that the OS can do—then put
it off!”
Since a user can connect anything from a record player to a RAID chassis
via USB, the user might think that they would be able to boot from a USB-
connected device if physically possible. Though this is physically possible, it is
within the purview of the platform design to enable or disable such a behavior.
In this particular platform, the decision was made to not support booting
from USB media and to not support the user interrupting the boot process.
This means that during the DXE/BDS phase, the BIOS was able to avoid
initializing the USB infrastructure to get keystrokes and this resulted in a
savings of nearly 0.5 second in boot time.
Note Even though 0.5 second of boot time was saved by eliminating late
BIOS USB initialization, upon launching the platform OS, the OS
was able to interact with plugged-in USB devices without a problem.
Note Changes in the BIOS codebase that avoided the unnecessary creation
of certain tables saved roughly 400 ms in the boot time.
■■ Does the motherboard have any devices built in that have a legacy
option ROM?
■■ Does the platform support adding a device that requires the launch of
a legacy option ROM?
■■ If any of the first two are true, does the platform need to initialize the
device associated with that option ROM?
One reason why launching legacy option ROMs is fraught with peril for boot
performance is that there are no rules associated with what a legacy option
ROM will do while it has control of the system. In some cases, the option
ROM may be rather innocuous regarding boot performance, but not always.
For example, the legacy option ROM could attempt to interact with the user
during launch. This normally involves advertising a hot-key or two for the user
to press, which would delay the BIOS in finishing its job for however long the
option ROM pauses waiting for a keystroke.
For this particular situation, we avoided the launching of all of the drivers
in a particular BIOS and instead opted to launch only the drivers necessary
for reaching the boot target itself. Since the device we were booting from was
a SATA device for which the BIOS had a native UEFI driver, there was no
need to launch an option ROM. This action alone saved approximately three
seconds on the platform. More details associated with this trick and others are
in the section “Additional Details.”
One could leverage the UEFI event services to take advantage of the
marketing-driven delay to accomplish other things, which effectively parallelizes
some of the initialization.
■■ A user downloads a special file from an OEM’s Web site and puts
it on a USB dongle and reboots the platform with the USB dongle
connected.
314 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
presume for some platforms that the established factory default settings are
sufficient and require no user adjustments. Most OEMs do not go this route.
However, it is certainly possible for an OEM to expose “applets” within the OS
to provide some of the configurability that would have otherwise been exposed
in the pre-OS timeframe.
With the advent of UEFI 2.1, and more specifically the HII (Human
Interface Infrastructure) content in that specification, the ability for
configuration data in the BIOS to be exposed to the OS was made possible.
This makes it possible for many of the BIOS settings to have methods exposed
and configured in what are not traditional (pre-OS) ways.
If it is deemed unnecessary to interact with the BIOS, there is very little
reason (except as noted in prior sections) for the BIOS to probe for a hot key.
This only takes time from a platform boot without being a useful feature of the
platform.
Additional Details
When it comes time to address some codebase issues, the marketing requirements
clearly define the problem space an engineer has to design around. With that
information, several methods can help that are fairly typical of a UEFI-based
platform. These are not the only methods, but they are the ones that most any
UEFI codebase can use.
At its simplest, the BDS phase is the means by which the BIOS completes
any required hardware initialization so that it can launch the boot target. At its
most complex, you can add a series of platform-specific, extensive, value-added
hardware initialization that is not required for launching the boot target.
Are We in an Are We in an
S3 Boot Mode? S3 Boot Mode?
Yes No Yes No
Diagnostics Boot
Boot
Connect Consoles
Diagnostics
Boot
(loaded into memory from flash), and the second one is when a driver is
connected to a device. Platform policy could dictate that the DXE core avoids
finding unnecessary drivers. For instance, if the USB device boot is not needed,
the USB-related drivers could be segregated to a specific FV, and material
associated with that FV would not be dispatched.
Summary
Ultimately, the level of performance optimization that is achievable is largely
subject to the requirements of the platform. Given sufficient probing, there are
almost always methods to achieve boot speed gains using some of the techniques
highlighted in this chapter. Here are some of the highlights of items to focus on
and areas within each BIOS codebase that deserve further investigation.
■■ Tweaks
–– Only initiate activity that the BIOS must do; the OS is often
going to repeat what the BIOS just did.
–– If no hardware changes are detected there is no need to re-
enumerate various subcomponents.
–– It may not be a need to probe boot options if we cache the last
known valid boot option.
■■ Analyze drivers that spend time blocking the boot progress. More
often than not, these drivers can gain improvements in performance
with minor adjustments.
–– If hard disk spin-up time is a blocking factor in the platform boot
times, the BIOS owner could adjust some of the logic to initiate
the disk spin-up in an earlier stage of the boot logic to mitigate
some of this slow-down and avoid a blocking behavior. Using an
EFI event for such an optimization may be very reasonable.
■■ First focus optimization work on the components that the BIOS
spends the most time on. Usually more optimization results can be
achieved in these components.
Chapter 16
Embedded Boot
Solution
Unless you try to do something beyond what you have already mastered, you
will never grow.
—Ralph Waldo Emerson
323
324 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Print Imaging
Industrial Voice
Example
6 Segments
Routers
Infotainment
This chapter describes the boot firmware challenges and solutions for these
market segments. The primary focus is to cover the platform boot solution,
which includes standard PC BIOS, bootloaders (also known as steploaders),
initial program loaders (IPLs, also known as second-stage bootloaders), and OS
boot driver components for running a shrinkwrap and/or industry standard
embedded OS.
CE Device Landscape
The Intel® Atom™ processor family of low power embedded processors are
making their way into many lower power platforms, the key being MIDs
(mobile Internet devices), netbooks and a variety of embedded markets as
enumerated above. Some of these segments are targeted towards consumers,
following the Consumer Electronics (CE) device model paradigm. One of the
Chapter 16: Embedded Boot Solution n 325
■■ Ease of use
■■ The time between power-on and the user interface becoming active,
also known as boot latency to user interface/human machine interface
(UI/HMI)
of it. Figure 16.2 identifies some of the components in the boot path that
contribute to the overall system boot latency as needed for the CE devices.
The following is a short list of some key components that contribute to the
overall boot latency to UI active time.
■■ Platform power sequencing latencies, such as stabilization of PLL/
Clocks, voltage regulators, and power rails
■■ Use of file system type for storing the boot image, such as ROM, FAT,
and EXT3
Graphics
Staged OS Power
Loading Management
Root File
System
Kernel (OS)
IPL Loader
(Stage-2)
Power
Sequencing
Hardware
A case study of one of the CE device usages for IVI with typical boot
requirements follows. The fast boot requirements for most other CE segments
are considered to be a subset of IVI, which has the most stringent requirements
of all.
In-Vehicle Infotainment
An IVI user expects an instant power-on experience, similar to that of most
consumer appliances like TVs. To meet this same expectation, one of the key
requirements of the IVI platform is the sub-second cold boot time, which helps
facilitate the user experience when the ignition key/button is turned on. The
typical boot latency requirements are as illustrated in Figure 16.3.
Chapter 16: Embedded Boot Solution n 329
Power On
to CPU Reset < 20 ms**
CAN
Display Driver Operable < 100 ms
Dependency
Hardware
Splash Self Init
Screen < 500 ms
MOST
Operable < 500 ms
PDC,
Human Machine Interface Beep < 2000 ms
(UI) < 5000 - 6000 ms
Key
Milestone
Legend:
Navigation Bootloader Dependency
On < 8000 to 15000 ms
OS Dependency
Within the requirements highlighted above, there are multiple key latency
checkpoints where the boot firmware plays a key role. These include:
■■ Power-on to splash screen active. The time between hardware power-
on and splash screen active is key because it helps improve the user
330 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ Power-on to the boot storage device active. The time between these
functions impacts the speed at which the OS can be shadowed and
launched by the Initial Program Load. This is typically done in the
early firmware boot sequence as part of the chipset initialization, to
hide the boot device ready latency such as hard disk spin-up, eMMC/
SD device ready, and so on.
Generic Requirements
Traditional platforms typically have boot latencies to UI active times that
average 10–40 seconds. Getting this UI active latency down to below 5–6
seconds, with an active splash screen in less than 500 ms is a big challenge.
To reduce time to market and product development costs, it is highly desired
to develop one boot firmware and OS solution that can scale across different
CE device platforms from each of the OEMs with varying topologies, but
based on the same SoC core. Many optimizations were done to both the
BIOS and bootloader solutions to fit into the IVI platform and the same can
be easily extended to any CE device. The key being the reordering and early
initialization of user-visible I/O like display activation, initial program load
(IPL) boot menus, enabling processor cache usage at boot as high speed RAM
(CAR), and so on.
The basic or generic bootloader for any CE device model requires the
following attributes:
■■ Low Boot Latency. The generic boot requirements for a CE device can
be summarized as: power-on to OS handoff in less than one second
and splash screen in less than 500 ms.
Set Up
Interrupt Mode Find and
Memory
Initialize
Configuration
Expansion ROMs
Advanced Cache
Initialization
Initialize Stack,
Jump to Initialize
Advanced Memory Map
Initialization Shadow ROM
to RAM
Initialize Legacy
Services
Miscellaneous - Optional
Device
Initialization
Initialize
MP Tables
Configure SIO,
Enable Serial
Con - Optional
Call User
Init Functions
Initialize
kdb/Mouse -
Optional
Boot Strategies
To fit most of the usage models described above, different CE device boot
strategies are adopted, namely Fixed Topology Systems, Binary Modules model
and Simplified bootloader, as described below:
■■ Fixed Topology Systems. This strategy uses standard ACPI-compliant
UEFI BIOS with a fixed platform topology and a compliant IPL,
such as eLilo. This is typically used with aftermarket products that
may run an embedded version of a shrinkwrap OS, but with varying
I/O devices that are chosen by the end customer (such as Standard
Embedded Linux or Window XPe). The BIOS is required to provide
PC compatibility and is readily available from the independent BIOS
vendors (IBV) or Original Device Manufacturers (ODM). This
solution provides the most flexibility for seamless addition of I/O for
each of the OEM machine topologies, but at the expense of higher
boot latencies. Many of the initialization sequences in the boot path
are optimized to reduce the latencies significantly in the order of 5–10
seconds. Some of the noncritical PC BIOS functions such as PCIe
device enumeration, OptionROM scanning, memory testing, POST,
and video BIOS usage may be eliminated or simplified during the
boot sequence. Disabling of these and other functions help reduce
the boot latencies significantly. Refer to the white paper on one such
implementation and the optimizations done for it:
http://download.intel.com/design/intarch/papers/320497.pdf
■■ Binary Modules with Configuration. This is the most highly optimized
solution for the CE platform for low boot latencies and is tightly
coupled to the functions on the SoC. Since the functions of the
SoC do not change across different OEM implementations, one
single firmware image compiled from a set of object libraries would
suffice to boot all platforms built around the SoC. The OEM may
use a development kit, which would allow customization facilitated
through a set of exposed application programming interfaces (APIs)
in the objects. These object APIs could perform basic and advanced
initialization and control tasks like the following:
–– Processor initialization (including multiprocessor support, cache
configuration, and control)
336 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Power Management
Traditional Intel architecture platforms support various power management
capabilities to conserve power of battery powered devices and to reduce
thermal dissipation for AC powered devices. The CE device will leverage from
the same power states as defined in the ACPI specification (Sx) and (Dx), but
with or without ACPI support in the firmware. A simplified ACPI table or its
equivalent, with a capability to communicate standby (S3) state wake-up vector
information between the OS and the firmware is the minimum requirement
for this usage model.
As highlighted earlier, one of the key design goals of the CE device is a
fast boot in the order of seconds. Typically, any resumption from Suspend/
Hibernate back to active state involves restoring the previous state. In certain
CE device use cases, the Resume from Sleep (suspend to RAM) could be used
for sub-second fast boot purposes. However, Sleep mode is undesirable for
some CE device use cases like IVI, due to the battery drain from DRAM leakage
current in an extended park scenario or a need to avoid inadvertently restoring
one user context for another for a rental car scenario. This makes the fast cold
boot with a completely fresh state on every power-on a key requirement for the
CE device architecture.
Partitioning Differences
e•MMC 4.3 e•MMC 4.4
SPI Legacy
Address Range Boot Code
Boot Code Partitions
(XIP)
SDIO Partition 1
Block Storage (High Performance)
Device User Area
Partition 2
(High Performance)
OS Partition
User Area
(High Density)
Write Protected
Flash with Boot Partition
Unprotected
Top 1MB
Boot Partition
(NOR Latencies)
0xFFFFFFFF
CRT M
Boot FW
User
CMC
NAND
(eMMC)
SPI Legacy 0xFFF80000
Address Range 1-32GB
(XIP)
Empty
0xFFF20000
ROMBoot
Loader
0xFFF00000
Descriptor
SDIO
Block Storage
Device
Security
Different embedded segments have varying security requirements collectively
categorized as Security. These security requirements apply to two different
usage models, which are orthogonal to each other:
■■ Security as it relates to platform defense against attacks from hackers
and malware.
Based on the usage model described in Table 16.1, the assets on the platform
that need to be protected from a hacker are as follows:
■■ Platform resources including: CPU, memory, and network (3G,
WiMax, Wi-Fi)
Trust Boundary
p-Unit
CRTM in
OS
BootROM BIOS OS App
Loader
(HW RoT)
The BootBlock can be burned into ROM so that it can not be modified
and hence can act as a hardware RoT. Core Root of Trust for Measurement
(CRTM) is the root of trust from which integrity measurements begin within a
trusted CE device platform. The platform manufacturer provides CRTM logic
for each trusted platform. The CRTM logic can be changed, but only under
controlled conditions by the OEM.
The OS loader, kernel, and drivers will be measured as part of the CE device
measured boot flow. The details of a typical chain of trust for measurement
with a TPM device and PCRx are outlined as follows:
■■ CRTM measures firmware (bootloader or BIOS)
–– Stores the measurement in PCR-0
–– Standard OS handoff tables like ACPI, E820, and EFI
measurements are stored in PCR-1
–– Any option ROM measurements are stored in PCR-2
■■ Bootloader/BIOS measures OS Initial Program Load (IPL)
–– Stores the measurement in PCR-4
344 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Manageability
The manageability framework, also known as the Device Management (DM)
framework, provides services on the client platform for use by IT personnel
remotely. These services facilitate key device management functions such as
provisioning, platform configuration changes, system logs, event management,
software inventory, and software/firmware updates. The actual services enabled
on a particular platform are a CE OEM choice. The following sections describe
the two key frameworks in use for a CE device, namely OMA-DM and AMT.
Open Mobile Alliance - Device Management (OMA-DM) is one of
the popular protocols that would allow manufacturers to cleanly build
Chapter 16: Embedded Boot Solution n 345
DM applications that fit well into the CE device usage model. Many of
the standard operating systems support OMA-DM or a variation of it with
enhanced security. The data transport for OMA-DM is typically over a wireless
connectivity such as WiMax, 3G/4G, and so on. This protocol can run well on
top of the transport layers such as HTTPS, OBEX, and WAP-WSP. The CE
device platform would be able to support this, as long as the OEM supports
the connectivity and the client services.
The other possible framework for manageability is Intel® Active Management
Technology (Intel® AMT). Intel AMT provides a full featured DASH-compliant
manageability solution that can discover failures, proactively alert, remotely
heal-recover, and protect. Intel AMT Out of Band (OOB) device management
allows remote management regardless of device power or OS state. Remote
troubleshooting and recovery could significantly reduce OEM service calls.
Proactive alerting decreases downtime and minimizes time to repair.
In the manageability space, making DASH-compliant manageability on
CE platform is opportunity that allows OEM differentiation and provides a
much richer manageability features.
Summary
The need for a boot solution that is low cost, has a small footprint, offers low
boot latencies, and is platform-agnostic provides an exciting opportunity to ISVs
and OSVs to develop and deliver such tool kits. This also creates opportunities
for CE device OEMs to provide creative solutions of their own, making their
products more competitive and unique. In addition, device vendors can take
advantage of opportunities to provide hardware IP (Intellectual Property) that
are self initializing, thereby relieving the boot software from doing the same
and giving back some time to improve latencies.
The challenge that remains to be addressed is a single boot firmware
solution that can boot both shrinkwrap operating systems that require PC
compatibility and embedded operating systems. There are multiple challenges
to be addressed with innovative solutions like supporting security features,
manageability, and a unified storage device like an eMMC, all with the key
low boot latency attribute. Finally, there are opportunities for the OS vendors
to come up with innovative optimizations within the OS boot flows to achieve
faster boots.
346 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Chapter 17
Manageability
I came, I saw, and I conquered.
—Julius Caesar
347
348 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
WS-MAN
Dynamic In-Band
In-Band error management is typically handled by software that is part of
the standard system software stack consisting of system BIOS (SMI/PMI),
operating system, device drivers/ACPI control methods, and user mode
manageability applications running on the target system. The key technologies
that are covered in this context are as follows:
■■ Standardized UEFI error format
1
SMI: System Management Interrupt of x86 processor; PMI: Platform Management Interrupt of Itanium® processor
350 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Out-of-Band
Out-of-band error management is handled by out-of-band firmware such as,
for example, firmware running on BMCs conforming to IPMI standards. The
key technologies that are covered in this space are:
■■ IPMI
■■ Intel AMT
Machine Check
Exception
OS Legacy
Interface (MCE)
IPMI
Native OS SMI
MSR Error
Access Firmware Handler
Processor Platform
F/W Controlled
Logging-Settings
H/W
F/W Error Logs (H/W)
CSRs:
Err Detection Mux
Writes
- Corrected Errors
- Uncorrected Errors
Err Log Mux
SMI Enable
CPEI Enable
MCERR En Operating System
S/W
Err Signal Mux
Based on this state of OS error handling and the identified needs for future
enhancements, a new architecture framework has been defined. This framework
is based on the top-down approach, with the OS usage model driving various
lower level system component behaviors and interfaces.
Error management includes two different components, namely error
notification/signaling and error logging/reporting, for all system errors. The
fundamental component of this architecture is a model for error management,
which includes an architected platform firmware interface to the OS. This
interface was defined to facilitate the platform to provide error information to
the OS in a standardized format. This firmware-based enhanced error reporting
will coexist with legacy OS implementations, which are based on direct OS
access to the architected processor hardware error control and status registers,
such as the processor machine check (MC) Banks.
The architected interface also gives the OS an ability to discover the
platform’s error management capabilities and a way to configure it for the
chosen usage model with the help of standardized error objects. This enables
the OS to make the overall system error handling policy management decisions
through appropriate system configuration and settings.
To facilitate abstracted error signaling and reporting for most common
platform in-band errors, namely those emanating from the processor and
chipset, a new UEFI/ACPI Error Interface extension was defined with the
following goals:
■■ Achieve error reporting abstraction for architectural and non-
architectural platform functional hardware
Manageability
Software OS Error Handling Components
Machine Check
Exception
UEFI IPMI
SMI AMT
Error
Interface Handler
Firmware
Processor Platform
■■ Initilization (INIT)
■■ Boot
■■ DMAr
Creator Identifier
Creator ID record types are associated with event notification types, but the
actual creator of the error record can be one of the system software entities.
This creator ID is a GUID value pre-assigned by the system software vendor.
This value may be overwritten in the error record by subsequent owners of the
record than the actual creators, if it is manipulated. The standard creator IDs
defined are as follows:
■■ Platform Firmware as defined by the firmware vendor
■■ OS vendor
358 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
■■ OEM
An OS saved record to the platform nonvolatile storage will have an ID created
by the OS, while platform-generated records will have a firmware creator ID.
The creator ID has to be specified during retrival of the error record from
platform storage. Other system software vendors (OS or OEM) must define a
valid GUID.
Error Capability
The error capability record type is associated with platform error capability
reporting and configuration. Error capability is reserved for discovering
platform capabilities and its configuration.
For further details on the APIs to get/set/clear error records from the non-
volatile storage on the platform through UEFI, refer to the UEFI 2.3 or above
specification.
Management/Reporting Applications
WMI Management
ETW Error
Interface
Notifications
Kernel
Hardware/Firmware (UEFI/ACPI)
Provided by:
The layout of the UEFI standardized error record format used by WHEA
is illustrated in Figure 17.6.
362 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Record Header
Some of the standard error sources and global controls covered by WHEA/
UEFI are as described in Table 17.1.
Table 17.1 Standard Error Sources and Global Controls Covered by WHEA/UEFI
Error Sources System Interrupts and Exceptions: NMI, MCE, MCA, CMCI,
PCIe, CPEI, SCI, INTx, BOOT
Standard Error Formats Processor, Platform Memory, PCIe, PCI/PCI-X Bus, PCI
Component
It is beyond the scope of this chapter to go into the details of the dynamic
error handling flow. However, Figure 17.7 provides an overview of the error
handling involving the firmware and OS components.
Chapter 17: Manageability n 363
Processing Options:
1. Error Collection
from platform
2. Error Correction
Attempt (ex: Memory Uncorrected/Corrected
Migration, Mirroring) Hardware Error Event
3. Error Recovery
Attempt
4. Predictive Failure
Analysis Running OS OS Logs Errors
5. Messaging to & Continues
Management Console
6. Other OEM actions
No Error Event
Valid Error Event
Poll For Polling
Error Interrupt Handler
Invoked Corrected Errors
in Hardware or
Firmware
OS Error Errors
Handler Found
OS Error
Handling
Successful
No
Reboot
ICMB
(Intelligent Chassis Management Bus)
REMOTE
MANAGEMENT CARD
RS-485
Transceivers
Serial
LAN Controller
Modem
ICMB
BRIDGE
(optional)
LAN Serial Aux. IPMB Aux. IPMB
Connector Connector Connector Connector
PCI Management
Bus IPMB
Side-band
Interface Non-volatile Storage CHASSIS
to NIC, • System Event Log (SEL) MANAGEMENT
Network e.g. BASEBOARD • Sensor Data Record (SDR)
(LAN) SMBus MANAGEMENT Repository (SATELLITE
CONTROLLER • Baseboard Field-Replaceable CONTROLLER)
Controller Unit (FRU) Info
(BMC)
Sensors & Control Circuitry
e.g. Voltages, FRU
Serial Temperatures, Fans, SEEPROM
Port Serial Power & Reset Control, etc.
Controller Chassis
Sharing Private Management Busses Sensors
e.g. Fans,
Temperatures,
Motherboard System Interface Power Supplies
Serial
Controller FRU FRU CHASSIS BOARD
IPMI SEEPROM SEEPROM
Messages
System Bus Temperature FRU
Sensor SEEPROM
MOTHERBOARD
MEMORY PROCESSOR REDUNDANT
BOARD BOARD POWER BOARD
IPMI has defined a set of standard sensors, which would monitor different
platform functions and generate events and report them through the system
event log interface (SEL) as 16-byte error log entries. Each of the sensors
in turn is associated with Senor Data Record (SDR), which describes the
properties of the sensor, to let the manageability software discover its capability,
configurability and controllability and the error record associated with it. A set
of predefined controls for use by manageability software is also defined by
the IPMI specification, in addition to other OEM-defined controls through
SDR. The standard sensors along with the standard controls do allow a level of
standardization for managing these out-of-band errors. Some of the standard
sensor and global controls are as described captured below in Table 17.2.
366 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Serialization (SOAP)
Transport (HTTP)
Connection (TLS)
Like IPMI, one of the key interfaces of Intel AMT is event management,
which allows configuring hardware and software events to generate alerts and
to send them to a remote console and/or log them locally.
Remote
Local Management Access Management Access
WS-MAN Local Management
Management S/W Management Applications
Applications XML/SOAP
WS-MAN
Stacks
XML/SOAP
Instrumentation Provider
WS-MAN
Over LAN
IPMI/AMT Driver
IPMI/MEI
IPMI/AMT HW Interface
BMC/ME
and Monitoring H/W
Figure 17.11 Management Build Blocks Linking IPMI, HPI, UEFI, and WHEA
platform-specific interface between UEFI and the IPMI firmware layers for
exchange of this information. It is also possible for the UEFI to extend and
define yet another error format for IPMI SEL logs identified with a new GUID.
This way, an OS or manageability application would be able to get complete
platform errors for in-band and out-of-band errors in a standardized format
through one single UEFI-based interface. UEFI can intercept the IPMI sensor
events through the firmware first model as defined by Microsoft WHEA and
provide the SEL logs to the OS. This type of extension can be modeled along
the Itanium Processor Machine Check Architecture specification for IPMI
error logging and is an area of opportunity of future standardization effort.
Future Work
Table 17.4 shows the four areas of potential work for standardization that offers
interesting possibilities:
■■ Bridge over the Intel AMT/IPMI functionality over to the UEFI-OS
error reporting
372 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Table 17.4 Manageability and error management standards and possible future
work.
Summary
In the case of manageability, the UEFI framework will help make platforms
more robust and reliable through remote management interfaces like Intel
AMT, and WS-MAN, to meet the RAS goal of five nines. This unified approach
would be a win-win to all (OEM, IBV, OSV), to deliver a great end user value
and experience with a complete solution for in-band and out-of-band error
and event management.
The net result of the level of abstraction provided by UEFI/WHEA and
Intel AMT/IPMI technologies in security and manageability space will now
enable many vendors to develop OS-agnostic unified tools and application
software for all embedded/client/server platforms. This would allow them to
spend their efforts on innovation with a rich set of features at the platform level
rather than on developing multiple platform-specific implementations for the
same manageability functionality.
Appendix A
Data Types
T able A.1 contains the set of base types that are used in all UEFI
applications and EFI drivers. Use these base types to build more complex
unions and structures. The file EFIBIND.H in the UDK 2010 located on
www.tianocore.org contains the code required to map compiler-specific data
types to the UEFI data types. If you are using a new compiler, update only
this one file; all other EFI related sources should compile unmodified. Table
A.2 contains the modifiers you can use in conjunction with the UEFI data
types.
Mnemonic Description
BOOLEAN Logical Boolean. 1-byte value containing a 0 for FALSE or a 1 for TRUE.
Other values are undefined.
INTN Signed value of native width. (4 bytes on IA-32, 8 bytes on Itanium®-
based operations)
UINTN Unsigned value of native width. (4 bytes on IA-32, 8 bytes on Itanium®-
based operations)
INT8 1-byte signed value.
UINT8 1-byte unsigned value.
INT16 2-byte signed value.
UINT16 2-byte unsigned value.
INT32 4-byte signed value.
UINT32 4-byte unsigned value.
INT64 8-byte signed value.
373
374 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Mnemonic Description
377
378 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
381
382 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
C D
Cache-as-RAM (CAR) 284–286 Denial of Service 231
CAR. See Cache-as-RAM (CAR) Dependency Expression 160, 275
Central Processing Unit (CPU) 21, 122, 178, 285, supported op codes 161
308 Device Drivers 48–51, 53, 56
Certificate Authorities (CAs) 64 Device Handle 48–50
CLI. See Command Line Interface (CLI) Device Path Protocol 47, 48, 74, 76, 183
Command Line Interface (CLI) 133 Disk I/O Protocol 168, 190
Configuration Access Protocol 196–198 Distributed Management Task Force (DMTF)
Configuration Table 149 350, 369
console DMA Operations 171
devices 164 DMTF. See Distributed Management Task Force
services 77, 103, 132 (DMTF)
splitter 116–118 DRAM. See Dynamic RAM (DRAM)
stack 133 Driver Binding Protocol 43, 45, 49–51
Consumer Electronics (CE) Device Driver Execution Environment (DXE)
boot challenges 325 applications 169, 216
boot strategies 335 architectural protocols (APs) 144–152, 162,
firmware 342 176, 267
384 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
W
Watchdog Timer
architectural protocols (APs) 147
Web Services Management Protocol 350, 364,
368–370, 372
WHEA. See Windows Hardware Error Architecture
(WHEA)
Windows Authenticode Portable Executable
Signature Format 64
Windows Hardware Error Architecture (WHEA)
350, 370, 371
WinNtThunk Capability 294, 298, 299
Wired for Management Baseline specification 248
WS-MAN. See Web Services Management Protocol
X
XIP. See Execute-In-Place (XIP)
Z
396 n Beyond BIOS: Developing with the Unified Extensible Firmware Interface
Continuing Education is Essential
These technical books are planned to synchronize with roadmaps for technology and
platforms, in order to give the industry a head-start. They provide new insights, in an
engineer-to-engineer voice, from named experts. Sharing proven insights and design
methods is intended to make it more practical for you to embrace the latest
technology with greater design freedom and reduced risks.
I encourage you to take full advantage of Intel Press books as a way to dive deeper
into the latest technologies, as you plan and develop your next generation products.
They are an essential tool for every practicing engineer or programmer. I hope you
will make them a part of your continuing education tool box.
Sincerely,
ISBN 0-9764832-1-1
Dong Wei
Vice President and Chief Executive,
the Unified EFI Forum
HP Distinguished Technologist
ESSENTIAL BOOKS FOR SYSTEM DEVELOPERS
ISBN 0-9764832-1-1
www.intel.com/intelpress/bookbundles.htm
Our products are planned with the help of many people in the developer
community and we encourage you to consider becoming a customer advisor.
If you would like to help us and gain additional advance insight to the latest
technologies, we encourage you to consider the Intel Press Customer
Advisor Program. You can register here:
www.intel.com/intelpress/register.htm
For information about bulk orders or corporate sales, please send email to
bulkbooksales@intel.com
Beyond BIOS
Developing with the Unified Extensible Firmware Interface
ABOUT THE AUTHORS