In both ARM and x86, a BIOS is required to start the server. BIOS software got many legacy and backward compatible software to ensure a reliable behavior accross many boards. I was in charge of the BIOS development for our new generation of x86 servers.
This article presents technical choices we used during our development.
What is a BIOS and what were our requirements?
BIOS main goals are to boot the OS and provide some hardware abstractions to the OS so that it knows how to operate.
The BIOS is the first software that runs on the CPU when the computer starts.
You might have seen its interface: the “setup menu” you can get by pressing a key early when powering on your computer.
It is stored on a flash chip on the motherboard itself.
We wanted to make a BIOS that could:
- Boot the OS:
- Provide the abstraction expected by modern OS
- Provide a remote console via a serial port
- Interface with our specific BMC (Board Management Controller)
- Secure its update process.
So with this in mind, why go open source?
For the first x86 generation we tested vendors and their provided BIOS but we were not really happy with the process.
Vendors give you a mix of sources and binaries but not much documentation.
You pay a by device fee, with extra for support which is not that efficient.
When you design your board, you get the reference design from Intel, they provide a BIOS implementation for this board but you are not allowed to use it in production (and you don’t have the source either).
In summary no solutions would easily cover all of our needs.
So we decided to develop our own BIOS, but not from scratch: by using Open Source components.
How to build an Open Source BIOS
The main component is the community driven project coreboot.
It is responsible for the very early initialization (ie the first instruction that run on the CPU will be from coreboot), launch multiprocessor if your system has multiple cores (which is quite common nowadays) and starting the next step which is called a payload.
The second component is called Firmware Support Package (FSP).
FSP is a closed-source software provided by Intel to perform several tasks.
Mainly the configuration and training of the DDR memory through Memory Reference Code (MRC) and Silicon Init that will initialize the internal components before the PCI enumeration takes place.
The FSP provides APIs and is called by coreboot when needed.
Finally the last component required is TianoCore.
It is an open source project initiated by Intel to replace the BIOS altogether as it is the reference implementation of the uEFI specification.
So TianoCore is used as a payload for coreboot and will actually start your OS.
Pros and Cons of the approach
- 95% of existing code
- It fits our needs!
- The performances are inline with reference BIOS
- Extra features with our Baseboard Management Controller (BMC)
- UART Verbosity rate config
- Low level Flash Protection
- Discussing with Intel support had an influence on release content:
The MRC code provide many memory training information but Intel disabled the traces at some point during development.
We kept asking for re-enabling the traces so they told us we would continue to get a version with it under NDA.
Finally Intel uploaded a version with the traces enabled to github.
- A little longer to develop
- No nice graphical menu
- No legacy BIOS. We didn’t use the open source project seabios as Compatibility Support Module (CSM)
- Intel’s bugs hits us instead of our BIOS vendor
- Early contributions are hard:
- Before the release of the C3000 we were under Intel NDA
- When they finally upstreamed the support to coreboot, it was with a different implementation than the one we had been working on for a year.
Developing a BIOS was an useful investment because we gained full stack control.
We pushed our BIOS to tens of thousands of production servers!
Putting all these components together will give you a working BIOS. But you might miss a few features or initializations.
Additional technical details behind this will be the subject of a later post.