The ThinkPad X220 is an older, but still excellent small laptop. Around the slightly outdated CPU and display is an amazing rugged chassis and one of the best keyboards you can find on a laptop.
Possibly because of this, there’s a huge community of hackers and modders using and developing for the X220 (and other ThinkPads). It is well supported by Linux distributions and other operating systems like OpenBSD.
The X220 is well supported by the free and open source firmware project Coreboot, which has a few benefits over the stock firmware:
- Free and open source
- No whitelists, you can use your own network card or battery
- Super fast boot times
Aside from the needing your X220, you will also need:
- A Phillips screwdriver
- A CH341A USB programmer
- A Pomona SOIC8 clip
- Another computer
You can pick up the CH341A and the test clip for cheap on sites like eBay or AliExpress.
The ThinkPad will reject our modified firmware if we try to flash it through software, so we’ll open up the laptop and flash the chip containing the BIOS directly. Luckily the ThinkPad’s maintenence friendly design means that it’s only hiding behind a few screws and a little bit of plastic.
Start by removing the battery and then the screws from the underside of the laptop that hold the keyboard and palm rest in. All of these screws are of the same size so don’t worry about mixing them up. There are seven of them in total and they are helpfully labelled with an icon of a keyboard.
Once the screws are removed, flip the laptop back over and use both hands to slide the keyboard towards the screen. Lift the keyboard up from the front and remove the ribbon cable connecting the keyboard to the motherboard. Lift up the latch holding in the palm rest ribbon cable, remove the ribbon cable, and then remove the palm rest by pulling it from the corners.
You shouldn’t have to force anything. If you get stuck, there’s an excellent video for disassembly on the Lenovo website.
Now peel up the sheet of plastic from the front left corner of the motherboard. This reveals the BIOS chip.
Reading the Original BIOS Image
After freeing the BIOS chip from its plastic prison we can use our programmer to read the original BIOS image from our device.
You’ll need to install
flashrom on your second computer. Consult your distribution’s package manager (e.g.
sudo apt install flashrom), or check the Flashrom web page.
If you really wanted to, you could desolder this chip from the board and insert it into your programmer. But to save time, we’ll use a test clip. Insert the PCB end of your test clip into the programmer, into the holes that are closest to the USB port end of your programmer.
Plug the programmer into your computer and a red LED should turn on. Put the clip over the BIOS chip - if the red LED goes dim you’ve connected it backwards so flip your clip around and try again. This shouldn’t damage anything.
Now we can finally use the
flashrom program to dump the original BIOS:
sudo flashrom \ -c 'MX25L6406E/MX25L6408E' \ -p ch341a_spi \ -r x220-orig.bin
You should back this file up, just in case you ever want to go back to the stock BIOS.
If you want to be certain everything is working as it should, you can try dumping the BIOS again (to a different file) and comparing the two dumps with the
diff command (e.g.
diff x220-orig.bin x22-orig-2.bin should exit with no message).
(Partially) Removing Intel’s Management Engine
On the generation of Intel CPU that the x220 uses, me_cleaner can be used to partially remove most of Intel ME. It’s possible to remove all of it, but then the laptop will get upset and shut itself down after a few minutes after booting.
git clone https://github.com/corna/me_cleaner.git cd me_cleaner python me_cleaner.py -SO ../x220-no-me.bin ../x220-orig.bin
You could stop here and flash the
x220-no-me.bin image back onto your laptop, but we will continue by using this image to build Coreboot.
Firstly, let’s grab the Coreboot source code:
git clone --recursive https://review.coreboot.org/coreboot.git
Next we’ll build
ifdtool, a program that we can run to split our BIOS image up into pieces:
cd coreboot/util/ifdtool make
And then we can run it and move the pieces into Coreboot’s blobs directory:
./ifdtool -x ~/x220/x220-no-me.bin cd ../.. mkdir -p 3rdparty/blobs/mainboard/lenovo/x220 cd 3rdparty/blobs/mainboard/lenovo/x220 mv ~/x220/coreboot/util/ifdtool/flashregion_0_flashdescriptor.bin \ descriptor.bin mv ~/x220/coreboot/util/ifdtool/flashregion_2_intel_me.bin \ me.bin mv ~/x220/coreboot/util/ifdtool/flashregion_3_gbe.bin \ gbe.bin
Now we can go back to the Coreboot root directory and configure it:
cd ../../../../.. make menuconfig
I changed the following options from the defaults:
Mainboard -> Mainboard vendor -> Lenovo Mainboard model -> ThinkPad X220 Chipset -> Add Intel descriptor.bin file Add Intel ME/TXE firmware Add gigabit ethernet configuration Generic Drivers -> PS/2 keyboard init Secondary Payloads -> Load coreinfo as a secondary payload Load nvramcui as a secondary payload
Sticking with SeaBIOS as the default payload is the easiest way to go. You can use it to boot other operating systems like a Linux distribution, FreeBSD, Windows, etc. as normal.
coreinfo is a small application that provides some system information, and
nvramcui allows you to tweak some system settings.
You could use Tianocore instead, which provides a UEFI interface instead of a BIOS interface, but it’s quite slow and doesn’t really offer any benefits. If you’re willing to tweak a few settings, the GRUB and Linux kernel payloads are very interesting and allow your laptop to boot very quickly.
After configuration, we’re almost ready to build Coreboot. However, some of Coreboot (specifically some of the graphics initialisation code) is written in Ada, so you’ll need an Ada compiler. Check your distribution’s package manager. Debian 10 users can try
sudo apt install gnat-8, and Gentoo users can
Firstly we’ll build a compiler that targets plain i386 (your current toolchain probably targets x86_64-linux), then we’ll build the IASL ACPI compiler, and then finally we can use both of those to actually compile Coreboot.
make crossgcc-i386 CPUS=$(nproc) make iasl make
After a lot of waiting, you should see the message
Built lenovo/x220 (ThinkPad X220). Your new firmware image is available in the build directory and can be flashed with flashrom!
Connect the clip and programmer the same way as it was when reading the original image. The
-w parameter is the path to the image to flash.
sudo flashrom \ -c 'MX25L6406E/MX25L6408E' \ -p ch341a_spi \ -w build/coreboot.rom
After writing, flashrom automatically reads the data back again to verify that it was written correctly.
Testing and Re-assembly
Connect the keyboard back to the motherboard, and either reconnect the battery or the charger. Press the power button and you should be greeted with the SeaBIOS boot menu. From here you can press Esc and a number key to select a boot option such as your internal storage drive, a USB memory stick, or one of your secondary payloads like nvramcui.
If you get stuck at some point, there are a few communities you could try asking for help in:
Now that Coreboot is installed, you can update it without needing to use an external programmer. On Debian and derivatives, you need to firstly add
iomem=relaxed to your kernel command line. GRUB users can accomplish this by adding the following line to
/etc/default/grub and running
After flashrom is installed, it can be used like this:
sudo flashrom \ -c 'MX25L6406E/MX25L6408E' \ -p internal:laptop=force_I_want_a_brick \ -w coreboot.rom
The GRUB payload is quite easy to use, however embedding the
grub.cfg file into your BIOS makes it annoying to work with as tools like
grub-mkconfig won’t be able to write to it. To remedy this, you can use your embedded config file to read your real configuration from the disk:
# assuming your /boot is the first # partition on the first drive configfile (ahci0,0)/grub/grub.cfg
The process should be identical on the ThinkPad T420. With the ThinkPad X230 and T430, there are two BIOS chips that you need to concatenate together to make your image.