Coreboot
Requirements[edit]
- An 8-pin SOIC clip
- A device capable of SPI (I've used a Bus Pirate with good results)
- Flashrom
- A 3.3v power supply (though you can potentially circumvent this requirement)
Setup[edit]
You'll first need to disassemble your laptop to gain access to the EEPROM on the motherboard. First disconnect the battery and remove the AC adapter. After this you need to remove a bunch of screws from the base of the laptop, remove the keyboard by pushing it towards the LCD and prying up its front edge, and finally remove the palm rest and trackpad by prying up the rear edge.
With all of that done you need to peel back the plastic tape beside the ExpressCard slot on the lower left of the board to reveal the EEPROM beneath.
Configuring your SPI flasher and pinouts[edit]
With the EEPROM exposed you'll first need to take a copy of your existing BIOS. To do this first configure your chosen SPI flashing hardware, in this case I'm using a buspirate and so have configured the pinout as so:
Note that pin #1 on the EEPROM (for the x220) is the lower right pin designated by the circle indentation on the face of the chip. The pins read counter-clockwise from 1-8, with the 8 being the lower left pin.
Also I'm using
| BusPirate pin | EEPROM pin |
|---|---|
| CS | 1 (CS) |
| MISO | 2 (MISO) |
| N/A | 3 (WP) |
| Ground (GND) | 4 (GND) |
| MOSI | 5 (MOSI) |
| CLK | 6 (CLK) |
| N/A | 7 (HOLD) |
| N/A | 8 (VCC) |
Connect the BusPirate to your laptop and check that you can see it as a new serial interface.
Powering the EEPROM[edit]
The EEPROM requires a 3.3v source be provided when it's being read from or written to. It's possible to provide this through the pin #8 VCC input, however in my experimenting neither the BusPirate or a raspberry pi were able to provide enough current to the EEPROM for me to achieve stable reads from the device.
One alternative way of powering the EEPROM is to use the AC adapter and onboard power supply. This approach involves using the Wake on Lan functionality of the motherboard to cause it to power the EEPROM without booting the laptop.
You can achieve this powered, but not booted state by doing the following: 1. Plug in the AC adapter 2. Boot the laptop (you'll need to connect the keyboard ribbon to do this) 3. Power the laptop down after it POSTs 4. After it has powered off insert a live (link not PoE) ethernet cable into the RJ45 jack 5. Observe that the link light on the RJ45 jack lights 6. Observe 3.3v between pins 8 and 4 on the EEPROM
At this point the board will supply a good 3.3v voltage to the EEPROM such that you can read from and write to it, without you having to provide the 3.3v from the flashing hardware. Note however that you still need to connect the GND pin (4) to your flashing hardware.
Reading your first EEPROM dump[edit]
With all of the above done you can connect the SOIC clip to the EEPROM and attempt to read the contents using flashrom with the following command
-> sudo flashrom -p buspirate_spi:dev=/dev/ttyUSB0 -r dump00.bin flashrom v0.9.9-r1954 on Linux 4.8.0-2-amd64 (x86_64) flashrom is free software, get the source code at https://flashrom.org Calibrating delay loop... OK. Found Winbond flash chip "W25Q64.V" (8192 kB, SPI) on buspirate_spi. Reading flash... done.
With any luck flashrom will identify the EEPROM chip the first time around and read its contents. If it complains that it can't detect any chip try re-seating the clip onto the EEPROM and ensure that all pins make contact. It can be a bit delicate so try it a few times.
Take two or more consecutive reads and compare their checksums to ensure that you have accurate data.
Building your Coreboot payload[edit]
To build a Coreboot payload you first need to extract various regions from your EEPROM dump to be compiled back into the coreboot build: namely the Intel ME (Intel Management Engine), Intel GBE (Gigabit Engine) and Flash Descriptor regions.
You should follow the Intel Sandybridge Coreboot build documentation for detailed instructions on how to extract these regions using the ifdtool utility included in the coreboot source code.
With that done you should have the following files:
dump00.binflashregion_0_flashdescriptor.binflashregion_1_bios.binflashregion_2_intel_me.binflashregion_3_gbe.bin
You should place these files in the following directory within the coreboot source code
3rdparty/blobs/mainboard/lenovo/x220/descriptor.bin 3rdparty/blobs/mainboard/lenovo/x220/me.bin 3rdparty/blobs/mainboard/lenovo/x220/gbe.bin
Neutralizing the Intel Management Engine[edit]
The Management Engine is an separate co-processor contained within the CPU that has its own direct memory access engine and network access amongst other things. In recent generations the ME has also taken responsibility for certain CPU initialization, without which the CPU shuts down after 30 minutes of use.
The ME is widely viewed as a major obstacle to user-directed security and privacy concerns, but as of late 2016 researchers have found a way to selectively disable certain components of the ME while retaining the critical hardware initialization routines.
Their project is available on Github and can be run as so:
./me_cleaner.py flashrom_2_intel_me.bin
Note that this overwrites the input file with a "cleaned" ME which can be used as an input in the coreboot build process
extracting VGA bios[edit]
While coreboot offers its own graphics initialization code there are some minor stability issues; namely the GPU hiccuping and deciding to show noisy output until you sleep/resume the device.
To avoid this it's possible to extract your original VGA BIOS option ROM from the initial EEPROM dump that you took and compile this blob back into your coreboot and also subsequent coreboot payload ROMS e.g. SeaBIOS
TODO Talk about extracting the VGA BIOS using EUFITool and where to compile it back in.
There exists some documentation on the Coreboot Wiki which should be referenced in the meantime.
Building coreboot cross compilers[edit]
Before you can compile coreboot you'll need to provision your cross-compiler toolchain. Thankfully coreboot includes a makefile target just for this.
If you want to target only your X220 you can make the i386 toolchain only with the following:
make crossgcc-i386 CPUS=$NUMCPUS
which will fetch and compile all the toolchain necessary to build coreboot.
Coreboot configuration and build[edit]
NB: these configuration options are taken from the Coreboot wiki page for Intel Sandybridge Build and are the ones that I've used. Your mileage may vary on different hardware.
With all the components in order it's time to configure your coreboot build.
In the coreboot source directory run the following:
make menuconfig
to enter an interactive configuration prompt.
There are a few things you'll need to change:
- Under "General setup"
- Select "Use CMOS for configuration values"
- Under "Mainboard"
- set your vendor to Lenovo
- set your model to Thinkpad X220
- set your ROM chip size to be 8MB
- Under "Chipset"
- Select "Add Intel descriptor.bin file"
- Select "Add Intel ME/TXE firmware"
- Select "Add gigabit ethernet firmware"
- Under "Devices"
- Select "Use native graphics initialization" if you are not providing your own VGA bios option ROM
With all that done and your toolchain provisioned as above you can build your ROM with make in the coreboot source directory.
Flashing your build[edit]
The coreboot build process will output your final ROM in build/coreboot.rom which you will flash with flashrom as follows:
sudo flashrom -p buspirate_spi:dev=/dev/ttyUSB0 -w build/coreboot.com
This will take a while as flashrom will erase the existing ROM, write the new payload, and then verify that the write was correct by reading it back.