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…
- 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
Don't forget to install all (firmware) updates before disassembling the device!
- HMM: 1160 – Base cover assembly
- Tutorial video: Jack Zhang @YouTube
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 🤡)
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)
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)
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.
- Device: Raspberry Pi 1B (headless with network is fine)
- Operating system: Raspberry Pi OS 12 (Bookworm)
sudo apt install flashromsudo raspi-config- Interfacing Options
- Enable SPI kernel module
Try to detect the chip:
flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512That 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.
# 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 *.binAll 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. 😉
# 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.romSuccessfully 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# 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
makeNow simply flash the file build/coreboot.rom. (See: Writing to chip)
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
makeNow 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 nowNote: 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.
Symptom: Black screen after SeaBIOS.
- Update coreboot configuration and rebuild it:
CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=1280CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=720
(Valid VESA video mode recommended for SeaBIOS!)
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.
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.
(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. (Workaround:
ectool -w 0xb4 -z 0x06) - FN key LED state is always-on with
f1_to_f12_as_primary=Enable.
- doc.coreboot.org: Tutorial – Starting from scratch
- doc.coreboot.org: Mainboard-specific documentation
- wiki.flashrom.org: Using Raspberry Pi as SPI interface
- tomvanveen.eu: How to flash bios chips with Raspberry Pi
- libreboot.org: Read/write 25XX NOR flash via SPI protocol
- libreboot.org: ThinkPad T440p external flashing
- blog.0xcb.dev: Lenovo T440p Coreboot









@Chublins I think this should fix it… (for
24.08and maybe25.03too)This is already fixed in Coreboot
mainbut not in the latest release.When building the toolchain for
24.08there's an additional workaround required, because the original URL has disappeared:Please report back if it works now 🙂
I'll update this Gist once I've successfully flashed
25.03to one of my T440p mainboards.