My Lenovo Thinkpad x220 was corebooted in August of 2020. As I’ve recently purchased Nitrocaster’s FHD mod, I need to upgrade my coreboot installation to the latest version which has the patches and support for the mod.

This blog post is more for me to remember how to do this rather than a full tutorial. And I don’t think I finished this post either but making it public anyway.

Internal Flashing (not an arrestable offence)

coreboot (and libreboot) allow you to flash new BIOS images straight from the operating system. Sweet! So I build coreboot, thinking myself an expert with the hubris of youth, and flash it directly to the BIOS chip with sudo flashrom -p internal -w coreboot.rom.

Nothing explodes in a cacophony of fire and holy chip smoke so I pat myself on the back, crack a cold beer, and kick my feet up. ‘Another job well done’, I think to myself.

UEFI? New phone who dis

Forgetting that I have my boot set to use UEFI, obviously nothing boots. Why don’t I just reflash and go back to BIOS Legacy Mode? It’s because I spent a long time setting up my current build. Boot is encrypted, swap is encrypted, it does some funny LUKS stuff. I can’t even remember half the shit I’ve done to this laptop but I know that I like it and I’m keeping it setup like this.

Using a LiveUSB to boot up Ubuntu in Legacy Mode which (surprisingly) works in my favour as I am still able to flash a new ROM image. Perfect, I’ll just go back to my original coreboot build. I look through ym

Re-flashing coreboot

Lucky I still have my original firmware files.

┌─[peter@tartarus] - [/mnt/nas/Backups/X220/07.2020]
└─[$]> ls -lah roms
total 49M
drwxr-xr-x 2 root root    0 Jul 27  2020 .
drwxr-xr-x 2 root root    0 Jan 12 14:45 ..
-rwxr-xr-x 1 root root 8.0M Jul 27  2020 flash01.bin
-rwxr-xr-x 1 root root 8.0M Jul 27  2020 flash02.bin
-rwxr-xr-x 1 root root 8.0M Jul 27  2020 flash02.bin.bak
-rwxr-xr-x 1 root root 8.0M Jul 27  2020 flash03.bin
-rwxr-xr-x 1 root root 4.0K Jul 27  2020 flashregion_0_flashdescriptor.bin
-rwxr-xr-x 1 root root 3.0M Jul 27  2020 flashregion_1_bios.bin
-rwxr-xr-x 1 root root 5.0M Jul 27  2020 flashregion_2_intel_me.bin
-rwxr-xr-x 1 root root 8.0K Jul 27  2020 flashregion_3_gbe.bin
-rwxr-xr-x 1 root root 4.0K Jul 27  2020 ifd_shrinked.bin
-rwxr-xr-x 1 root root  80K Jul 27  2020 me_shrinked.bin
-rwxr-xr-x 1 root root 8.0M Jul 27  2020 out.bin

out.bin looks correct, right? I don’t think - I just do.

Yeah… despite having flash0{1,2,3}.bin as reads of the original firmware I decided that wasn’t enough and made a copy as *drum roll please* out.bin! Amazing! The laptop now runs the original Lenovo firmware and now I have to open it up and manually flash the ROM with my janky Raspberry Pi setup and some dodgy connectors.

Chip PIN set

Computer PIN set

re-building coreboot

me_cleaner

me_cleaner.py -t -r x220_me.bin -O me_out.bin

Adding Windows Support because at this point why not

Downloaded VGA BIOS image from here and slapped it in my 3rdparty blob folder. Added in the config.

Building EDK2 / TianoCore

Setup with the default EDK2 / TianoCore settings from MrChromebox’s fork. We’re missing nasm so install it with sudo pacman -S nasm.

Too Fat

Ugh, the ROM is still too big and won’t fit the UEFI payload in 8192KBs! Time to remove the VGA BIOS and see if that helps. Nope, doesn’t work. Adding it back because it’s not the problem.

Increasing the size of the CBFS partition from 0x100000 to 0x250000 fixes the problem!

Bingo! We build and it can hold Tianocore!

Building tint

I have no idea what this is and why I selected it as a secondary payload.

Something breaks when trying to install tint in the build process. I have no idea what this program is or what it does. Have to manually edit coreboot/payloads/external/tint.tint.sh and add url="https://mirror.fsf.org/trisquel/pool/main/t/tint" on line 115. This hardcodes the URL download path for tint and will enable it to keep compiling. Yes, it’s hacky - don’t @ me.

It works but there’s no display

Weirdly, the laptop is able to boot and the screen backlight comes on. However, nothing is display. I typed my LUKS password in to unlock the drive and I was dumped into my Linux install after a few seconds.

Need to enable CONFIG_MAINBOARD_USE_LIBGFXINIT and the linear buffer option for it to work.

Bootsplash Details

These can be created in GIMP, they MUST be exactly 1024 x 768 after saving your .xcf, choose to export the image as a .jpeg

Then select advanced deselect ‘progressive’ and change the quality to reduced chroma 4:2:0.

Adding a bootsplash to the Coreboot config doesn’t work with TianoCore / EDK2 - along with extra payloads (like MemTest and tint).

Final Config

Here is the output of make savedefconfig for future reference.

CONFIG_VENDOR_LENOVO=y
CONFIG_CBFS_SIZE=0x250000
CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=1600
CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=2560
# CONFIG_POST_DEVICE is not set
CONFIG_VGA_BIOS=y
CONFIG_CONSOLE_POST=y
CONFIG_IFD_BIN_PATH="3rdparty/blobs/mainboard/lenovo/x220/descriptor.bin"
CONFIG_ME_BIN_PATH="3rdparty/blobs/mainboard/lenovo/x220/me.bin"
CONFIG_GBE_BIN_PATH="3rdparty/blobs/mainboard/lenovo/x220/gbe.bin"
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000
CONFIG_EDK2_BOOT_TIMEOUT=2
CONFIG_VGA_BIOS_FILE="3rdparty/blobs/mainboard/lenovo/x220/vga-8086-0126.bin"
CONFIG_HAVE_IFD_BIN=y
CONFIG_PCIEXP_HOTPLUG_BUSES=8
CONFIG_PCIEXP_HOTPLUG_MEM=0x800000
CONFIG_PCIEXP_HOTPLUG_PREFETCH_MEM=0x10000000
CONFIG_BOARD_LENOVO_X220=y
# CONFIG_RAMINIT_ENABLE_ECC is not set
CONFIG_HAVE_ME_BIN=y
CONFIG_HAVE_GBE_BIN=y
CONFIG_MAINBOARD_USE_LIBGFXINIT=y
CONFIG_BOOTSPLASH=y
CONFIG_PCIEXP_HOTPLUG_IO=0x2000
CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_I2C_TRANSFER_TIMEOUT_US=500000
# CONFIG_SMMSTORE is not set
# CONFIG_TPM_PPI is not set
CONFIG_DRIVERS_PS2_KEYBOARD=y
CONFIG_POST_IO_PORT=0x80
CONFIG_PAYLOAD_EDK2=y
CONFIG_EDK2_BOOT_MANAGER_ESCAPE=y
CONFIG_EDK2_SD_MMC_TIMEOUT=10
CONFIG_COREINFO_SECONDARY_PAYLOAD=y //not necessary 
CONFIG_MEMTEST_SECONDARY_PAYLOAD=y  //not necessary 
CONFIG_NVRAMCUI_SECONDARY_PAYLOAD=y //not necessary