Installing Coreboot
Motivation
When not at work, I primarily use a Lenovo Thinkpad x220 with Debian GNU/Linux. Recently, the factory installed wireless card failed. I purchased a replacement wireless card from Think Penguin and quickly found that the factory BIOS prevents the use of non-whitelisted hardware. I took this as a challenge to see if I could work around the freedom limiting factory BIOS.
Summary
These project notes breakdown into two discrete tasks:
- Construct the coreboot image
- Burn the coreboot image
Constructing the new BIOS image is fairly straight forward and pretty well documented by the coreboot community. I share my process to potentially save others (future versions of myself included) a bit of searching/patchwork from mailing lists, forum posts, etc.
The initial "burn" of the coreboot image required the use an "external" or direct-hardware flashing mechanism to overwrite the factory BIOS. Essentially, I need another device capable of physically connecting to, and writing bytes to the SOIC - Small Outline Integrated Circuit - chip which houses the BIOS on the mainboard of the x220. To achieve this I used a Raspberry Pi 2 Model B and its GPIO board to act as the "burning" device.
Setting up the Raspberry Pi 2 Model B
The Raspberry Pi is the external device I used to read/write firmware directly to/from the x220's mainboard. I used the flashrom
utility to communicate with the x220's BIOS SOIC chip. This section details how to install flashrom
, enable the SPI - Serial Peripheral Interface - kernel modules to enable communication across the Raspberry Pi's GPIO, and how to wire up the SOIC hardware clip to the x220's mainboard.
Install flashrom
sudo apt-get install build-essential pciutils usbutils libpci-dev libusb-dev libftdi1 libftdi-dev zlib1g-dev subversion mkdir -p ~/Documents/BIOS/tools cd ~/Documents/BIOS/tools git clone --branch stable https://github.com/flashrom/flashrom.git cd flashrom make
Load the SPI Kernel modules
sudo echo -e "spi_bcm22835 \nspidev" >> /etc/modules sudo modprobe spi_bcm22835 sudo modprobe spidev
Connect GPIO to BIOS SOIC (Pomonoa 5250 Clip)
!!!!!!!!!!!! WARNING: Remove the X220 Battery and Power supply; failure to do so will cause damage to the BIOS SOIC
I use the Pomonoa 5250 clip to connect the Raspberry Pi's GPIO interface to the x220's BIOS SOIC chip. Here's the basic wiring information:
BIOS SOIC / Pomonoa Pin layout
* Closest to Screen * | 5 | 4 | | 6 | 3 | | 7 | 2 | | 8 | 1 | * Colsest to Palmrest Edge *
BIOS SOIC => GPIO Wiring information
BIOS SOIC / Pomonoa Pin # | GPIO Pin # | Role |
---|---|---|
1 | 24 | CEO |
2 | 21 | MISO |
3 | (not used) | |
4 | 25 | GND |
5 | 19 | MOSI |
6 | 23 | SCLK |
7 | (not used) | |
8 | 1 | 3.3V |
Read Factory Firmware
On the Raspberry Pi, prepare a directory to which we can read the Factory BIOS in case something goes wrong with the coreboot installation.
mkdir -p ~/Documents/BIOS/firmwares/factory cd ~/Documents/BIOS/firmwares/factory
Make two backups of the Factory BIOS, we're going to validate them against one another to make pretty sure we have the correct factory BIOS bits.
Make note of the capacity of the BIOS chip, we'll need this later when configuring coreboot. In my case flashrom reported that the Winbond flash chip W25q64.V chip has 8192KB of storage
sudo ~/Documents/BIOS/tools/flashrom/flashrom -p linux_spi:dev=/dev/spidev0.0 -r ~/Documents/BIOS/firmwares/factory/lenovo_x220_factory_bios.test.bin sudo ~/Documents/BIOS/tools/flashrom/flashrom -p linux_spi:dev=/dev/spidev0.0 -r ~/Documents/BIOS/firmwares/factory/lenovo_x220_factory_bios.bin md5sum ~/Documents/BIOS/firmwares/factory/lenovo_x220_factory_bios.test.bin md5sum ~/Documents/BIOS/firmwares/factory/lenovo_x220_factory_bios.bin
If the md5sums of both the images are the same, rock on. If not, STOP - a corrupt factory BIOS image will likely brick your laptop if you base your coreboot image on it, and you won't have a way to restore the factory BIOS. Try re-reading the factory BIOS and make sure you end up with two consecutive reads that have the same md5 checksum.
Copy the lenovo_x220_factory_bios.bin
to the x220 via sftp, USB media, etc. Verify the md5sum after copying.
Optional - Neutralize the Intel Management Engine (ME)
What is the Intel Management Engine (ME)?
The gory details are best explained by the experts here, but suffice to say that it can act as a way for third parties to remotely execute code on your machine - for good or ill. The ME is installed, in one form or another, on all newer Intel chipsets and can be mostly neutralized by the me_cleaner tool.
Clean the ME from the factory bios
NOTE: me_cleaner mutates the BIOS file you supply as an argument. We'll want to do this on a copy of our factory BIOS binary so we still have an original version of the factory BIOS somewhere if we need to restore it for some reason in the future.
On the x220, clone the me_cleaner tool and run it against the factory BIOS binary
mkdir -p ~/Documents/BIOS/workspace cp ~/Documents/BIOS/firmwares/factory/lenovo_x220_factory_bios.bin ~/Documents/BIOS/workspace/ cd ~/Documents/BIOS/tools/ git clone https://github.com/corna/me_cleaner.git python me_cleaner.py ~/Documents/BIOS/workspace/lenovo_x220_factory_bios.bin
Prepare Coreboot
Install coreboot prerequisites on the x220
sudo apt update sudo apt install gcc ncurses-dev
Get the coreboot source
mkdir -p ~/Documents/BIOS/tools cd ~/Documents/BIOS/tools git clone http://review.coreboot.org/p/coreboot cd coreboot git submodule update --init --checkout
Build the ifdtool
.
We'll use this to extract the proprietary blobs from the factory BIOS
cd ~/Document/BIOS/tools/coreboot/util/ifdtool make
Extract the blobs from the factory BIOS binary
~/Documents/BIOS/tools/coreboot/util/ifdtool/ifdtool -x ~/Documents/BIOS/workspace/lenovo_x220_factory_bios.bin
This should produce the following files:
- ~/Documents/BIOS/workspace/flashregion_0_flashdescriptor.bin
- ~/Documents/BIOS/workspace/flashregion_1_bios.bin
- ~/Documents/BIOS/workspace/flashregion_2_intel_me.bin
- ~/Documents/BIOS/workspace/flashregion_3_gbe.bin
NOTE: If you did not perform the Intel Management Engine neutralization step you'll need to copy your factory BIOS to the ~/Documents/BIOS/workspace directory before attempting to run the ifdtool command above.
mkdir -p ~/Documents/BIOS/workspace cp ~/Documents/BIOS/firmwares/factory/lenovo_x220_factory_bios.rom ~/Documents/BIOS/workspace/lenovo_x220_factory_bios.bin
Make the coreboot 3rd party binary blobs directory for the Lenovo x220
mkdir -p ~/Documents/BIOS/tools/coreboot/3rdparty/blobs/mainboard/lenovo/x220
Copy the necessary blobs to the coreboot 3rd party directory for the Lenovo x220
cp ~/Documents/BIOS/workspace/flashregion_0_flashdescriptor.bin ~/Documents/BIOS/tools/coreboot/3rdparty/blobs/mainboard/lenovo/x220/descriptor.bin cp ~/Documents/BIOS/workspace/flashregion_2_intel_me.bin ~/Documents/BIOS/tools/coreboot/3rdparty/blobs/mainboard/lenovo/x220/me.bin cp ~/Documents/BIOS/workspace/flashregion_3_gbe.bin ~/Documents/BIOS/tools/coreboot/3rdparty/blobs/mainboard/lenovo/x220/gbe.bin
Configure Coreboot
Use the coreboot menu tool to configure the BIOS image
cd ~/Documents/BIOS/tools/coreboot make menuconfig
Note: this menu changes a bit from coreboot version to coreboot version, some of the options might change. The mainboard and chipset options are the really important ones and probably won't change too often.
- Mainboard Menu
- Mainboard Vendor = Lenovo
- Mainboard Model = Thinkpad X220
- ROM Chip Size = 8192 KB (8 MB)
- use the output of flashrom command
- Chipset Menu
- Untick "Build With a fake IFD"
- Tick "Add Intel descriptor.bin file" (descriptor.bin)
- Tick "Add Intel Management Engine firmware" (me.bin)
- Tick "Add gigabit ethernet firmware" (gbe.bin)
- Devices Menu
- Tick Use Native Graphics initialization
- Tick Run Option ROMS on PCI devices
- Console Menu
- Tick Use onboard VGA as primary video devices
- Payload Menu
- Add a payload: SeaBIOS
- SeaBIOS Version: Use the latest tagged stable version
- Exit menuconfig tool
- Choose "Yes" when propted to save the config file
Install the coreboot build chain (this takes a little while)
make crossgcc-i386
If something goes wrong, search for the relevant error logs
find . -name '*.log' | xargs grep Error
Build Coreboot image
make
This builds the new firmware to ~/Documents/BIOS/tools/coreboot/build/coreboot.rom
. Copy this file to the collection of firmwares in case it is needed for re-flashing at a later date:
mkdir -p ~/Documents/BIOS/firmwares/coreboot/seabios/ cp ~/Documents/BIOS/tools/coreboot/build/coreboot.rom ~/Documents/BIOS/firmwares/coreboot/seabios/lenovo_x220_coreboot_seabios_<date-stamp>.bin
Compute the md5sum of the lenovo_x220_coreboot_seabios_<date-stamp>.bin
then copy it to the Raspberry Pi's filesystem - place it in ~/Documents/BIOS/firmwares/coreboot/seabios
.
Burn the Coreboot ROM
Back on the Raspberry Pi, connect the SOIC clip back onto the X220's chip and use flashrom to write the coreboot BIOS image to the X220's SOIC chip.
NOTE: Remember to remove the battery and disconnect the power supply from the x220 BEFORE attaching the SOIC clip to the x220.
sudo ~/Documents/BIOS/tools/flashrom/flashrom -p linux_spi:dev=/dev/spidev0.0 -w ~/Documents/BIOS/firmwares/coreboot/seabios/lenovo_x220_coreboot_seabios_<date-time>.bin
Verifying that the ME is neutralized
Coreboot supplies a tool to show the status of various partitions of the ME.
sudo ~/Documents/BIOS/tools/coreboot/util/intelmetool/intelmetool -s
The relevant bits are:
ME: FW Partition Table : OK ME: Firmware Init Complete : NO ME: Current Working State : Recovery ME: Progress Phase : BUP Phase
Could not map MEI PCI device memory
When I first ran this tool I received the following error output:
Error mapping physical memory 0x..... [0x4000] ERRNO=1 Operation not permitted Could not map MEI PCI device memory
To solve this:
Edit =/etc/default/grub
Add the iomem=relaxed
option
... GRUB_CMDLINE_LINUX_DEFAULT="iomem=relaxed ..."
Update the boot images
sudo update-grub
Resources
- http://www.coreboot.org/pipermail/coreboot/2015-February/079208.html
- http://www.coreboot.org/Build_HOWTO#Building_a_payload
- https://github.com/bibanon/Coreboot-ThinkPads/wiki/Hardware-Flashing-with-Raspberry-Pi
- https://github.com/bibanon/Coreboot-ThinkPads/wiki/Compiling-GRUB2-for-Coreboot
- http://www.coreboot.org/Talk:GRUB2
- https://github.com/corna/me_cleaner