Search code examples
x86bios

BIOS rewrite on x86


My question is rather simple, yet I couldn't find out the answer.

How to write on the BIOS memory chip ?

Allright, to write data to IO devices on x86 (or actually whatever), the process always seems to be accessing the IO device through port-mapped or memory mapped IO. To me, the modern BIOS flash memory chip is IO device, and if it is writable, it must be so through that process. Coreboot is an opensource replacement for PC BIOSes, however, I believe it uses flashrom to actually rewrite the BIOS chip with its code, and flashrom is proprietary, so I wonder why is it so hard to write the BIOS that I can't find a reliable answer about how to actually do it.


Solution

  • In the x86 market there are two kind of devices: The ones with a standard interface and the ones without. Your case fall in the second category.

    To write to a flash ROM you only have to send a specific command to a specific address.
    Say you have this ROM chip of 1KB, it responds to read requests from 000h to 0fffh. You can however send write requests, but the chip won't even consider them. You cannot write to a F-ROM as easily as you read from it.
    You have to send a write command by writing, say, 55h to address AAh and then sending the page you want to reflash followed by writes with data. This is a proprietary interface (there are efforts to standardize it) and I have simplified it omitting not theoretically relevant parts.

    So you only have to send the write commands to the ROM chip.
    The matter is that the ROM chip is not next to the CPU, it is beyond what is called a bridge, usually more the one.
    In the x86 architecture one hell of a chip is the chipset, it is an hub routing request between devices (recently there have been a decentralization but devices like ROMs are still connected only to the chip once called South Bridge). You, the CPU programmer, communicate with the chipset by requests in the memory and IO address spaces.

    By default chipsets won't let writes reach the flash rom, you have to enable it by setting/clearing some bits in the chipset registers (which are memory mapped or in the PCI(e) register space). This is a proprietary interface.

    If you are lucky and your chipset is documented well enough (like the Intel's ones) to let you known how to allow writes reach the ROM, you have to figure how this requests are routed.
    Bridges are not always transparent, they perform address translations, for example you may write to 8123h and a bridge may alter the address to 0123h.
    This is what surely happen for the bridge in front of the flash ROM (this was a LPC bridge with a SIO chip, now it is SPI bridge) since the ROM is just an ordinary chip that respond in the range 0h - xxxxxxxxxh while from the CPU perspective it is mapped in the top end of the 4GB. So you have also to figure out what is the base address for the ROM, this is again chipset specific and also ROM specific since it depends on the ROM size (the chipset let you choose from a fixed number of different base address).

    Flashing a BIOS is not hard, I have done it for fun, it is just extremely not portable to the point that every computer model may need a different program to do it. It requires having your chipset datasheet too and this is not so common as you may expect.

    If you want to get a more practical idea you can download the Intel X99 PCH datasheet here (http://www.intel.com/content/www/us/en/chipsets/x99-chipset-pch-datasheet.html) and look a the SPI chapter.