About a year ago I replaced the horrible TN display of my boyfriend’s T430 with a Full-HD IPS and in the same move I replaced the LAN Ethernet USB Board due to a bent USB port. Because the laptop had to be completely disassembled anyway, I decided to give Coreboot a try.

This blogpost serves as a memory support, if I should decide to flash another laptop. I’ve used a CH341A programmer.

Unfortunately I did not take any pictures, but you should find some in the linked blogposts below.

Retrieve Sources, Checkout and Compile Toolchain

Basically:

git clone https://github.com/coreboot/coreboot
cd coreboot
git submodule update --init --checkout
make crossgcc-i386 CPUS=$(nproc)
cd util/ifdtool
make
  • crossgcc-i386 – Build the crossgcc compiler with i386 support.
  • ifdtool - Extracts the blobs from our bios.

Dump original firmware

Check the connection to the programmer and chip

jan@jantop ~/T430 % sudo flashrom -p ch341a_spi
[sudo] password for jan:
flashrom v1.1 on Linux 5.3.13-arch1-1 (x86_64)
flashrom is free software, get the source code at https://flashrom.org
 
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3205(A)" (4096 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L3273E" (4096 kB, SPI) on ch341a_spi.
Multiple flash chip definitions match the detected chip(s): "MX25L3205(A)", "MX25L3205D/MX25L3208D", "MX25L3206E/MX25L3208E", "MX25L3273E"
Please specify which chip definition to use with the -c <chipname> option.

Now it is time to back up the factory roms.

You should make at least two copies of the factory rom, then compare the SHAsums so you can verify that they are the same. If they are different, give it another go. Often the clamps on the chip doesn’t make right contact or the wires are too long. if nothing helps, change the spispeed.

Dump the factory rom top chip

Read the flashchip

sudo flashrom --programmer ch341a_spi -r backup_top1.bin -c "MX25L3205D/MX25L3208D"
sudo flashrom --programmer ch341a_spi -r backup_top2.bin -c "MX25L3205D/MX25L3208D"
sudo flashrom --programmer ch341a_spi -r backup_top3.bin -c "MX25L3205D/MX25L3208D"

Verify the dump

jan@jantop ~/T430 % sha512sum backup_top*.bin
3a95f283e892508c42b7a93aa40e5eaa179669d05612eeb4172ab622626186ee1bd713af8dd3078dcf3d8e9c6bfe1b832d019b194a7111e5c40e65851ef7bbb0  backup_top1.bin
3a95f283e892508c42b7a93aa40e5eaa179669d05612eeb4172ab622626186ee1bd713af8dd3078dcf3d8e9c6bfe1b832d019b194a7111e5c40e65851ef7bbb0  backup_top2.bin
3a95f283e892508c42b7a93aa40e5eaa179669d05612eeb4172ab622626186ee1bd713af8dd3078dcf3d8e9c6bfe1b832d019b194a7111e5c40e65851ef7bbb0  backup_top3.bin

Dump the factory rom bottom chip

Read the flashchip

sudo flashrom --programmer ch341a_spi -r backup_bottom1.bin -c "MX25L6406E/MX25L6408E"

verify the dump

jan@jantop ~/T430 % sha512sum backup_bottom.bin
8edb965dd0d0b3c9bc27d236ff606f28ad26ea6abe66ce5ac23340cc8324a86726585aa14737b2f8e2140d5554bb65782cee5dc8cf33707b50000842e428ec37  backup_bottom1.bin
8edb965dd0d0b3c9bc27d236ff606f28ad26ea6abe66ce5ac23340cc8324a86726585aa14737b2f8e2140d5554bb65782cee5dc8cf33707b50000842e428ec37  backup_bottom2.bin
8edb965dd0d0b3c9bc27d236ff606f28ad26ea6abe66ce5ac23340cc8324a86726585aa14737b2f8e2140d5554bb65782cee5dc8cf33707b50000842e428ec37  backup_bottom3.bin

Combine the files

Now, combine the two files to create one 12MB file.

cat backup_bottom1.bin backup_top1.bin > T430-bios.rom

Extract Binary Blobs from Original Firmware Dump

use ifdtool to extract flashregions, i.e.:

cd util/ifdtool
make
jan@jantop ~/T430/coreboot/util/ifdtool (git)-[master] % ./ifdtool -x ~/T430/t430-bios.bin
File /home/jan/T430/t430-bios.bin is 12582912 bytes
  Flash Region 0 (Flash Descriptor): 00000000 - 00000fff
  Flash Region 1 (BIOS): 00500000 - 00bfffff
  Flash Region 2 (Intel ME): 00003000 - 004fffff
  Flash Region 3 (GbE): 00001000 - 00002fff
  Flash Region 4 (Platform Data): 00fff000 - 00000fff (unused)

Copy the binary blobs to the build directory of coreboot.

$ mkdir -p ~/T430/coreboot/3rdparty/blobs/mainboard/lenovo/t430
$ mv flashregion_0_flashdescriptor.bin ~/T430/coreboot/3rdparty/blobs/mainboard/lenovo/t430/descriptor.bin
$ mv flashregion_2_intel_me.bin ~/T430/coreboot/3rdparty/blobs/mainboard/lenovo/t430/me.bin
$ mv flashregion_3_gbe.bin ~/T430/coreboot/3rdparty/blobs/mainboard/lenovo/t430/gbe.bin

Coreboot Configuration

cd ~/T430/coreboot/
make nconfig
general
    - [*] Compress ramstage with LZMA
    - [*] Include coreboot .config file into the ROM image
    - [*] Allow use of binary-only repository
    - [*] Use CMOS configuration values
mainboard
    -  Mainboard vendor (Lenovo)
    -  Mainboard model (ThinkPad T430)
    -  ROM chip size (12288 KB (12 MB))
    -  (0x100000) Size of CBFS filesystem in ROM
chipset
    - [*] Enable VMX for virtualization
    -  Include CPU microcode in CBFS (Generate from tree)
    -  Flash ROM locking on S3 resume (Don't lock ROM sections on S3 resume)
    - [*] Add Intel descriptor.bin file
      (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin) Path and filename of the descriptor.bin file
    - [*] Add Intel ME/TXE firmware
      (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/me.bin) Path to management engine firmware
    - [*] Add gigabit ethernet firmware
      (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/gbe.bin) Path to gigabit ethernet firmware
devices
    - [*] Use libgfxinit initialization
display
    - Framebuffer mode (Linear "high-resolution" framebuffer)
generic drivers
    - [*] Support Intel PCI-e WiFi adapters
    - [*] PS/2 keyboard init
console
    - [*] Squelch AP CPUs from early console.
      [*] Show POST codes on the debug console
system tables
    - [*] Generate SMBIOS tables
payload
    - Add a payload (SeaBIOS)
    - SeaBIOS version (master)
    - (3000) PS/2 keyboard controller initialization timeout (milliseconds)
    - [*] Hardware init during option ROM execution
    - [*] Include generated option rom that implements legacy VGA BIOS compatibility
    - [*] Use LZMA compression for payloads
    - Secondary Payload
        - [*] coreinfo
        - [*] Memtest86+
        - [*] nvramcui
debugging
    - (nothing checked)

Compile and flashing

When you have exit themenuconfig tool, type:
$ make

This will provide thecoreboot.rom in the folder build/.

Split into Top and Bottom ROM

As two individual flash chips are used to form a virtual 12M BIOS chip, we have to split the generated ROM:

dd if=build/coreboot.rom of=build/coreboot-bottom.rom bs=1M count=8
dd if=build/coreboot.rom of=build/coreboot-top.rom bs=1M skip=8

The file coreboot-bottom.rom belongs into chip #1, located close to the sysboard’s HDD SATA Connector.
The file coreboot-top.rom belongs into chip #2, located between chip #1 and the SATA Connector of the CD/DVD-Slot.

Flash the ROM

sudo flashrom --programmer ch341a_spi --write coreboot-bottom.rom -c "MX25L6406E/MX25L6408E"
sudo flashrom --programmer ch341a_spi --write coreboot-top.rom -c "MX25L3205D/MX25L3208D"

Done!

Remember to clean up the folder util/ifdtool/ by removing binaries or by creating a backup, i.e.:

cd coreboot/util/ifdtool  
mkdir backup-t430  
mv \*.bin backup-t430

Don’t forget to reset the checksum of your NVRAM Option Table to zero by unplugging the small coin battery for some seconds.

Update coreboot via internal flasher

You don’t want to disassemble the whole laptop only for an update of coreboot. Luckly flashrom has an internal flasher:

sudo flashrom -p internal:laptop=force_I_want_a_brick -w coreboot.rom

More information and helpful links