2.13. The Bochs BIOS

2.13.1. The biossums utility

2.13.1.1. Intention

Writing a BIOS for a pc-compatible includes the task of embedding various checksums. At least there is the overall bios checksum stored in the very last byte of the program. Depending on the number and types of services the bios provides there are others, e.g.

  • a checksum for the PCI BIOS extensions

  • a checksum for the PCI interrupt routing table

  • a checksum for the plug and play BIOS extensions

All these checksums have one common point: using the usual assembler directives they are hard (if not impossible) to compute at compile time. You can either compute them by hand --- a tedious, error-prone task, where in addition you often have to make unreliable assumptions about the memory layout of the entire BIOS. Or you patch them directly into your compiled BIOS image. Apart from computing the checksums this is what biossums does for you.

2.13.1.2. Checksums

With the exception of the overall BIOS checksum, in a modern PC BIOS checksums are not used to ensure data integrity. Instead they are used in conjunction with certain signatures to securely identify the entry points or the addresses of important data of some BIOS extensions. Because these services are often invoked from x86 protected mode the original method via interrupts is not applicable. Scanning (even only parts) of the BIOS for (short) signatures and solely relying on this is insecure though, cause the found signature might not refer to the sought service but rather be some obscure machine code resembling the signature by accident.

Since signatures are usually part of a larger header or table the above mentioned problem is being circumvented by checksumming over this header and comparing the result to a checksum stored next to the signature. In practice the checksum is often part of the header, chosen in a way that the contents of the header add up to zero.

2.13.1.3. Usage

biossums is very simple and straightforward. The only (and mandatory) argument is the file name of the BIOS image. The file is being read, patched and written. So if you want to keep your original file for reference, use biossums on a copy of your BIOS image.

For now, biossums can only rely on signatures to find the locations of the accompanying checksums. Therefore biossums refuses to set any checksums if it finds more than one signature of the same type.

2.13.1.4. Example output

Running upon the current BIOS-bochs-legacy biossums displays:

PCI-Bios header at: 0x9610
Current checksum:     0x17
Calculated checksum:  0x17


$PIR header at:     0x99C0
Current checksum:     0x37
Calculated checksum:  0x37


$PnP header at:     0x9C80
Current checksum:     0xD1
Calculated checksum:  0x0F  Setting checksum.


Bios checksum at:   0xFFFF
Current checksum:     0x00
Calculated checksum:  0x28  Setting checksum.

If we patch in a second "_32_" signature at offset 0x9F00 and reset the $PIR checksum to 0x00 we get:

PCI-Bios header at: 0x9610
Current checksum:     0x17
Calculated checksum:  0x17  

PCI-Bios header at: 0x9F00
Current checksum:     0x00
Calculated checksum:  0x00  Multiple PCI headers! No checksum set.


$PIR header at:     0x99C0
Current checksum:     0x00
Calculated checksum:  0x37  Setting checksum.


$PnP header at:     0x9C80
Current checksum:     0x0F
Calculated checksum:  0x0F


Bios checksum at:   0xFFFF
Current checksum:     0x28
Calculated checksum:  0x05  Setting checksum.

2.13.1.5. Possible enhancements

Although biossums takes care of all checksums being used by the BIOS of the Bochs project (as of version 2.02) there are more to cover, e.g. the checksums for "Plug and Play" BIOS extension.

In addition it was planned to provide further information to biossums via map-/symbol-files to verify the locations of checksums apart from scanning for signatures. For now this seems not to be necessary; in practice no double signatures have been observed yet.