Computer platform firmware is used during initialization of computer systems to verify system integrity and configuration. It also generally provides the basic low-level interface between hardware and software components of those computer systems, enabling specific hardware functions to be implemented via execution of higher-level software instructions contained in computer programs that run on the computer systems. In many computers, a primary portion of this firmware is known as the Basic Input/Output System (BIOS) code of a computer system. The BIOS code comprises a set of permanently recorded (or semi-permanently recorded in the case of systems that use flash BIOS) software routines that provides the system with its fundamental operational characteristics, including instructions telling the computer how to test itself when it is turned on, and how to determine the configurations for various built-in components and add-on peripherals.
Typically, firmware code is stored in a “monolithic” form comprising a single set of code that is provided by a platform manufacturer or a BIOS vendor such as Phoenix or AMI. Various portions of the single set of code are used to initialize different system components, and to provide various runtime services. Since there is only a single set of code, the trustworthiness and reliability of the firmware may be verified through testing by its producer. In other situations, a monolithic BIOS may be extended using one or more “Option ROMs” that are contained on one or more periphery device cards. For example, SCSI device driver cards and video cards often include an option ROM that contains BIOS code corresponding to services provided by these cards. Typically, firmware in option ROMs is loaded after the firmware in the monolithic BIOS has been loaded or during loading of the monolithic BIOS in accordance with a predefined scheme.
Recently, a new firmware architecture has been defined that enables platform firmware to include firmware “modules” and “drivers” that may be provided by one or more third party vendors in addition to the firmware provided by a platform manufacturer or BIOS vendor that is originally supplied with a computer system. This firmware architecture is called the Extensible Firmware Interface (EFI) (specifications and examples of which may be found at http://developer.intel.com/technology/efi). EFI is a public industry specification that describes an abstract programmatic interface between platform firmware and shrink-wrap operation systems or other custom application environments. The EFI framework include provisions for extending BIOS functionality beyond that provided by the BIOS code stored in a platform's BIOS device (e.g., flash memory). More particularly, EFI enables firmware, in the form of firmware modules and drivers, to be loaded from a variety of different resources, including primary and secondary flash devices, option ROMs, various persistent storage devices (e.g., hard disks, CD ROMs, etc.), and even over computer networks.
Another consideration for firmware development is the ability to port code to different processor instruction sets and across platform architectures. To address this development aspect, the EFI framework provides a processor-independent intermediate language (IL) known as EFI byte code or EBC. Drivers and modules written in EBC are interpreted at execution time by an appropriate interpreter for the platform, enabling a common set of EBC to support different platform architectures.
Although the EFI framework provides many advantages, it opens up the opportunity for a system to be disabled or damaged through use of an errant or rogue firmware module or driver. For example, a flawed firmware module may not operate properly, causing one or more system components to be disabled. Even worse, it may cause problems to the operation of other firmware components and modules. This problem is further exacerbated when EBC is employed. For implementation simplicity, EBC does not provide formalized type-safety guarantees, such as those found in other intermediate languages (e.g., Java). As a result, the behavior of EBC code on different platform architectures is not always predictable, and there are no existing provisions to ensure safe execution.