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 flashrom
sudo raspi-config
- Interfacing Options
- Enable SPI kernel module
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.
# 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. 😉
# 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
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
# 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)
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.
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!)
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.
- FN key LED state is always-on.
- 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
Timeline
Changelog