Skip to content

Instantly share code, notes, and snippets.

@killerbees19
Last active July 12, 2025 16:56
Show Gist options
  • Save killerbees19/bad66440f6fed917f2440536080b4737 to your computer and use it in GitHub Desktop.
Save killerbees19/bad66440f6fed917f2440536080b4737 to your computer and use it in GitHub Desktop.
coreboot @ Lenovo ThinkPad T440p

Replace original BIOS/UEFI with open-source alternative coreboot and strip down Intel ME.

This is my very first experience with SPI chips and external flashing πŸ₯³

These are my personal notes, just in case I need them again…

Hardware

  • Notebook: Lenovo ThinkPad T440p (20AW; without dGPU / only iGPU)
    • Top chip: Winbond 25Q32FVSIQ (4 MiB; accessible through "big door")
    • Bottom chip: Winbond 25Q64FVSIQ (8 MiB; full disassembly required)
  • Cables: 6 Γ— Jumper Wire (2.54 mm; Female to Female)
  • SOIC Test Clip: Pomona 5250 (8-pin)
  • SPI Interface: Raspberry Pi 1B

Disassembly

Don't forget to install all (firmware) updates before disassembling the device!

Wiring

Always remember: DO NOT CONNECT WIRES OR CLIPS WHILE ANYTHING IS POWERED ON!

Color reference for attached images only. (To all electricians: Don't blame me for weird color assigment 🀑)

Raspberry Pi 1 Mod. B (and later generations)

GPIO connector block at the top left corner:

x  x  x  x  x  x  x  x  x  x  x  24 x
|  |  |  |  |  |  |  |  |  |  |  |  |
|  |  |  |  |  |  |  |  |  |  |  |  |
x  x  x  x  x  x  x  x  17 19 21 23 25
  • Pin #17: 3V3 Power (Green)
  • Pin #19: GPIO10 / MOSI (Purple)
  • Pin #21: GPIO9 / MISO (Orange)
  • Pin #23: GPIO11 / SCKL (Blue)
  • Pin #24: GPIO8 / CE0 (Red)
  • Pin #25: GND (Yellow)

SOIC8 clip (Pomona 5250)

Topview, see attached photos:

4 x 2 1
| | | |
#######
#######
| | | |
5 6 x 8
  • Pin #1: CE0 (Red)
  • Pin #2: MISO (Orange)
  • Pin #4: GND (Yellow)
  • Pin #5: MOSI (Purple)
  • Pin #6: SCKL (Blue)
  • Pin #8: 3V3 (Green)

SPI chips

There's a little white sign on the PCB to mark pin 1!

  • Bottom chip (25Q64FVSIQ): Assuming that the battery slot is positioned at the top, pin 1 is located at the bottom left.
  • Top chip (25Q32FVSIQ): The top chip is rotated by 180Β°, therefor pin 1 is located at the top right near the RAM slots.

Using flashrom

  • Device: Raspberry Pi 1B (headless with network is fine)
  • Operating system: Raspberry Pi OS 12 (Bookworm)
sudo apt install flashrom

Enable SPI interface

sudo raspi-config
  • Interfacing Options
  • Enable SPI kernel module

Testing connection

Try to detect the chip:

flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512

That should output something like this:

 Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on linux_spi.
Found Winbond flash chip "W25Q64BV/W25Q64CV/W25Q64FV" (8192 kB, SPI) on linux_spi.
Found Winbond flash chip "W25Q64JV-.Q" (8192 kB, SPI) on linux_spi.
Multiple flash chip definitions match the detected chip(s): "W25Q64BV/W25Q64CV/W25Q64FV", "W25Q64JV-.Q"
Please specify which chip definition to use with the -c <chipname> option.

Reading from chip

# Read from top chip (25Q32FVSIQ) – takes approx. 1 minute.
flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -r "top.$(date +%s).bin"

# Read from bottom chip (25Q64FVSIQ) – takes approx. 2 minutes.
flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c W25Q64BV/W25Q64CV/W25Q64FV -r "bottom.$(date +%s).bin"

Repeat this multiple (2-5) times and compare the files:

md5sum *.bin

All checksums must be identical. DO NOT PROCEED IF THEY DO NOT MATCH!

Don't forget to store the original chip content as backup at multiple locations. πŸ˜‰

Writing to chip

# Split coreboot image into top/bottom part
dd if=coreboot.rom of=bottom.rom bs=1M count=8
dd if=coreboot.rom of=top.rom bs=1M skip=8

# Write to top chip (25Q32FVSIQ)
flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -w top.rom

# Write to bottom chip (25Q64FVSIQ)
flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c W25Q64BV/W25Q64CV/W25Q64FV -w bottom.rom

Building coreboot ROM from source

Successfully tested versions:

  • 24.02.01 (0a280ff747b44d7a2a62206ea0c25dbcbc5ce20b)
  • 24.05 (5a0207e56a4dbf599a2268fdc43ca3ab78b3af26)
  • 24.08 (04bb74a7267a64d39ca87ba8c9b4f9f34c7d2bbb)
  • 25.06 (9fe1546ffe29d00a82e1a99d94beccf2ad3c26dc)

Build environment: VM with Debian 12.11.0 (Bookworm) – alternatively use the RPi for building.

sudo apt install bison build-essential coreboot-utils curl flashrom flex gcc-multilib git gnat \
                 imagemagick libncurses5-dev libssl-dev m4 nasm ncurses-bin parted pkg-config \
                 python-is-python3 sharutils unzip uuid-dev zlib1g zlib1g-dev

First build

# Clone source code repository
git clone https://review.coreboot.org/coreboot
cd coreboot

# Checkout release tag
git checkout 25.06

# Merge original ROM (top + bottom) into one file.
# DO NOT FORGET TO REPLACE THE PATH TO THESE FILES!
cat ~/bottom.bin ~/top.bin > util/ifdtool/original.rom

# Export blobs from original ROM
(cd util/ifdtool && make && ./ifdtool -x original.rom)

# Obtaining mrc.bin from a haswell chromebook firmware image
(make -C util/cbfstool && cd util/chromeos && ./crosfirmware.sh peppy && ../cbfstool/cbfstool coreboot-*.bin extract -f mrc.bin -n mrc.bin -r RO_SECTION)

# Import default build configuration from attachment T440p.defconfig
wget -O configs/defconfig https://gist.githubusercontent.com/killerbees19/bad66440f6fed917f2440536080b4737/raw/T440p.defconfig
make defconfig

## Or create your own!
# make menuconfig
# make savedefconfig

# Build required toolchain
make crossgcc-i386 CPUS=$(nproc)

# Build ROM
make

Now simply flash the file build/coreboot.rom. (See: Writing to chip)

Subsequent builds

Requirement: coreboot already installed, operating system booted with iomem=relaxed!

# Update source code repository
cd ~/coreboot
git fetch -a

# Checkout release tag
git checkout 25.06

# Revise config
make menuconfig

## Optional: Save config
#make savedefconfig

# Build required toolchain
make crossgcc-i386 CPUS=$(nproc)

# Build ROM again
make

Now copy the file build/coreboot.rom to the running system and flash it:

sudo apt install flashrom
sudo flashrom -p internal:laptop=force_I_want_a_brick -w coreboot.rom
sudo shutdown -h now

Note: Disconnect all power sources (AC & battery) for a short period of time after shutdown. Otherwise POST could fail, which results in a black screen and 100% fan speed. If you've "bricked" your device, disassemble again and flash a known working ROM or the original backup.

Workarounds (for Debian 12)

SeaBIOS & GRUB: No display output

Symptom: Black screen after SeaBIOS.

  • Update coreboot configuration and rebuild it:
    • CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=1280
    • CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=720

(Valid VESA video mode recommended for SeaBIOS!)

SeaBIOS & GRUB: Fullscreen resolution

Symptom: GRUB only visible in a small area at the top left.

  • Update /etc/default/grub: GRUB_GFXMODE=1280x720
  • And rebuild GRUB configuration: sudo update-grub

Use the values from CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH and CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT.

ACPI kernel module

Symptoms: Missing fan speed, no battery thresholds, …

echo 'options thinkpad_acpi force_load=1' | sudo tee -a /etc/modprobe.d/coreboot.conf
sudo rmmod thinkpad_acpi; sudo modprobe thinkpad_acpi

This should fix many issues, but not all of them.

Known problems

(TODO: Create tickets at the Issue Tracker!)

  • SD card reader broken. (CB#297)
  • TLP older than v1.7.0: Missing or invalid battery values at tlp-stat -b. (CB#448)
  • Power LED's disabled after reboot. (power button + red i-dot; see related CB#535)
  • Keyboard backlit not controllable by OS anymore. (maybe related: CB#R51412)
  • FHD not supported by Coreboot/EDK2/GRUB while docked, only XGA works.
  • Battery calibration not supported.
  • FN key LED state is always-on.

External links

Alternative: Patch original BIOS/UEFI

Patch original BIOS/UEFI to remove WLAN/WWAN whitelist and enable hidden advanced menus.

This is just a short write-up. Please take a look at the full README-COREBOOT.md for detailed wiring instructions!

Install required tools

UEFIPatch

Quote from GitHub:

Image editing is currently only possible using an outdated and unsupported UEFITool 0.28 (old_engine branch) and the tools based on it (UEFIReplace, UEFIPatch).

Therefore we'll extract the binary from an old Debian package. (Use snapshot.debian.org or web.archive.org if these links vanish!)

Download UEFIPatch (amd64)

wget http://deb.debian.org/debian/pool/main/u/uefitool/uefitool-cli_0.28.0-1_amd64.deb
sha256sum -c <(printf '%s  %s' 'b0c65f77ad90ac192d584304c8786aaa92b0d5496b54cda9166303b24bd096c8' 'uefitool-cli_0.28.0-1_amd64.deb')
ar --output=/tmp x uefitool-cli_0.28.0-1_amd64.deb data.tar.xz
tar xfva /tmp/data.tar.xz ./usr/bin/UEFIPatch --strip=3
sudo apt install libqt5core5a

Download UEFIPatch (i386)

wget http://deb.debian.org/debian/pool/main/u/uefitool/uefitool-cli_0.28.0-1_i386.deb
sha256sum -c <(printf '%s  %s' '25b8a75429f7c5e71f6348c7d24803f82f1aec6234fa05d614b4480c4d4b12f7' 'uefitool-cli_0.28.0-1_i386.deb')
ar --output=/tmp x uefitool-cli_0.28.0-1_i386.deb data.tar.xz
tar xfva /tmp/data.tar.xz ./usr/bin/UEFIPatch --strip=3
sudo apt install libqt5core5a

Download UEFIPatch (arm64)

wget http://deb.debian.org/debian/pool/main/u/uefitool/uefitool-cli_0.28.0-1_arm64.deb
sha256sum -c <(printf '%s  %s' 'fa964779307e573cdbc74ebb72ac82387cc4b53f69570f1cd958c8f073e4e605' 'uefitool-cli_0.28.0-1_arm64.deb')
ar --output=/tmp x uefitool-cli_0.28.0-1_arm64.deb data.tar.xz
tar xfva /tmp/data.tar.xz ./usr/bin/UEFIPatch --strip=3
sudo apt install libqt5core5a

Download UEFIPatch (armel)

wget http://deb.debian.org/debian/pool/main/u/uefitool/uefitool-cli_0.28.0-1_armel.deb
sha256sum -c <(printf '%s  %s' '0641e17971612070ac1ac897d486ff03b22671f53af1e0d0cd918e8d38c7fe4e' 'uefitool-cli_0.28.0-1_armel.deb')
ar --output=/tmp x uefitool-cli_0.28.0-1_armel.deb data.tar.xz
tar xfva /tmp/data.tar.xz ./usr/bin/UEFIPatch --strip=3
sudo apt install libqt5core5a

Download UEFIPatch (armhf)

wget http://deb.debian.org/debian/pool/main/u/uefitool/uefitool-cli_0.28.0-1_armhf.deb
sha256sum -c <(printf '%s  %s' '467064c6adbca49091d8498b9b7d077027dac73ad6f3b4ea94f3cbb975ec6a1c' 'uefitool-cli_0.28.0-1_armhf.deb')
ar --output=/tmp x uefitool-cli_0.28.0-1_armhf.deb data.tar.xz
tar xfva /tmp/data.tar.xz ./usr/bin/UEFIPatch --strip=3
sudo apt install libqt5core5a

Download thinkpad-uefi-sign

sudo apt install git python3 python3-pip
python3 -m venv python3
python3/bin/pip install pycryptodome
git clone https://github.com/thrimbor/thinkpad-uefi-sign.git

Download patches

wget -O 'T440-BIOS-Patch.txt' https://pastebin.com/raw/TZYnnmY8

Read from chip

flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -r top-original.bin

Repeat this multiple (2-5) times and compare the files!

Patch file

./UEFIPatch top-original.bin T440-BIOS-Patch.txt -o top-patched.bin

Image patched

Sign file

python3/bin/python3 thinkpad-uefi-sign/sign.py top-patched.bin -o top-patched-signed.bin

IMAGE SIGNED!

Check signature

python3/bin/python3 thinkpad-uefi-sign/verify.py top-patched-signed.bin

SIGNATURES CORRECT!

Write to chip

flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -w top-patched-signed.bin

Known problems

  • RTC can't be set in BIOS/UEFI anymore after flashing a modded image with advanced settings enabled! (Use any OS to update date/time.)

External links

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

@killerbees19
Copy link
Author

killerbees19 commented May 28, 2024

Timeline

  • 2023-10-19: Got my first T440p from Willhaben, someone mentioned coreboot support.
  • 2024-03-18: Got another cheap T440p from eBay, someone mentioned Pomona 5250.
  • 2024-03-25: Pomona 5250 arrived. (RPi 1B and jumper wires pre-existent)
  • 2024-05-20: Disassembled my cheap T440p from eBay.
  • 2024-05-21: Read original flash chip contents.
  • 2024-05-22: Built and flashed coreboot.
  • 2024-05-24: Final build/flash. (β‰₯ 10)
  • 2024-05-28: Public documentation.

Changelog

  • 2024-06-15: Switched from SeaBIOS to edk2 (UEFI).
  • 2024-06-17: Added instructions for whitelist-removal.
  • 2024-06-19: Removed useless coreboot configs.
  • 2024-10-31: Fixed missing commands in list.

TODO

@Chublins
Copy link

Whenever I run make to build coreboot I get:
Aborting
fatal: Unable to checkout 'de90e54bbe82e5be4fb9608b6f5c308bb837d355' in submodule path 'CryptoPkg/Library/OpensslLib/openssl'
make[1]: *** [Makefile:196: /home/myuser/coreboot/payloads/external/edk2/workspace/mrchromebox] Error 1
make: *** [payloads/external/Makefile.mk:160: build/UEFIPAYLOAD.fd] Error 2

How do I fix this?

@Chublins
Copy link

@killerbees19 Same error with 25.03. I'll try making a new config and see if that changes anything.

@Chublins
Copy link

@killerbees19 No matter what I do to the config I get the same error. I tried switching over to the original edk2 repository and not MrChromebox's fork and I had a lot of errors not related to this that I am not qualified to begin solving. But this did show that the error was specific to MrChromebox's fork, at least as far as I could tell. I guess he needs to fix it upstream.

@killerbees19
Copy link
Author

killerbees19 commented Jun 13, 2025

@Chublins I think this should fix it… (for 24.08 and maybe 25.03 too)

This is already fixed in Coreboot main but not in the latest release.

# Patch default config
git cherry-pick 157b7ae778e7d00c7abf0c9c67f7e0a2740967d4

# Patch current config
[ -f .config ] \
  && grep -q '^CONFIG_EDK2_REPOSITORY="https://github.com/mrchromebox/edk2"$' .config \
  && sed -i -r 's#^(CONFIG_EDK2_TAG_OR_REV)=".+"$#\1="origin/uefipayload_2502"#' .config

# Build Coreboot
make

When building the toolchain for 24.08 there's an additional workaround required, because the original URL has disappeared:

# Download the failed file manually
wget -nc -O util/crossgcc/tarballs/acpica-unix-20230628.tar.gz https://www.coreboot.org/releases/crossgcc-sources/acpica-unix-20230628.tar.gz

# Build toolchain (again)
make crossgcc-i386 CPUS=$(nproc)

Please report back if it works now πŸ™‚

I'll update this Gist once I've successfully flashed 25.03 to one of my T440p mainboards.

@Chublins
Copy link

@killerbees19 Thanks for the reply and potential fix. I could have done something wrong, but I'm fairly certain I did everything correctly. This still gives me errors, however they are different now. This is with 24.08

Ran 303 tests in 1.446s

OK
make[3]: Leaving directory '/home/myuser/coreboot/payloads/external/edk2/workspace/mrchromebox/BaseTools/Tests'
make[2]: Leaving directory '/home/myuser/coreboot/payloads/external/edk2/workspace/mrchromebox/BaseTools'
grep: /home/myuser/coreboot/payloads/external/edk2/workspace/mrchromebox/Conf/tools_def.txt: No such file or directory
/home/myuser/coreboot/payloads/external/edk2/workspace/mrchromebox/edksetup.sh: line 82: /home/myuser/coreboot/payloads/external/edk2/workspace/tianocore/BaseTools/BuildEnv: No such file or directory
EDK2: Building... bash: line 4: build: command not found
Failed!
make[1]: *** [Makefile:282: /home/myuser/coreboot/payloads/external/edk2/workspace/Build/UefiPayloadPkgX64/RELEASE_COREBOOT/FV/UEFIPAYLOAD.fd] Error 1
make: *** [payloads/external/Makefile.mk:160: build/UEFIPAYLOAD.fd] Error 2

@killerbees19
Copy link
Author

killerbees19 commented Jun 13, 2025

@Chublins Retry it with 25.03, I've successfully built (but not flashed!) this version with my workaround from above in a clean new directory. (Debian 12.11 / amd64)

Draft for my Gist:

# Clone source code repository
git clone https://review.coreboot.org/coreboot
cd coreboot

# Checkout release tag
git checkout 25.03

# Patch default config (only required for 25.03 or earlier!)
git cherry-pick 157b7ae778e7d00c7abf0c9c67f7e0a2740967d4

# Merge original ROM (top + bottom) into one file.
# DO NOT FORGET TO REPLACE THE PATH TO THESE FILES!
cat ~/bottom.bin ~/top.bin > util/ifdtool/original.rom

# Export blobs from original ROM
(cd util/ifdtool && make && ./ifdtool -x original.rom)

# Obtaining mrc.bin from a haswell chromebook firmware image
(make -C util/cbfstool && cd util/chromeos && ./crosfirmware.sh peppy && ../cbfstool/cbfstool coreboot-*.bin extract -f mrc.bin -n mrc.bin -r RO_SECTION)

# Import default build configuration from attachment T440p.defconfig
wget -O configs/defconfig https://gist.githubusercontent.com/killerbees19/bad66440f6fed917f2440536080b4737/raw/T440p.defconfig
make defconfig

## Or create your own!
# make menuconfig
# make savedefconfig

# Build required toolchain
make crossgcc-i386 CPUS=$(nproc)

# Build ROM
make

This should work, but currently I'm unable to test if it boots without issues. πŸ˜‡

@killerbees19
Copy link
Author

@Chublins I've successfully built 25.06 without any patches. Linux boots fine at one of my T440p boards πŸ˜€

(Gist updated for the latest Coreboot release.)

@Jameeble
Copy link

Jameeble commented Jul 4, 2025

@Chublins I've successfully built 25.06 without any patches. Linux boots fine at one of my T440p boards πŸ˜€

(Gist updated for the latest Coreboot release.)

Haha oh wow I literally just did this too, works perfect!
20250704_184640

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment