More Power To Firmware

© Amit Singh. All Rights Reserved. Written in June 2004

Part I: The Firmware Scene

Introduction

The PC BIOS is as old as the PC itself, while the acronym BIOS is even older, dating back to the CP/M operating system. BIOS (Basic Input/Output System) was one of the three primary components of CP/M, the other two being BDOS (Basic Disk Operating System) and CCP (Console Command Processor).

Firmware

Firmware may be defined as software residing in (or embedded in) hardware, such as some kind of a programmable read-only memory. Thus, a typical BIOS is also a firmware, but every firmware is not considered a BIOS. We shall use the term BIOS for PC firmware.

There may be several pieces of firmware in a computer system, including "really low-level" ones that execute before the user-visible firmware. In a simplified view, we consider the firmware to be the one that is user-visible. We can think of this firmware as sitting atop the hardware. Both the bootloader and the operating system (for certain purposes, at least) interact with the firmware.

Legacy Pains

One reason for the longevity of the BIOS, and for its sustained primitivity, is the insanely successful DOS (for the PC), which was built on top of the BIOS. DOS programs call BIOS routines via software interrupts (for example, the BIOS disk routine corresponds to INT 0x13). Note that this is similar to many erstwhile Apple systems where the Macintosh ROM contained both low-level code (such as for hardware initialization, diagnostics, drivers, etc.) and the higher level "Toolbox" -- a collection of reusable software routines.

In a "modern" setting, the old-fashioned BIOS has severe limitations, even though it has seen numerous tweaks, improvements, extensions, and additions over the years. Consider some examples:

A small range of extended memory addresses can be accessed in real mode (Gate A20). 386 and higher x86 processors can be switched from protected mode to real mode without a reset, which allows them to operate in the Big Real Mode: a modified real mode in which the processor can access up to 4 GB of memory. BIOSs can put the processor in this mode during POST (Power On Self Test) to make access to extended memory easier.

A representative legacy BIOS could be visualized as containing three sets of procedures: those that are the same on all BIOSs (the core procedures), those that are specific to chips on the platform (the silicon support procedures), and those that are specific to the system board. There is a great deal of "secret-sauce" element in the BIOS. The BIOS APIs are very limited, and it is very hard to extend the BIOS -- it is a black box not just to end users, but also to those who wish to develop pre-boot or pre-OS applications (as value-add, say). Even if such developers license the BIOS source, the environment is expensive to develop for in all respects (including deployment).

A Bit of a Problem

64-bit computing came relatively late to the PC world. With the advent of 64-bit PCs (those based on the Itanium Processor Family, for example), a better solution to the "BIOS problem" was sought, although the x86 real mode can be emulated in IA-64.

New Beginning

64-bit PCs do not use legacy BIOS. The IA-64 firmware is divided into three primary components: the Processor Abstraction Layer (PAL), the System Abstraction Layer (SAL), and the Extensible Firmware Interface (EFI).

PAL abstracts the processor hardware implementation from the point of view of SAL and the operating system. Different processor models with potential implementation differences appear uniformly via PAL. Examples of the PAL layer's functionality include:

PAL has no knowledge of platform implementation details. Note however that PAL is part of the IA-64 architecture. The firmware implementation of PAL is supplied by the processor vendor, and it resides in OEM flash memory.

SAL provides an abstraction for the platform implementation, without any knowledge of processor implementation details. SAL is not part of the IA-64 architecture -- it is part of the Developer's Interface Guide for 64-bit Intel Architecture (DIG64). The firmware implementation of PAL is provided by the OEM.

As on IA-32 systems, Advanced Configuration and Power Interface (ACPI) exists as an interface for allowing the operating system to direct configuration and power management on the computer. ACPI is also a part of the firmware, and could be listed as the fourth primary component. Note that since EFI also exists for IA-32, only PAL and SAL are the IA-64 specific parts of an IA-64 firmware.

The remaining component, EFI, could be thought of as the grand solution to the BIOS problem -- for PCs.

Extensible Firmware Interface

The Extensible Firmware Interface (EFI) can be traced back to the "Intel Boot Initiative" (IBI) program (1998, but see Innovate[2] later in this document)). The EFI specification, developed and maintained by a consortium of companies (including Intel and Microsoft), defines a set of APIs and data structures to be exported by a system's firmware, and to be used by a variety of clients, such as:

In a representative EFI system, a thin Pre-EFI Initialization Layer (PEI) might do most of the POST-related work that is traditionally done by the BIOS POST. This includes things like chipset initialization, memory initialization, bus enumeration, etc. EFI prepares a Driver Execution Environment (DXE) to provide generic platform functions that EFI drivers may use. The drivers themselves provide specific platform capabilities and customizations.

EFI Services

There are two types of services available in the EFI environment: Boot Services and Runtime Services. Applications that run only within the pre-boot environment make use of boot services, which include services for events, timer, and task priority, for memory allocation, for handling EFI protocols, for loading various types of images (EFI applications, EFI boot services drivers, EFI runtime drivers), and for miscellaneous purposes.

An operating system loader also uses boot services to determine and access the boot device, allocate memory, and create a functional environment for the operating system to start loading. At this point, an OS loader could call the ExitBootServices() function, after which boot services will not be available. Alternatively, an operating system kernel could call this function.

Runtime services are available both before and after ExitBootServices(). This category includes services for:

EFI was designed for computers based on the Itanium Processor Family (IPF), but its scope has been widened to include the next generation of IA-32 computers, with provisions for compatibility with legacy BIOS through a Compatibility Support Module (CSM) -- a series of drivers cooperating with a legacy BIOS runtime component. CSM loads into memory in well-known legacy areas (below 1 MB). Standard BIOS memory areas such as the Bios Data Area (BDA) and the Extended BDA are initialized. The Boot Device Selection (BDS) mechanism appropriately selects either EFI or legacy BIOS.

Current day IA-64 computers use EFI-based firmware. Gateway even sells an IA-32 system with EFI-based firmware: the Media Center 6x0, which uses Insyde Software's InsydeH2O firmware. InsydeH2O includes a CSM for legacy BIOS runtime compatibility.

Intel and Microsoft are behind EFI. One of the major BIOS manufacturers, American Megatrends, Inc. (AMI) already has products based on EFI: AMI Enterprise64 for IPF, and AMIBIOS8 with an add-on EFI-32 eModule for the IA-32. Another major player, Phoenix, is currently adopting a somewhat more incremental approach, but apparently has intentions for supporting EFI. Device vendors such as ATI and Adaptec are also supporting EFI. It is expected (by those behind EFI) that EFI would be the primary, if not the only, firmware used in new PC systems within the next two to three years.

EFI Drivers

EFI drivers can come from non-volatile memory, from the option ROM of a card, or from a device that EFI supports natively.

Most EFI drivers would conform to the EFI Driver Model. Such drivers are written in C and operate in a flat memory model. Driver images may be converted to EFI Byte Code (EBC), and are typically compressed (using Deflate, a combination of LZ77 compression and Huffman coding). Examples include:

Drivers that may not conform to the EFI Driver Model include:

EFI drivers consume various protocols (PCI I/O, Device Path, USB I/O, USB Path, etc.) and produce several other protocols (Simple Input, Simple Pointer, Block I/O, UGA Draw, UGA I/O, Simple Text Output, SCSI Block I/O, SCSI Passthrough, Network Interface Identification, Serial I/O, Debug Port, Load File, etc.)

Benefits

EFI aims to be a powerful and modular firmware that is readily extensible, even by (power) users. Some noteworthy aspects of EFI include:

Preeminence of Pre-boot

As PC hardware and software vendors try to differentiate their offerings, the pre-boot environment is getting increasingly important. A computer with pre-boot functionality for backup and restore, recovery, virus scanning, etc. would have more perceived value than one without. In some cases, an application must be pre-boot, because it cannot rely on the operating system -- for example, applications for performing low-level diagnostics, recovering the operating system, and updating certain firmware. In some other cases, an application may not need the "full" operating system, and may explicitly wish to run without the operating system, so as to make the computer behave like an appliance -- for example, a DVD or MP3 player, a mail client, web browser, etc.

With legacy BIOS, such pre-boot applications are rather expensive to develop, deploy, and run. EFI strives to simplify this domain greatly and includes specifications for creating pre-boot software. Even the end-user could create a pre-boot application using familiar development tools.

EFI's pre-boot environment is also meant to facilitate robust solutions for secure network booting, secure network resetting, remote provisioning and setup (through bootable "agents" that are EFI objects), remote management of system firmware, and so on. Thus, it is easier to deploy and manage a large number of "headless" servers.

Example EFI Environment

Following is a "site map" of a hypothetical user-visible EFI environment you may be presented with on an EFI-based machine:

(o) Power On | +-+ Boot Manager | +-+ Device Path(s) To OS Loader(s) | | | +-- Windows XP-64 | +-- Linux IA-64 | +_+ Boot Maintenance | | | +-- Change Boot Order | +-- Boot From Specified File | +-- Add Boot Options | +-- Select Console I/O | +-+ Launch EFI Shell | +-- Various shell functions

EFI Shell

The EFI environment (optionally) includes an interactive shell that allows a user to do a wide variety of tasks:

The EFI shell has flavors of both the DOS command prompt and a rudimentary Unix shell. It is implemented in C, and is developer extensible.

Following are some examples of using the EFI shell, most of which are self-explanatory:

fs0:\> ver EFI Specification Revision : 1.10 EFI Vendor : INTEL EFI Revision : 14.62 fs0:\> ls Directory of: fs0:\ 06/12/04 02:30a <DIR> 4,096 diskutils 11/24/03 07:50p 401,773 Efildr 06/12/04 02:32a <DIR> 4,096 apps 1 File(s) 401,773 bytes 2 Dir(s) fs0:\> devices -b C T D T Y C I R P F A L E G G #P #D #C Device Name == = = = == == == =============================== 06 R - - - 2 - FAT File System [FAT12] 1440 KB 07 R - - - 2 2 VenHw(Unknown Device:80) 0C R - - - 1 11 Acpi(PNP0A03,0) 1B D - - 1 - - Primary Standard Error Device 1C D - - 1 - - Primary Console Input Device 1D D - - 1 - - Primary Console Output Device ... fs0:\> dh -b Handle Dump 1: Varstore 2: Image(EFI Core) 3: DevIO DevPath () 4: UnicodeCollation 5: Image(BiosDisk) 6: Fs DiskIo BlkIo DevPath (Acpi(PNP0604,0)) ... fs0:\> cd apps fs0:\apps> ls Directory of: fs0:\apps 06/11/04 01:32a <DIR> 4,096 . 06/11/04 01:32a <DIR> 0 .. 06/11/04 02:18a 15,360 DrawBox.efi 06/11/04 02:18a 163,840 dhclient.efi 06/11/04 02:18a 114,688 ed.efi 06/11/04 02:18a 33,280 edit.efi 06/11/04 02:18a 14,848 extboot.efi 06/11/04 02:18a 192,512 ftp.efi 06/11/04 02:18a 73,728 hexdump.efi 06/11/04 02:18a 65,536 hostname.efi 06/11/04 02:18a 126,976 ifconfig.efi 06/11/04 02:18a 90,112 loadarg.efi 06/11/04 02:18a 73,728 mkramdisk.efi 06/11/04 02:18a 65,536 nunload.efi 06/11/04 02:18a 21,504 osloader.efi 06/11/04 02:18a 126,976 ping.efi 06/11/04 02:17a 19,968 pktsnoop.efi 06/11/04 02:17a 16,896 pktxmit.efi 06/11/04 02:17a 172,032 pppd.efi 06/11/04 02:17a 16,384 ramdisk.efi 06/11/04 02:17a 15,360 rtdriver.efi 06/11/04 02:17a 14,336 rtunload.efi 06/11/04 02:17a 16,896 test.efi 06/11/04 02:17a 4,608 test3.efi 06/11/04 02:24a 339,968 python.efi 06/11/04 02:24a 73,728 which.efi 06/11/04 02:24a 21,504 testvrt.efi 06/11/04 02:24a 15,360 testva.efi 06/11/04 02:24a 15,872 test4.efi 06/11/04 02:24a 14,848 test2.efi 06/11/04 02:24a 172,032 tcpipv4.efi 06/11/04 02:23a 126,976 route.efi 06/11/04 02:23a 335,872 zh_tw.efi 31 File(s) 2,571,264 bytes 2 Dir(s) fs0:\apps> load tcpipv4.efi Interface attached to lo0 Interface attached to ppp0 Timecounter "TcpIpv4" frequency 18 Hz Network protocol loaded and initialized load: Image fs0:\apps\tcpipv4.efi loaded at 0xBDBA000 - Success fs0:\apps> ifconfig -a lo0: flags=8008<LOOPBACK,MULTICAST> mtu 16384 ppp0: flags=8010lgt;POINTTOPOINT,MULTICAST> mtu 1500 fs0:\apps> ifconfig lo0 inet 127.0.0.1 up fs0:\apps> ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time<1 ms ... fs0:\> help ... Use 'help -b' to display commands one screen at a time.

GUID Based Partitioning Scheme

EFI defines GUID Partition Table (GPT), a new partitioning scheme that must be supported by EFI firmware. GPT uses globally unique identifiers to tag partitions. It is used by the 64-bit version of Windows, and offers several advantages over the legacy MBR-based partitioning scheme:

The primary header structure of a GUID partition table is stored on block 1 of the logical device, while the backup is stored on the last block. A GUID partition table header may never span more than one block on the device. Moreover, although GPT does not support nesting of partitions, it is legal to have a legacy MBR nested inside a GPT partition. Note however that the boot code on a legacy MBR is not executed by EFI firmware.

GUIDs

A GUID (also called UUID, for Universally Unique Identifier) is specified to be 128 bits long in Intel's Wired for Management (WfM) specification, and is unique across time (for example, until 3400 A.D. as per one GUID generation algorithm) and space (relative to other GUIDs). A key to generating a GUID without requiring a centralized authority is the use of a globally unique value that is available to each GUID generator -- a node identifier. For networked systems, this is a 48-bit IEEE 802 address (usually the host address, or some host address in case of multiple interfaces). For a host without an IEEE 802 address, this value is chosen in a probabilistically unique fashion. This is not sufficient for uniqueness, though. Other values involved in GUID generation include a timestamp, a clock sequence, and a version number.

A sample implementation of GPT disk utilities is available from Intel. The package includes diskpart (disk partitioning tool), efifmt (formatting tool), and efichk (disk checking tool).

fs0:\diskutils> diskpart ... DiskPart> select 0 Selected Disk = 0 DiskPart> inspect Selected Disk = 0 ### BlkSize BlkCount --- ------- ---------------- * 0 200 167CA00 0: EFISYS C13A7328-F81F-11D2 = EFISYS 34D22C00-1DD2-1000 @ 0 22 - C8021 1: MSDATA EBD0A0A2-B9E5-4432 = MSDATA 1845F401-1DD2-1000 @ 0 C8022 - 167C9DE

Universal Graphics Adapter (UGA)

As mentioned earlier, legacy BIOS depends on VGA, a legacy standard. Thus, given the growing needs of pre-boot applications, graphics support in a firmware environment is both very limited and hard to program with (consider factors like 640x480 maximum resolution, small framebuffer, use of palette modes, and so on). EFI defines the UGA specification as a replacement for VGA and VESA. Microsoft is behind UGA, with support from major graphics device manufacturers like ATI.

Any graphics device with UGA firmware can be considered a UGA device. It may also contain VGA firmware for compatibility. The firmware execution environment interprets UGA firmware, which again is implemented in a high level language. Similarly, programming a UGA device does not require you to deal with hardware registers, etc.

The UGA model would work as follows: the UGA firmware may reside on the graphics device, may be a part of the system firmware in case of an onboard graphics device, or may even come from a regular storage device. The firmware contains an EFI driver, which is still a "lowest common denominator" driver, and is not meant to replace a "high-performance" device specific driver that would normally be part of the operating system. That said, the UGA driver may be used in the post-boot environment in various scenarios:

Unlike VGA, the UGA firmware does not access the graphics hardware directly. It operates within an EFI virtual machine. Microsoft provides a generic Virtual Machine Library (VML) that a UGA firmware is linked with. This virtual machine -- a thin logical layer above EFI -- wraps (encapsulates) a specific UGA firmware implementation.

EFI Byte Code

Option ROMs require different executable images for different processors and platforms. EFI defines an EFI Byte Code (EBC) Virtual Machine to abstract such differences. The interpreter for this virtual machine is part of the firmware. C source can be compiled into EBC, then linked to yield drivers that "run" on the interpreter.

The EBC virtual machine uses two sets of 64-bit registers: 8 general purpose, and 2 dedicated registers. Further, it uses natural indexing for data offsets (relative to a base address) -- instead of a fixed number of bytes as an "offset unit", it uses a "natural unit", which is defined as the operation (as opposed to a constant) sizeof(void *). This allows EFI byte code to execute seamlessly on 64-bit and 32-bit systems.

There exists a C to EBC compiler. Note that you have several restrictions for the kind of C you can use: floating point and inline assembly are not supported, for example. You cannot use C++ either.

Experimenting with EFI

It is possible to develop and test your own EFI applications, even on an IA-32 computer. You need an EFI runtime environment to explore EFI and run EFI programs, while you need an EFI development environment to create your own EFI programs. You have choices for each environment:

Runtime Environment: You can explore EFI on an IA-64 system, which would have a real implementation of the EFI firmware. It may also be possible to acquire an "artificial" EFI environment, such as within an EFI emulator or an IA-64 simulator. An EFI BIOS32 boot floppy is also available from Intel, using which you can simply "boot into" a real EFI environment on an x86 machine with a legacy BIOS.

Development Environment: You can develop EFI programs on Windows and Linux (perhaps on some others even).

An example Windows development environment for EFI could consist of (but not limited to) the following:

EFI emulation under Windows should allow for convenient application development and debugging.

Following is source for an example EFI program, hanoi.efi, that solves Towers of Hanoi. You can build the program in an environment similar to the one described above. You can run it from the EFI shell. Refer to instructions in the README file within the source archive for details.

Download

Source for Towers of Hanoi in the EFI environment.

fs1:\> ls Directory of: fs1:\ 06/12/04 05:11a 15,872 hanoi.efi 1 File(s) 15,872 bytes 0 Dir(s) fs1:\> hanoi usage: hanoi N Exit status code: Invalid Parameter fs1:\> hanoi 3 move 1 --> 3 move 1 --> 2 move 3 --> 2 move 1 --> 3 move 2 --> 1 move 2 --> 3 move 1 --> 3

You can also develop EFI applications for IA-64 and x86 using the GNU toolchain on Linux. You need:

The ELF32 (or ELF64 on IA-64) binaries normally produced on Linux must be converted to EFI binaries, which are supposed to be in the PE32+ format. ELF sections are copied (via objcopy) into PE32+. The EFI specific crt0's _start function calls a relocator function, followed by a call to efi_main. Compiling an EFI application on Linux looks like the following:

# Compile position independent, force wide characters to shorts % gcc -I/usr/include/efi/ia32 -fpic -fshort-wchar -c hanoi.c # Use EFI specific linker script % ld -Bsymbolic --no-check-sections -nostdlib -L/usr/lib \ -T elf_ia32_efi.lds -shared /usr/lib/crt0-efi-ia32.o \ -o hanoi.so hanoi.o -lefi -lgnuefi \ /usr/lib/gcc-lib/i486-linux/3.3.3/libgcc.a # Copy specified sections to target % objcopy --target=efi-app-ia32 -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc \ hanoi.so hanoi.efi

More details of this process can be found in the file README.gnuefi within the GNU EFI package.

PE32+

The executable and object file formats under Microsoft Windows are called Portable Executable (PE) and Common Object File Format (COFF), respectively. A PE file is essentially a COFF file with an MS-DOS 2.0 compatible header (see Microsoft Portable Executable and Common Object File Format Specification for details). An optional header contains a magic number that further designates a PE files as "PE32" or "PE32+". PE32+ images allow for a 64-bit address space, although the image size is limited to 4 GB.

The Subsystem ID in an EFI PE image header is one of 0xa, 0xb, or 0xc, corresponding to an image that is an EFI application, an EFI boot service driver, or an EFI runtime driver, respectively. Note that an operating system loader is a special type of EFI application. The Machine ID in the same header corresponds to one for IA-32, IA-64, or EFI Byte Code (EBC).

Elilo, the EFI Linux boot loader, allows booting of Linux on EFI systems (both IA-64 and IA-32). The Linux kernel also supports EFI, that is, the Linux kernel provides an interface to the EFI runtime services (you need a recent 2.6 kernel for such support on IA-32).

Innovate[2]

Accepted connotations of the word "Innovate": Innovate [1] To introduce something new. Innovate [2] To introduce something as if new. - Some dictionary.

EFI has been described grandiloquently by Marketing, understandably. Phrases such as "Application Development Meets Firmware" and "Nothing Similar Existed Before" have been used to qualify and quantify EFI's importance. It is path-breaking. I agree that it finally gets rid of several painful issues with legacy BIOS in one blow.

It should still be a few years before we should see widespread adoption and deployment of EFI.

Now, I must point out that something "similar" has existed in the non-PC world for over 15 years: Open Firmware, which first shipped in 1989. In my opinion, EFI could be considered a new-generation implementation of the philosophy of Open Firmware. It has more features, and does several things better than Open Firmware, but it would be strange if it did not, with 15 years of hindsight!

Initiallly, I found it remarkable that I had not seen a single reference to Open Firmware in any EFI specification, presentation, whitepaper, or related document. I wondered whether I had not looked hard enough, or if it was appropriate not to mention prior ideas since EFI's pathbreaking-ness was valid in the context of PCs. Andrew Fish, the inventor of EFI, provided me with his historical perspective on EFI, for which I am grateful.

Andrew Fish on EFI

Andrew Fish invented EFI at his desk in the late 1990s, calling it Intel Boot Initiative (IBI) at that time. He offered his 26 page unsolicited white paper to his management. The paper was meant to be a response to major operating system and hardware companies rejecting legacy BIOS as the firmware for enterprise class Itanium® Processor Platforms.

Andrew says:

"At that time, two firmware solutions were put on the table as replacements for BIOS architectures for the Itanium: Alpha Firmware (ARC) and Open Firmware. It turned out that nobody really owned the inellectual property to ARC, and in any case, it did not have enough extensible properties to make it practical for a horizontal industry. At this point, Open Firmware became the frontrunner as Apple and Sun both used it. However, Open Firmware was not without its own technical challenges. The PC had started down a path of using the Advanced Configuration and Power Interface (ACPI) as its runtime namespace to describe the platform to the operating system. As I liked to say at the time, the only thing worse than one namespace is keeping two namespaces in sync. The other problem was the lack of third party support for Open Firmware. We invited the FirmWorks guys to come visit us at Dupont (WA), and we had a great talk. Given we had just gone through an exercise of inventing a firmware base from scratch, I think we were uniquely qualified to appreciate what Open Firmware had been able to achieve. Unfortunately, it became clear that the infrastructure to support a transition to Open Firmware did not exist. Given the namespace issue with Open Firmware and the lack of industry enabling infrastructure, we decided to go on and make EFI a reality."

"EFI is an interface specification and it really is more about how to write an operating system loader and an Option ROM than it is about how to make a BIOS that works. The Intel® Platform Innovation Framework for EFI (Framework for short) is Intel's next generation firmware architecture from the ground up. The core chunks of this code are available under an Open Source license at www.TianoCore.org. Tiano was the developer code name while Framework was the marketing name."

"To sum up, EFI is an industry interface specification that defines how OS loaders and PCI Option ROMs work. The Framework defines a new modular architecture that allows an entire firmware base to be constructed in a modular fashion. The Framework has a nice property in that it allows binary modules to work together in the boot process. This allows the code from each vendor to have an arbitrary license type. Intel® was interested in EFI from making a standard Itanium platform (as well as IA-32 platforms of the future) to drive adoption and enable a horizontal industry to make compatible platforms. The Framework is more about silicon enabling, so it drills down to a much lower level of how things work."

Links

TianoCore — Open Platform Firmware Development

Open Firmware

We discuss Open Firmware briefly in the following section. More details on interacting with Open Firmware may be found in Booting Mac OS X

Background

Open Firmware originated at Sun Microsystems in 1988, and was later adopted by Apple and some other vendors. Sun's implementation is trade-marked as OpenBoot, while Apple simply calls it Open Firmware.

Open Firmware is a non-proprietary, platform- (CPU and system) independent, programmable, and extensible environment for use in boot ROMs. Consider:

Interaction

You can enter Open Firmware by pressing the key combination cmd-opt-O-F just as you power on a Macintosh. The cmd key is the one with the Apple logo, and the opt (option) key is the same as the alt key. You should see a welcome message and some other verbiage, and should be dropped into a prompt like the following:

ok 0 >

You can continue booting the machine by typing mac-boot, or shut it down by typing shut-down.

For more details on Open Firmware, refer to Booting Mac OS X.

Others

Let us take a quick look at some other firmware related efforts.

Open Source

There is some "firmware activity" in the open source world, aimed both at developing open source alternatives to the BIOS, or to even replace the BIOS with Linux.

LinuxBIOS

LinuxBIOS is an open source project that uses the Linux kernel as the firmware.

LinuxBIOS uses a system call, LOBOS (Linux OS Boots OS), to boot a new Linux kernel from a running Linux kernel -- without going into real-mode, and without using the BIOS. Thus, LinuxBIOS can be used as a network bootstrapper, and even as a BIOS replacement.

FreeBIOS

FreeBIOS aims to provide an open source replacement for any computer's firmware, with initial support for Intel-based processors and chipsets.

OpenBIOS

OpenBIOS is work-in-progress towards an open source firmware implementation that aims to be 100% compliant with Open Firmware.

Phoenix Core System Software (CSS)

As mentioned earlier, Phoenix currently seems to be taking a more incremental approach to EFI adoption.

Phoenix has been extending the functionality of their BIOS products through features such as:

Phoenix plans to support both EFI and legacy boot methods in Longhorn timeframe, with a gradual transition to EFI, leading to an eventual removal of legacy. Phoenix says this is a low-risk, low-cost, and non-disruptive approach.

In the next sections, we look at examples of using graphics and mouse within Open Firmware.

Part II: GUI Widgets In Open Firmware

(Having Fun On A Mac Without An Operating System)

The implementation of Open Firmware used in Apple computers includes the device support extensions for several devices, and in particular, for the graphics and the mouse devices. Thus, it is possible for you to write Open Firmware programs that use the mouse and draw to the framebuffer.

We look at two examples: creating a "window" that you can move around using the mouse, and animating Towers of Hanoi.

Creating Windows

Open Firmware Windows

Open Firmware Windows

The sample Forth code in this section (see link below) creates a small, fixed size window that you can move around. Specifically, the code does the following:

Usage

The following example demonstrates how to "boot" into a window-drawing demo from the Open Firmware prompt, assuming the program file (called ofwindows, say) resides in user amit's home directory on the default hard disk:

0 > boot hd:\Users\amit\ofwindows ... ok 0 > ofwindows Press control-z to quit the Open Firmware Windows demo. ...

Download

Source for ofwindows.

Animating Towers of Hanoi

I have been interested in implementing (the solution of) Towers of Hanoi in several different ways, as evidenced by the "Hanoimania!" page [external page on www.kernelthread.com]. I recently added an implementation of animated Towers of Hanoi in Open Firmware, which serves as another (somewhat simpler than "ofwindows") example of using the framebuffer.

Animating Towers of Hanoi in Open Firmware

Towers of Hanoi

Usage

The following example demonstrates how to "boot" into Towers of Hanoi from within Open Firmware, assuming the program file (called ofhanoi, say) resides in user amit's home directory on the default hard disk:

0 > boot hd:\Users\amit\ofhanoi ... ok 0 > hanoi usage: n hanoi, where 1 <= n < = 8 ok 0 > 5 hanoi ... Press control-z to quit the animation. /* animation begins */ ok 0 > shut-down /* system powers off */

Download

Source for ofhanoi.

Project Ideas

While creating windows and moving disks might be fun, it might be important for those depending on Open Firmware (such as Apple) to think about its future, and what could be done to get to a new-generation firmware. This is particularly critical in the context of managed systems, whether they be servers or "desktops".

That said, it doesn't hurt to have some fun, even if it is arguably pointless.

A limited widget library could be developed to simplify creation of (small) GUI applications that run in the Open Firmware environment. Here are some fabricated reasons why somebody might want to do it:

Some conceivable projects could be:

Open Firmware Information Browser

A substantial amount of platform information is accessible from Open Firmware. It is also possible to set values of various parameters and device properties. Moreover, you can also access the filesystem from Open Firmware. A graphical interface could be created that displays such information, and allows GUI-based editing of parameters.

Simulation of Macintosh System 1

Open Firmware provides more resources in its execution environment than were available to Macintosh System 1. It should be possible to create a simulated System 1 within Open Firmware.

Simulation of Microsoft Windows 3.x

A subset of Microsoft Windows 3.x could be simulated, similar to System 1. Note that you can do color (8-bit) graphics in Open Firmware, as can be seen from the "Hanoi" example.