Black Bear Information Security
Information Technology Security
penetrationtesting.jpg

Blog

Coreboot on the ThinkPad X220

Coreboot_full_highres.png

 

Coreboot is an open source project to replace proprietary BIOS/UEFI with a lightweight and secure boot firmware. It also allows you to remove most of Intel's Managemnet Engine without any ill effects. I was in the market for a new laptop at the time. My daily driver had been a Macbook Pro (Early 2015) and it was growing long in the tooth. I decided to add Coreboot compatibility to my list of requirements (in addition to upgradable components and an external battery).

I found my perfect fit in a Lenovo ThinkPad X220. It was older but for under $400 I was able to get an i7 processor with 16GB of RAM and a 256GB SSD. You can take is apart with a Phillips head, pretty much all the components are upgradeable, there is a surplus of spare parts available and it is Coreboot compatible. Best $400 bucks I ever spent. Once it had arrived, I blocked off a weeknight and got to work.

There are two great guides on flashing the X220 by Karl Cordes and Tyler Cipriani, I will link them below as they served as my guides in this process. That being said, they are a bit confusing at points and there are new issues they aren't addressed in the guides because, as of this writing, they are about a year and a half old. So this will serve as my updated guide to flashing Coreboot on a ThinkPad X220.

Required Hardware/Software:

  • Lenovo ThinkPad X220 - duh
  • Raspberry Pi Running Raspian - Model 2 or 3
  • Pomona SOIC8 5250 chip clip
  • 8x Female Jumper Leads
  • Another Computer to SSH into the Raspberry Pi from
  • A Debian Server - Used for building Coreboot (I spun one up in DigitalOcean)

The Process

1) Configure SD Card with Raspian Lite image

2) Insert SD Card and connect Pi to network. I used an ethernet connection but you can use PiBakery to autoconnect to your wifi if you have a Raspberry Pi 3

3) Find the Raspberry Pi on your network and SSH into it. Check your DHCP server on your router.

ssh pi@$piipaddress  

4) Flashrom is a tool used to read the data from the BIOS chip. We will need to use the latest version but before we can do that we need to install some prerequisites first.

sudo apt update && sudo apt upgrade  
sudo apt install build-essential pciutils usbutils libpci-dev libusb-dev libftdi1 libftdi-dev zlib1g-dev subversion git  

5) Once everything is up to date and installed, download and compile Flashrom

git clone  https://review.coreboot.org/flashrom.git  
cd flashrom  
make  
sudo make install  

6) Now we need to enable the SPI kernel modules to /etc/modules so they persist between reboots. Once this is done. Shutdown the Pi and remove the power cable.

  sudo nano /etc/modules
    spi_bcm2835
    spidev

Alternatively: You can load them every boot manually

sudo modprobe spi_bcm2835  
sudo modprobe spidev  

7) We need to connect the Pi to the BIOS chip on the X220 which is located underneath the palmrest. Follow this Lenovo Support guide on removing the keyboard palmrest.

8) The BIOS chip is located underneath the black shielding by the PCMCIA slot. Attach the chip clip.

9) Connect the chip clip to the Raspberry Pi using the following diagram. (Courtsey of Karl Cordes)

Pamona 5250

Screen (furthest from you)  
         __
MOSI  5 --|  |-- 4  GND  
CLK   6 --|  |-- 3  N/C  
N/C   7 --|  |-- 2  MISO  
VCC   8 --|  |-- 1  CS

Edge (closest to you)  

Raspberry Pi

Edge of pi (furthest from you)  
L                                                             CS  
E                                                             |  
F +--------------------------------------------------------------------------------------------------------+  
T |    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    |  
  |    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    x    |
E +--------------------------------------------^----^----^----^---------------------------------------^----+  
D                                              |    |    |    |                                       |  
G                                             3.3V  MOSI MISO |                                      GND  
E                                           (VCC)            CLK  
  Body of Pi (closest to you)

10) With the clip connected, power on the Pi and SSH back into it. We should now be able to read the contents of the ROM with Flashrom. If Flashrom is not able to read the ROM, check your connections and try reseating the chip clip. Those are the two most common problems.

sudo flashrom -p linux_spi:/dev/spidev0.0,spispeed=512 -r oem01.bin`  

11) If the first read was successful, read the ROM again and compare the two reads to ensure everything is working correctly.

sudo flashrom -p linux_spi:/dev/spidev0.0,spispeed=512 -r oem02.bin  
md5sum oem01.bin oem02.bin  

12) Now that we have a known good copy of the ROM, we need to download and compile Coreboot. You can try to compile Coreboot on the Pi but in my experience that either takes too long OR fails entirely. This is where that Debian server comes into play. Transfer oem01.bin to the Debian server. We will need this for the Coreboot compilation.

Note: There is also a docker image available for building coreboot. I have not tried it yet though.  

13) On the Debian server, install the prerequisites for building Coreboot and me_cleaner (more on that later)

sudo apt install git build-essential gnat flex bison libncurses5-dev wget zlib1g-dev python3  

14) Clone the Coreboot source

git clone http://review.coreboot.org/coreboot.git  
~/coreboot
cd ~/coreboot  
git submodule update --init --recursive  
cd ~/coreboot/3rdparty  
git clone http://review.coreboot.org/p/blobs.git  

15) Build ifdtool. This is used to dump the Intel firmware from the ROM.

cd ~/coreboot/util/ifdtool  
make  
sudo make install  

16) Extract the individual components of the ROM for Coreboot to reference

cd ~  
ifdtool -x ~/oem01.bin  
mkdir -p ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220  
cd ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220  
cp ~/flashregion_0_flashdescriptor.bin descriptor.bin  
cp ~/flashregion_2_intel_me.bin me.bin  
cp ~/flashregion_3_gbe.bin gbe.bin  

17) With all the pieces in place, now we need to modify the Intel Management Engine to only run during the boot operation. This is done with me_cleaner.

cd ~  
git clone https://github.com/corna/me_cleaner ~/me_cleaner  
cd ~/me_cleaner  
./me_cleaner.py ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220/me.bin

18) Now we can configure Coreboot with all the settings we want before compilation.

cd ~/coreboot  
make nconfig  

19) Use the following settings for Coreboot. (Courtesy of Tyler Cipriani)

general  
  - [*] Compress ramstage with LZMA
  - [*] Include coreboot .config file into the ROM image
  - [*] Allow use of binary-only repository
mainboard  
  -  Mainboard vendor (Lenovo)
  -  Mainboard model (ThinkPad X220)
  -  ROM chip size (8192 KB (8 MB))
  -  (0x100000) Size of CBFS filesystem in ROM
chipset  
  - [*] Enable VMX for virtualization
  -  Include CPU microcode in CBFS (Generate from tree)
  -  Flash ROM locking on S3 resume (Don't lock ROM sections on S3 resume)
  - [*] Add Intel descriptor.bin file
    (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin) Path and filename of the descriptor.bin file
  - [*] Add Intel ME/TXE firmware
    (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/me.bin) Path to management engine firmware
  - [*] Add gigabit ethernet firmware
    (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/gbe.bin) Path to gigabit ethernet firmware
devices  
  - [*] Use native graphics initialization
display  
  - (nothing checked)
generic drivers  
  - [*] Support Intel PCI-e WiFi adapters
  - [*] PS/2 keyboard init
console  
  - [*] Squelch AP CPUs from early console.
    [*] Show POST codes on the debug console
system tables  
  - [*] Generate SMBIOS tables
payload  
  - Add a payload (SeaBIOS)
  - SeaBIOS version (master)
  - (3000) PS/2 keyboard controller initialization timeout (milliseconds)
  - [*] Harware init during option ROM execution
  - [*] Include generated option rom that implements legacy VGA BIOS compatibility
  - [*] Use LZMA compression for payloads
debugging  
  - (nothing checked)

20) Finally we can build Coreboot. Coreboot will put the ROM to ~/coreboot/build/coreboot.rom

cd ~/coreboot  
make crossgcc-i386 CPUs=4  
make iasl  
make  

21) Transfer coreboot.rom to your Raspberry Pi. Repeat steps 10 and 11 to confirm that the chip clip is connected properly and then go ahead and flash the ROM.

sudo flashrom -p linux_spi:/dev/spidev0.0,spispeed=512 -w ~/coreboot.rom  

22) Test to make sure that the ROM was flashed correctly.

sudo flashrom -p linux_spi:/dev/spidev0.0,spispeed=512 -r core01.bin  
sudo flashrom -p linux_spi:/dev/spidev0.0,spispeed=512 -r core02.bin  
md5sum core01.bin core02.bin  

23) Reassemble your X220 and boot. If you were successful you should be greated by SeaBIOS. If not, try again. If all else fails, revert to your old BIOS by flashing oem01.bin. Hang on to oem01.bin even if you did flash successfully. It will be helpful if you ever want to revert back to your old BIOS again.

References
Tyler Cipriani's Write Up
Karl Cordes Blog

Tim Kusajtys