Skip to content

Instantly share code, notes, and snippets.

@killerbees19
Last active November 7, 2024 17:54
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:

  • 2024.02.01 (0a280ff747b44d7a2a62206ea0c25dbcbc5ce20b)
  • 2024.05 (5a0207e56a4dbf599a2268fdc43ca3ab78b3af26)
  • 2024.08 (04bb74a7267a64d39ca87ba8c9b4f9f34c7d2bbb)

Build environment: VM with Debian 12.5.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 2024.02.01

# 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/b4311f6b540e7c8339f2be82cc6b34e8a3563630/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 24.05

# 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.

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