If you weren't scared away by my column last month, you must be ready to flash your BIOS.
In my last article, I introduced the Libreboot project: a free software distribution of coreboot, which is itself an open-source BIOS replacement. I also talked about some of the reasons you may want to run a free software BIOS and discussed some of the associated risks. If you made it through all of that and are ready to flash your BIOS, this article will walk you through the process.
Libreboot is available via binary distributions that make it easy to install (which is what I cover below) as well as source code distributions at libreboot.org/#releases. To get the latest binary release, go to libreboot.org/docs/release.html, and be sure to download both the .xz as well as the corresponding .xv.sig file, such as:
http://libreboot.org/release/20150208/libreboot_bin.tar.xz
http://libreboot.org/release/20150208/libreboot_bin.tar.xz.sig
Once you download the files, use gpg --verify to validate that the signature matches:
$ gpg --verify libreboot_bin.tar.xz.sig libreboot_bin.tar.xz gpg: Signature made Tue 14 Oct 2014 09:07:32 PM PDT using ↪RSA key ID 656F212E gpg: Good signature from "Libreboot Releases (signing key) ↪<releases@libreboot.org>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs ↪to the owner. Primary key fingerprint: C923 4BA3 200C F688 9CC0 764D ↪6E97 D575 656F 212E
Note that since I haven't added the Libreboot GPG key to my keyring and trusted it, all it can do here is validate that the signature matches whatever key generated the .sig, not that it's the official Libreboot key. To do that, I would have to go to more effort to download and validate the Libreboot GPG key.
Now that it has been validated, I can use tar to extract it and cd to the libreboot_bin directory:
$ tar xvf libreboot_bin.tar.xz $ cd libreboot_bin
There are a number of different libraries and software that this binary release needs on your system to work. Inside the libreboot_bin directory, you will see a deps-trisquel and deps-parabola script to be run as root. If you use a Debian-based distribution, run deps-trisquel, and if you use an Arch Linux-based distribution, run deps-parabola. For other distributions, unfortunately, you will need to use those scripts as a guide for what sorts of libraries and packages you will need to download. In my case, I was running from a Debian-based distribution (inside Tails in fact), so I ran:
$ sudo ./deps-trisquel
Once you have the package dependencies, you need to build flashrom and bucts on your system. Libreboot has provided two scripts to automate this process as well, called builddeps-bucts and builddeps-flashrom, so the next step is to run those:
$ sudo ./builddeps-flashrom $ sudo ./builddeps-bucts
This should create a ./flashrom/flashrom and a ./bucts/bucts binary that subsequent scripts will use.
Once you have all of the software downloaded or compiled, the next step is to identify which ROM you want to use. To ease the process and help ensure that you don't brick your laptop, you can choose from a number of pre-copiled BIOS ROMs that Libreboot provides. Under the ./bin/ directory are a few different directories named after the different laptops Libreboot currently supports:
$ ls bin/ macbook21 t60 x60 x60t
In my case, I'm flashing an x60, so I want to choose a ROM from that directory:
$ ls bin/x60 libreboot_frazerty_txtmode.rom libreboot_frazerty_vesafb.rom libreboot_itqwerty_txtmode.rom libreboot_itqwerty_vesafb.rom libreboot_svenska_txtmode.rom libreboot_svenska_vesafb.rom libreboot_ukdvorak_txtmode.rom libreboot_ukdvorak_vesafb.rom libreboot_ukqwerty_txtmode.rom libreboot_ukqwerty_vesafb.rom libreboot_usdvorak_txtmode.rom libreboot_usdvorak_vesafb.rom libreboot_usqwerty_txtmode.rom libreboot_usqwerty_vesafb.rom
As you can see, there are a number of different ROMs for different languages and keyboard layouts, and within each category, there also are txtmode and vesafb options depending on whether you want your BIOS to display a graphical GRUB screen in VESA mode or just rely on text mode. In my case, I selected bin/x60/libreboot_usqwerty_vesafb.rom.
You still are not yet at the point where you risk bricking anything, but you are close, so it's time to back up the old BIOS, so you have a chance of recovering this laptop in case something goes wrong. When I first tried to flash an x60 with coreboot, the main challenge was due to the fact that the laptop series had two different potential BIOS chipsets, and each required a special patch to flashrom. This meant physically inspecting the motherboard with a magnifying glass and reading the tiny print on the BIOS chip. The Libreboot project has greatly simplified this by creating both flashing tools ahead of time and realizing that one will work, and the other will fail safely.
So to back up your BIOS, cd to the flashrom directory and run two different commands:
$ cd flashrom $ sudo ./flashrom_lenovobios_sst -p internal -r factory.bin flashrom v0.9.7-unknown on Linux 3.16.0-4-586 (i686) flashrom is free software, get the source code at ↪http://www.flashrom.org Calibrating delay loop... OK. Found chipset "Intel ICH7M". Enabling flash write... WARNING: ↪SPI Configuration Lockdown activated. OK. No EEPROM/flash device found. Note: flashrom can never write if the flash chip isn't ↪found automatically. $ sudo ./flashrom_lenovobios_macronix -p internal -r factory.bin flashrom v0.9.7-unknown on Linux 3.16.0-4-586 (i686) flashrom is free software, get the source code at ↪http://www.flashrom.org Calibrating delay loop... OK. Found chipset "Intel ICH7M". Enabling flash write... ↪WARNING: SPI Configuration Lockdown activated. OK. Found Macronix flash chip "MX25L1605D/MX25L1608D/MX25L1673E" ↪(2048 kB, SPI) mapped at physical address 0xffe00000. Reading flash... done.
In this case, it turns out I had a Macronix BIOS chip, so the first script failed and the second script worked. The important thing is that at the end, you should have a factory.bin file in this directory. Back this file up! Because often the BIOS image has customizations that apply to that particular laptop, and because I have a number of different BIOS images I need to back up, I like to label my BIOSes based on the serial number, such as x60-BIOS-LV-A4332.bin (not a real serial number).
Warning: if you run any of the commands after this point in the column incorrectly, you risk bricking your laptop! If you aren't willing to take that risk, do not proceed! If you decide to proceed, read each example carefully and check all of your commands for correctness before you press Enter.
The BIOS flashing process occurs in two stages. The first stage is easily reversible (if you use a provided Libreboot ROM at least) and flips a particular setting in your BIOS and changes part but not all of the BIOS firmware. In the root directory where you unpacked the Libreboot tarball, you will see two scripts: lenovobios_firstflash and lenovobios_secondflash. Run the lenovobios_firstflash command as root and pass it the path to the Libreboot ROM you identified earlier.
Now, this command is going to output some incredibly frightening error messages. This is because it's using a general-purpose flashrom tool that in this first phase cannot completely reflash your BIOS. Instead, it is going to set BUC.TS=1 (a flag that will let you completely rewrite the BIOS after a complete shutdown) as well as set up a basic BIOS bootloader, but otherwise will fail, as it doesn't yet have the ability to rewrite all of the flash:
$ sudo ./lenovobios_firstflash bin/x60/libreboot_usqwerty_vesafb.rom Don't panic. See docs/index.html for an explanation of what BUC.TS is. MAKE SURE THAT YOU SEE 'Updated BUC.TS=1' IF NOT CHECK #libreboot ↪ON FREENODE bucts utility version '4' Using LPC bridge 8086:27b9 at 0000:1f.00 Current BUC.TS=0 - 128kb address range 0xFFFE0000-0xFFFFFFFF is ↪untranslated Updated BUC.TS=1 - 64kb address ranges at 0xFFFE0000 and 0xFFFF0000 ↪are swapped READ THE BIG WARNING ABOVE! MAKE SURE THAT YOU SEE 'DO NOT SHUT DOWN OR REBOOT' (YOU WANT TO ↪SEE THAT. MEANS IT WORKED). IF NOT CHECK #libreboot ↪ON FREENODE If (when) you see 'DO NOT SHUTDOWN OR REBOOT' do not panic. ↪That is normal, expected and very good. And you will ↪ignore what it says. flashrom v0.9.7-unknown on Linux 3.16.0-4-586 (i686) flashrom is free software, get the source code at ↪http://www.flashrom.org Calibrating delay loop... OK. Found chipset "Intel ICH7M". Enabling flash write... WARNING: ↪SPI Configuration Lockdown activated. OK. No EEPROM/flash device found. Note: flashrom can never write if the flash chip isn't ↪found automatically. flashrom v0.9.7-unknown on Linux 3.16.0-4-586 (i686) flashrom is free software, get the source code at ↪http://www.flashrom.org Calibrating delay loop... OK. Found chipset "Intel ICH7M". Enabling flash write... WARNING: ↪SPI Configuration Lockdown activated. OK. Found Macronix flash chip "MX25L1605D/MX25L1608D/MX25L1673E" ↪(2048 kB, SPI) mapped at physical address 0xffe00000. Reading old flash chip contents... done. Erasing and writing flash chip... spi_block_erase_20 failed ↪during command execution at address 0x0 Reading current flash chip contents... done. Looking for another ↪erase function. Transaction error! spi_block_erase_d8 failed during command execution at address ↪0x1f0000 Reading current flash chip contents... done. Looking for another ↪erase function. spi_chip_erase_60 failed during command execution Reading current flash chip contents... done. Looking for another ↪erase function. spi_chip_erase_c7 failed during command execution Looking for another erase function. No usable erase functions left. FAILED! Uh oh. Erase/write failed. Checking if anything has changed. Reading current flash chip contents... done. Apparently at least some data has changed. Your flash chip is in an unknown state. Get help on IRC at chat.freenode.net (channel #flashrom) or mail flashrom@flashrom.org with the subject "FAILED: ↪<your board name>"! ------------------------------------------------------------ DO NOT REBOOT OR POWEROFF! READ THE BIG WARNING ABOVE! Now you will SHUT DOWN (ignore the flashrom warning) but ↪first keep in mind before you then boot: Use 'Search for GRUB configuration on local storage' if ↪the normal menus don't work, or check docs/index.html ↪or #libreboot on freenode. SHUT DOWN NOW!!!! WAIT A FEW SECS!!!! THEN BOOT. DON'T PANIC.
With all of this output, there are a few specific things that you want to see. The first is this:
Current BUC.TS=0 - 128kb address range 0xFFFE0000-0xFFFFFFFF ↪is untranslated Updated BUC.TS=1 - 64kb address ranges at 0xFFFE0000 and ↪0xFFFF0000 are swapped
If you don't see Updated BUC.TS=1, don't reboot, but instead, attempt to run the command again. The second kind of output you want to look for is something like this:
Reading old flash chip contents... done. Erasing and writing flash chip... spi_block_erase_20 failed ↪during command execution at address 0x0 Reading current flash chip contents... done. Looking for ↪another erase function. Transaction error! spi_block_erase_d8 failed during command execution at ↪address 0x1f0000 Reading current flash chip contents... done. Looking for ↪another erase function. spi_chip_erase_60 failed during command execution Reading current flash chip contents... done. Looking for ↪another erase function. spi_chip_erase_c7 failed during command execution Looking for another erase function. No usable erase functions left. FAILED! Uh oh. Erase/write failed. Checking if anything has changed. Reading current flash chip contents... done. Apparently at least some data has changed. Your flash chip is in an unknown state.
Yes, that seems like a scary error, but it's apparently the kind of scary error that you want to see. What's happening is that flashrom was able to write part of the flash chip but not all of it, so it's erroring. If you see some sort of radically different scary error from the above, don't reboot or shut down your machine. Instead, use the flashrom tool to re-install your original BIOS.
Otherwise, if you see similar output to mine, completely shut down your machine, wait a few seconds, and then boot up again. You should see the Libreboot boot screen with a GRUB menu presenting a few options. You can attempt to use the normal menu options to boot from the local hard drive, or if that fails, select Search for GRUB configuration on local storage.
If after the first flash you don't see anything when you power on, the simplest explanation may be that your laptop backlight reset, so use the Fn-Home key combination to increase the brightness. Otherwise, if you see no boot screen, but the laptop itself doesn't make any sounds, you still can revert to the old BIOS. Just remove the keyboard and disconnect the CMOS battery for five to ten seconds, then plug it back in. You should be able to boot back in to your original BIOS. Otherwise, if you hear three beeps when you power it on, the laptop unfortunately has been bricked, and you will have to resort to a hardware flash to restore it.
Once you boot back in to your system on the new Libreboot BIOS, it's time to perform the second flash. This flash will permanently replace the original BIOS with Libreboot. Go back to your Libreboot binary directory, and run the lenovobios_secondflash utility as root with the same ROM you chose before as an argument:
$ sudo ./lenovobios_secondflash bin/x60/ ↪libreboot_usqwerty_vesafb.rom Don't panic. See docs/index.html for an explanation ↪of what BUC.TS is. MAKE SURE THAT YOU SEE 'VERIFIED' AT THE END (YOU WANT TO SEE ↪THAT. MEANS IT WORKED). flashrom v0.9.7-unknown on Linux 3.16.0-4-586 (i686) flashrom is free software, get the source code at ↪http://www.flashrom.org Calibrating delay loop... OK. coreboot table found at 0x7f6bd000. Found chipset "Intel ICH7M". Enabling flash write... OK. Found Macronix flash chip "MX25L1605D/MX25L1608D/MX25L1673E" ↪(2048 kB, SPI) mapped at physical address 0xffe00000. Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED. READ THE BIG WARNING ABOVE! MAKE SURE THAT YOU SEE 'Updated BUC.TS=0' IF NOT CHECK ↪#libreboot ON FREENODE bucts utility version '4' Using LPC bridge 8086:27b9 at 0000:1f.00 Current BUC.TS=1 - 64kb address ranges at 0xFFFE0000 and ↪0xFFFF0000 are swapped Updated BUC.TS=0 - 128kb address range 0xFFFE0000-0xFFFFFFFF ↪is untranslated Not writing BUC register since TS is already correct. READ THE BIG WARNING ABOVE! If the above 2 conditions are met, then shut down now. If not, ↪then run: sudo ./bucts/bucts 1 DON'T PANIC.
I don't know, there's something about seeing the words “don't panic” in all caps that makes you want to panic. Okay, as you can see in this output, there shouldn't be any scary errors. Instead, I was able to read the old flash contents and erase and write the new one:
Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED.
Also this script will reset the BUC.TS setting to 0:
Updated BUC.TS=0 - 128kb address range 0xFFFE0000-0xFFFFFFFF ↪is untranslated
If you see output like this, congratulations, you have completely replaced your BIOS with Libreboot! Now just shut down your machine, wait a few seconds, and the next time you boot, there it will be, completely with free software. Of course, you may decide you want to change the boot menu you see with Libreboot. If so, be sure to check out my final article in this series next month where I discuss how to tweak the initial GRUB boot menu.