Skip to content

kernel-tye/T420-Coreboot-Usermanual

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Thinkpad T420 coreboot + SeaBIOS guide

This is a guide on externally flashing coreboot + SeaBIOS payload onto a Lenovo Thinkpad T420. If you do not have a T420, some stuff in this guide may apply, however safer alternatives like skulls and Ivyrain also exist for other models. Flashing can be done with either a CH341A USB programmer + Linux, or a SOIC8 Clip + Jumper Wires + Raspberry Pi (RPi).

Materials Needed

  • Thinkpad T420
  • PH0 screwdriver
  • Basic Linux skills
  • Raspberry Pi running Raspbian (Note: Flashing is easier on Raspbian as the GPIO pins, SPI, and I2C are easily configurable. If you are running another distribution, you may require additional configuration)
  • Female to Female Dupont Jumper wires (Note: Not necessary if using a CH341A USB below)
  • SOIC8 Clip (Note: The Pomona clip is the most reliable, however cheaper alternatives like a CH341A USB programmer work just as fine. I used these SDK08 clips)
    • If you plan to use a CH341A programmer, you do not need to follow many of the instructions directed to RPi users
  • Another computer to build coreboot on (Note: coreboot can be compiled on the Raspberry Pi, but it will take many hours and even days to compile. I highly recommend using another linux machine. I used a virtual machine running Debian)

Raspberry Pi Setup

Before connecting any pins to the chip, the coreboot environment must be set up. Log into your Raspberry Pi either headless or with a display connected. Run

$ sudo raspi-config

to open up the RPi config menu. Open the 3 Interface Options choice on the first page. The following menu will appear:

raspi-config config menu

Enable I4 SPI and I5 I2C. If you are running the RPi headless, also enable I8 Remote GPIO. Exit the menu when done.

The flashrom utility is also required, which can be installed by

$ sudo apt install flashrom

Once flashrom is installed, you can sudo poweroff and disconnect power to the RPi.

Disassembly

Unfortunately, accessing the EEPROM chip requires basically a full disassembly of the laptop. The chip is underneath the magnesium structure protecting the motherboard, and sits just below the trackpad. Fortunately, Lenovo has an excellent T420 hardware maintenance manual with diagrams of the disassembly process.

When you have fully disassembled the laptop, you should have access to the chip. The below red arrow indicates the chip.

Picture of motherboard with arrow pointing to eeprom chip

Attaching wires

Note: DO NOT CONNECT JUMPER WIRES WHILE THE RPi IS POWERED ON. ENSURE THE RPi IS OFF BEFORE CONNECTING WIRES
The model of the chip is written on the EEPROM, for the T420, the chip is the Macronix MX25L6406E, the specsheet gives the pinout for the chip. (Note: the black dot is the physical indentation on the chip, not the painted pink dot)

Following flashrom's suggestions for pin connections, the final pins to connect with jumpers and clips are as shown in the table and accompanying diagram:

EEPROM PIN # EEPROM PIN HEADER RPi PIN #
1 CS# 24
2 SO 21
3 WP# See below
4 GND 25
5 SI 19
6 SCLK 23
7 HOLD# See below
8 VCC 17

diagram

For pins 3 and 7 (WP# and HOLD#), flashrom says the following:

In general the other pins (usually pin 3 is /WP and pin 7 is /HOLD) should be connected to Vcc unless they are required to be floating or connected to GND (both extremely uncommon for SPI flash chips). Please consult the datasheet for the flash chip in question.

However, you may encounter the issue where you run out of 3V3 pins to connect. In this case, it's best to connect pins 3 and 7 to any ground (GND) pins on the RPi. I was able to flash successfully while not connecting anything to pins 3 and 7, but YMMV, and it is better to connect to ground.

If you are running raspbian, you can enter the command

$ pinout

and get a similar diagram as the one shown above. Additionally, pinout.xyz has a more friendly-looking layout of the pins.

If using a CH341A USB programmer, you do not need to worry about pinouts, simply clip the chip such that the colored wire aligns with the first pin (indicated by the physical black indent on the chip) and ensure the clip is secure.

Reading and build prep

Once all the pins are connected, connect power to the RPi. To test if chip is detected, run the command:

$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 
...
Found Macronix flash chip "MX25L6406E/MX25L6408E" (8192 kB, SPI) on linux_spi.

flashrom should automatically detect the chip and its model number. If the chip is not detected, check the following:

  • Make sure the clip(s) have a secure connection to the RPi
  • Ensure that the SPI, I2C and GPIO configuration are done correctly
  • Run sudo apt upgrade and reboot the RPi

Create a folder to store the rom backups in a location of your preference with mkdir and cd to that folder. Then read the contents of the chip to a file with

$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c "chipname" -r filename
...
Reading flash... done.

replacing chipname with the chip name that flashrom previously detected (in my case, chipname= MX25L6406E/MX25L6408E) and replacing filename with the name of the output file where the read contents will be stored.

Note the reading process may take a few minutes. If you would like to speed it up, you can change the spispeed= value, say to 1024 instead of 512. Generally slower speeds are more reliable, but I haven't had any issues with 512 or 1024. I'll stick to 512 for now.

Optionally, you can add the -V verbose option at the end to print more debug messages.


Read the chip three times, saving the contents of the chip to three different files. After reading, calculate the MD5 sum of the files. My files saved to files romcopy1.bin, 2, 3, so I would run

$ md5sum romcopy1.bin romcopy2.bin romcopy3.bin
75a3a3a4b3fa5231850a806f2ff5d0a6  romcopy1.bin
75a3a3a4b3fa5231850a806f2ff5d0a6  romcopy2.bin
75a3a3a4b3fa5231850a806f2ff5d0a6  romcopy3.bin

If the md5 sums of all the files do not match, DO NOT CONTINUE. This means you got a bad read, and you need to recheck your pin connections and make sure all connections are secure and stable, and you need to reread and check the MD5 sums.

(Optional) Intel ME Cleaner

Optionally, you can clean the Intel Management Engine from your coreboot build using me_cleaner. If you don't already have git, install it with sudo apt install git, then run the following:

$ git clone https://github.com/corna/me_cleaner
$ python ./me_cleaner/me_cleaner.py -S pathtoinputfile -O pathtooutputfile

replacing pathtoinputfile with the path to one of the original rom copies, and replacing pathtooutputfile with the path to the cleaned rom copy that me_cleaner will create. Note: you may need to run the second command with sudo if you get a permission error.

(Optional) Alias flashrom

If typing the same line over and over is tedious, you can create an alias for it, for example:

$ alias flashromalias='flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512'

Then test it by running

$ flashromalias
...
Found Macronix flash chip "MX25L6406E/MX25L6408E" (8192 kB, SPI) on linux_spi.

which will run the alias. The alias will be erased after rebooting, and you need to set it again to use it. The commands in this guide will not use the alias

Configuration prep

On the second (hopefully more powerful) Linux computer, a few more tools are needed for coreboot to compile correctly.

For Debian based distros:

$ sudo apt-get install -y bison build-essential curl flex git gnat libncurses5-dev libssl-dev m4 zlib1g-dev pkg-config

For Arch-based distros:

$ sudo pacman -S base-devel curl git gcc-ada ncurses zlib

Change directory into a folder you would like to put the coreboot environment in, then clone the coreboot repo with:

$ git clone --recursive https://review.coreboot.org/coreboot.git

Then, change directory to the ifdtool directory and install the ifdtool

$ cd ./coreboot/util/ifdtool
$ sudo make install

The ifdtool is used to seperate the existing rom into 4 flash regions. Therefore we need to transfer a copy of the rom to our second computer. If you use me_cleaner, you should transfer the cleaned copy. You can use a flash drive, or a program such as scp to transfer over network. If you plan to compile on a RPi, you can ignore the above.

Once you have the rom binary on the computer you will compile coreboot on, change directory to the folder with the rom binary and run the ifd tool. For my cleaned rom, I ran

$ ifdtool -x rom_cleaned.bin
$ ls
flashregion_0_flashdescriptor.bin  flashregion_3_gbe.bin
flashregion_1_bios.bin             rom_cleaned.bin   
flashregion_2_intel_me.bin

Only the flashdescriptor, intel_me, and gbe files are needed. Rename the files so that coreboot can autodetect the files when we move them.

$ mv flashregion_0_flashdescriptor.bin descriptor.bin
$ mv flashregion_2_intel_me.bin me.bin
$ mv flashregion_3_gbe.bin gbe.bin

These files need to be in the coreboot/3rdparty/blobs/mainboard/lenovo/t420 folder. Make the folders and move the renamed files to the folder. In my case, my renamed files were in my home directory, so I did

$ cd coreboot/3rdparty/blobs
$ mkdir -p mainboard/lenovo/t420/
$ cd mainboard/lenovo/t420
$
$ mv ~/descriptor.bin ./
$ mv ~/me.bin ./
$ mv ~/gbe.bin ./

Configuration and Compiling coreboot

cd back to the top of the coreboot directory and open the coreboot config menu:

$ cd ~/coreboot
$ make nconfig

An interactive nconfig menu will appear. Look through all the choices in all the menus and select the ones I have here. This config is a pretty minimal just-get-it-working build, and you can add more config options if wanted.

General Setup --->
    Compiler to use (GCC) --->
    [*] Build a separate romstage
    [*] Include the coreboot .config file into the ROM image
    [*] Create a table of timestamps collected during boot
    [*]  Print the timestamp values on the console
    [*] Allow use of binary-only repository

Mainboard --->
    Mainboard vendor (Lenovo) --->
    Mainboard model (Thinkpad T420) --->

Chipset --->
    [*] Enable VMX for virtualization
    [*] Set IA32_FEATURE_CONTROL lock bit
    [*] Lock the AES-NI emablement state
        Include CPU microcode in CBFS (Generate from tree) --->
    [*] Enable ECC if supported
    [*] Lock down chipset in coreboot
    [*] Beep on fatal error
    [*] Flash LEDs on fatal error

    [*] Add Intel descriptor.bin file
        (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin) Path and filename of the descripto
    [*] Add Intel ME/TXE firmware
        (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/me.bin) Path to management engine firmware
    [*] Add gigabit ethernet configuration
        (3rdparty/blobs/mainboard/$(MAINBOARDDIR)/gbe.bin) Path to gigabit ethernet configuration

Devices --->
    Graphics initialization (Use libgfxinit) --->
    Early (romstage) graphics initialization (None) --->
    [*] Allow coreboot to set optional PCI bus master bits
    [*] Any devices
    [*] Enable PCIe Clock Power Management
    [*] Enable PCIe ASPM L1 SubState
    [*] Enable PCIe Hotplug Support
    [*] Add a Video BIOS Table (VBT) binary to CBFS
        (sec/mainboard/$(MAINBOARDDIR)/data.vbt) VBT binary path and filename
    [*] Allocate resources from top down

Generic Drivers --->
    [*] PS/2 keyboard init
    [*] Support Intel PCI-e WiFi adapters
    [*] Support MediaTek PCI-e WiFi adapters

Payload ---> 
    [ ] Don't add a payload
        Payload to add (SeaBIOS) --->
        SeaBIOS version (master) --->
    [*] Hardware init during option ROM excecution
    [*] Hardware Interrupts
    [*] Include generated option rom that implements legacy VGA BIOS compatibility
    [*] Use LZMA compression for secondary payloads
    Secondary Payloads --->
        [*] Load coreinfo as a secondary payload
        [*] Load Memtest86+ as a secondary payload
        [*] Load nvramcui as a secondary payload
        [*] Load tint as a secondary payload

Hit F6 to save the config to /coreboot/.config. Then exit with F9.

Compiling coreboot

Coreboot needs a cross-compiler to compile the rom for the destination hardware. Fortunately, coreboot provides one. To build the gcc cross-compiler toolchain, cd to the coreboot directory and run

$ make crossgcc-i386 CPUS=$(nproc)

This may take a significant amount of time if you are using a RPi or if you forget to allocate more threads to building the toolchain. Once that's done, you can compile:

$ make CPUS=$(nproc)

After the compiling is done, the final coreboot.rom image you will flash on your chip is located at coreboot/build/coreboot.rom. Move this file back to a directory on the RPi using a flash drive or scp as explained earlier.

Flashing coreboot

Before writing to the chip, read and verify the MD5 sums one more time to ensure a secure connection. Then, when you are ready to flash, navigate to the directory with the coreboot.rom file and run

flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -c "MX25L6406E/MX25L6408E" -w coreboot.rom -V

When the writing process is done, sudo poweroff the RPi and disconnect power, then remove the clip from the chip. Reassemble the laptop until the keyboard is attached and poweron. If all went well, the laptop will boot op to the SeaBIOS splash screen.

About

T420-Coreboot-Usermanual

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors