Flashing Libreboot on an X200 with a Raspberry Pi

A couple of weeks ago, someone kindly donated a ThinkPad X200 for me to practice flashing coreboot on. As the X200 has an Intel GPU, it is able to run Libreboot; the 100% Free, pre-compiled downstream of the coreboot project.

Unfortunately, the initial Libreboot flash cannot be done internally, so you have to open the laptop up. It’s not very complicated though. You only have to remove the palm rest, because the flash chip is at the top of the motherboard

I bought another SOIC clip online (a 16-pin one this time), and I wired up the six required wires to the Raspberry Pi. It’s probably best to get a numbered GPIO cable so you’ll only have to mess about with the wires on one side.

The X200's flash chip is very susceptible to interference, so you might want to make twisted pairs.

The chip’s pins are numbered counter-clockwise starting at the bottom right. So the row near the GPU consists of pins 1 to 8, and the row near the cardbus consists of pins 9 to 16.

Picture courtesy of 'snuffeluffegus'.

The pinout is like this:

2  - 3.3V    - Pi Pin #1
7  - CS#     - Pi Pin #24
8  - S0/SIO1 - Pi Pin #21
10 - GND     - Pi Pin #25
15 - S1/SIO0 - Pi Pin #19
16 - SCLK    - Pi Pin #23

 

Preparing the ROM

Libreboot’s ROMs are almost completely suitable to flash without intervention. The only thing you have to add is the MAC address of your ethernet controller. Libreboot’s documentation explains how this is done.

You will need to download the X200 ROMs (most likely the 8MB versions: 4MB is rare) and libreboot_util from the Libreboot download site and extract both those xz archives in a working directory. For instance, ~/Downloads/libreboot/.

To put it as simply as possible, first you choose a ROM based on your keyboard layout.

kevin@vanadium:~/Downloads/libreboot/x200_8mb$ ls
 [...]
 x200_8mb_ukdvorak_vesafb.rom
 x200_8mb_ukqwerty_vesafb.rom
 x200_8mb_usdvorak_vesafb.rom
 x200_8mb_usqwerty_vesafb.rom

Then you copy that file to the ich9gen directory, you rename it to libreboot.rom and  you change to that directory.

cp ~/Downloads/libreboot/x200_8mb/x200_8mb_usdvorak_vesafb.rom
~/Downloads/libreboot/libreboot_util/ich9deblob/x86_64/libreboot.rom
cd ~/Downloads/libreboot/libreboot_util/ich9deblob/x86_64/

Now look at the sticker on the bottom of your X200 and write down (or memorize) the MAC address. If you can’t find a sticker there, another one is underneath the RAM.

Create a descriptor with your MAC address by running this command:

./ich9gen --macaddress 00:1F:00:00:AA:AA
(Of course, use your own MAC address instead of this example.)

Then add that descriptor to the ROM by running this command:

dd if=ich9fdgbe_8m.bin of=libreboot.rom bs=1 count=12k conv=notrunc

Note that you have to use the 4MB version in the rare case that you have a 4MB BIOS chip.

Now put the libreboot.rom image on your Raspberry Pi.

scp libreboot.rom root@raspberry-pi.local:/root/libreboot/
(This is just an example using SFTP. Your situation may be different.)

 

Setting up the Raspberry Pi

You will have to update the Raspberry Pi’s kernel to the latest version (3.18) in order to get the X200′s chip to work somewhat reliably over spidev. (But it never really seems to be stable.)

sudo rpi-update

Then, download the Flashrom source code and compile it for armhf.

sudo apt-get install build-essential pciutils usbutils libpci-dev libusb-dev libftdi-dev zlib1g-dev subversion
svn co svn://flashrom.org/flashrom/trunk flashrom
cd flashrom
make

If you’re not in the mood to compile it yourself on a slow Raspberry Pi, I have precompiled armv6l Flashrom binaries here. See above for obtaining the source code.

Reading the chip took a lot of attempts before I started getting hash sum matches. In fact, I was close to giving up entirely because of the many unexplainable failed attempts.

./flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c "MX25L6405D" -r romread1.rom
./flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c "MX25L6405D" -r romread2.rom
./flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c "MX25L6405D" -r romread3.rom

sha512sum romread*.rom

(All checksums must be identical.)

To be honest, I have no idea what I did exactly to get it working eventually. All of a sudden, the checksums started matching three times in a row, even though I was on another floor, using SSH, and didn’t touch or change anything.

So after three successful reads, I just crossed my fingers and flashed the ROM.

./flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c "MX25L6405D" -w ../libreboot.rom

And I bricked the laptop…

Uh oh. Erase/write failed. Checking if anything changed.
Your flash chip is in an unknown state.

I booted it up, and everything remained black.

After crying for three hours straight, I tried flashing once more with spispeed=128, and then it worked. I got a “VERIFIED” at the end and it booted to GRUB.

./flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=128 -c "MX25L6405D" -w ../libreboot.rom

Winning!

Hello GRUB.

GRUB easily allowed me to load the Debian netinstaller. All that was left to do was to install an Atheros AR9280 WiFi card from my collection, and I now have a working X200 with Libreboot.

Ironically, you need to have a USB drive with a UEFI-menu for GRUB to boot from it.

Afterward, I tried some more test reads (spispeed varying between 128 and 1024), and I’d still be getting checksum mismatches at least one out of five times (sometimes more). So I still feel like the Raspberry Pi is quite volatile, and I’m curious whether the BBB is just as ‘hit and miss’.

I gave this X200 to my grandfather, who now uses it as his daily work machine. (He’s an accountant.) There are no hardware issues with Libreboot, other than the undock button on the docking station not working. But I already thought of a fix for that.

In the end, I concluded that flashing the X200 with a Raspberry Pi is quite a chore. It’s possible, but it seems to be dependent on the weather. The failure rate is easily 80%, although you will probably get it to work eventually.

Thankfully, after flashing Libreboot the first time, subsequent updates can be done internally with flashrom -p internal or simply Libreboot’s ./flash script.

Comments are closed.