Hack and /

Libreboot on an x60, Part II: the Installation

Kyle Rankin

Issue #252, April 2015

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.

Get Libreboot

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

Pull Down Software Dependencies

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.

Choose Your ROM

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.

Back up the Old BIOS

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).

Perform the First Libreboot Flash

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 First Flash Fails

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.

Perform the Second Libreboot Flash

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.

Kyle Rankin is a Sr. Systems Administrator in the San Francisco Bay Area and the author of a number of books, including The Official Ubuntu Server Book, Knoppix Hacks and Ubuntu Hacks. He is currently the president of the North Bay Linux Users' Group.