File systems have always fascinated me. My first published software was in an Apple II hacker magazine (Hardcore Computing) , where I rewrote the the way the 'catalog' instruction worked. When FAT12 (the IBM floppy format) came out, I was fascinated by the hard-sectored low-level hardware which didn't require "sync" bytes. During my career at Award I hand-disassembled a new boot sector virus which halted our development for a week because we thought it was a BIOS bug. FAT16? FAT32? NTFS? No problem.
File systems for flash devices, such as those used by the BIOS, are nothing new. Consider the Mars Rover, where NASA scientists were able to download firwmare updates from millions of miles away. But what happens if there is a power failure during the update? You have a very expensive brick. Your PC can be the same way. Ever see those warnings "Don't turn off your PC" when updating the flash? That' s because, if you did, you might lose your BIOS. No BIOS = Useless PC.
Isn't there a way around this? Sure. That's fault tolerance. Most file systems have some way to recover from power failures to a greater or lesser extent. In some cases, it comes at the expense of performance, since some speed enhancements, like write caching, mean that the physical media (flash, hard disk, etc.) aren't updated immediately. Just go check out the properties of your USB hard drive in the Windows Device Manager, where you can select for "Performance" or "Data Protection"
Flash devices present some interesting problems for file systems. First, the performance is relatively slow (which is why folks want to cache!). Second, writes to a flash part can only change a bit value once before have to erase and re-write some larger portion of the flash device (e.g. 4KB or 64KB). Third, flash devices wear out over time if you do too many writes or, on some devices, too many reads.
Microsoft documents their own variant of the FAT16 file system (called TFAT or Transaction-Safe File Allocation Table) here. The UEFI Platform Initialization Firmware File System specification (available here) also documents a standard file system as well as a means of extending support to other file systems.
But back up a second: Why does UEFI PI need to define a file system at all? Well, interoperability. In order for 3rd parties to be able to smoothly integrate their drivers and applications into a flash device containing Phoenix BIOS, we have to have a file format which everybody recognizes. Otherwise, they would have to recompile their drivers using Phoenix tools.
As I mentioned before, one of the key aspects of file systems is fault-tolerance. If I yank out the power cord while my BIOS is being updated, I still want to the BIOS to survive. For the UEFI PI firmware file system, fault-tolerance is achieved using well defined state transitions. The file system is stable before the state transition and the file system is stable after the state transition. In between the before-state and the after-state are atomic actions, which the file system software assumes will always complete once initiated.
For the UEFI PI firmware file system, there is only one atomic action: write-one-bit. Each state transition is marked by a single bit being changed. In UEFI PI, there are six file states, each represented by a single bit. If more than one bit is set, then only the highest state is considered:
- File Header Start Write - File system has started writing the file's header. The file header is invalid.
- File Header End Write - File system has completed writing the file's header and has started writing the file's data. The file header except for the file data checksum is valid but the file's data is not valid.
- File Data End Write - File system has completed writing the file's data. The file's header and data are valid.
- File Being Updated - File system is created an updated version of this file. The file's header and data are valid.
- File Deleted - The file has been deleted.
- File Invalid - The file's header is invalid.
File Being Updated is particularly interesting. It means that the file system started to create an updated version of this file somewhere in the same file volume. When that updated version has been written completely (File Data Written), then this version will be moved to File Deleted. But what happens if the power fails after the updated version has been written but before this one is deleted? Well, if two versions of the same file are found and one is File Being Updated and the other is File Data Written then the latter is ignored. Usually this state is detected when the firmware volume is mounted and the latter is moved to Deleted.
Here's the typical firmware volume layout:
Next time we'll talk a little bit more about the actual UEFI PI file and volume formats.
Tim