Thanks for your interest in Lenovo X220 port. Issues:
- no MRC cache (longer boot time)
- yellow USB port isn't powered in power-off state.
- Badly seated RAM may prevent booting (not really a problem but coreboot is more suspicious to this than vendor BIOS)
Tested (and works):
- RAM module combinations of 4G+0, 4G+4G, 8G+8G
- S3 (Suspend to RAM)
- Digitizer on x220t variant
- WLAN (first minipcie slot)
- Linux (through GRUB-as-payload)
- Fn hotkeys
- Video (internal, VGA and Displayport, including native gfx init)
- Battery indicator
- Fingerprint reader
- Thermal management
- Expresscard slot (including hotplugging)
- USB (all 3 ports)
- SD card slot
- Sound (integrated speakers, integrated mic, external headphones, external mic)
- WLAN slot USB
- Windows (through SeaBIOS; you have to use extracted VGA blob, dumped from memory isn't good enough)
- msata (second minipcie slot)
- dock (Mini Dock Series 3 TYPE 4337 tested)
- USB 3.0 in some models (probably doesn't work)
proprietary components status
- CPU Microcode
- VGA option rom (optional): you need it if you want graphics in SeaBIOS but most payloads should work without it (text mode or corebootfb mode), SeaBIOS works with coreboot native gfx init
- ME(Management Engine) => you do not have to touch it(just leave it where it is), but you can use a 1.5MB one from a sandybridge chromebook, to save some space
- EC(Embedded Controller) => you do not have to touch it(just leave it where it is)
X220 has 1 flash chip of 8M. It's subdivided in roughly in 3 parts:
- Descriptor (12K)
- ME firmware (5M-12K)
- System flash (7M)
ME firmware is not readable. Vendor firmware locks the flash and so you need to flash externally (unless until someone figures out a way around it).
Proceeds as follows:
- Turn off your laptop, remove battery and AC adapter.
- Remove the keyboard.
- Lift the left side of the plating (see pictures above)
- Connect your external SPI flasher to the top SPI chip (pictured). It's a 8M chip. The chip is layout is as so:
Screen (furthest from you) __ MOSI 5 --| |-- 4 GND CLK 6 --| |-- 3 N/C N/C 7 --| |-- 2 MISO VCC 8 --|__|-- 1 CS Edge (closest to you)
I recommend using SOIC clip, you can find a decent one from Pomona online. Depending on the flasher you use, you may have to use separate 3.3V source. Make sure not to feed more than 3.3V to the chip. You can use any device such as Raspberry Pi, BeagleBoard or Buspirate -- the latter being the slowest. For how to wire up the clip, see this guide (just for the setup). Then connect the clip to the chip, aligning it with the diagram above.
- Read the flash. Twice. Compare the files to be sure. Save a copy of it on external media.
flashrom -c "<yourchipname>" -p <yourprogrammer> -r flash.bin flashrom -c "<yourchipname>" -p <yourprogrammer> -r flash2.bin diff flash.bin flash2.bin
If they don't match, do not proceed.
- Recover descriptor and me firmware; you can use dd:
dd if=flash.bin of=coreboot/3rdparty/blobs/mainboard/lenovo/x220/descriptor.bin \ count=12288 bs=1M iflag=count_bytes dd if=flash.bin of=coreboot/3rdparty/blobs/mainboard/lenovo/x220/me.bin \ skip=12288 count=5230592 bs=1M iflag=count_bytes,skip_bytes
Or a much simpler solution is to just use ifdtool (coreboot/util/ifdtool, you may need to compile it):
ifdtool -x </path/to/extracted/flash.bin>
Which will give you your flashdescriptor, bios, intel_me and gbe .bin files.
- Compile coreboot. Before you do this, you will need to make a folder for the .bin files and copy them there:
cd </path/to/coreboot> mkdir -p 3rdparty/blobs/mainboard/lenovo/x220 cd 3rdparty/blobs/mainboard/lenovo/x220 cp </path/to/flashregion_0_flashdescriptor.bin> descriptor.bin cp <flashregion_2_intel_me.bin> me.bin cp <flashregion_3_gbe.bin> gbe.bin
- Follow the Build HOWTO page and flash the resulting build/coreboot.rom
If you have trouble reading the chip successfully, the most common problems are
- insufficient power supply
- bad contacts
- too long wires
- bad pinout
The cable shipped with buspirate was too long, and needed to be trimmed.
flashing over existing coreboot payloads
Once you are running coreboot any subsequent flashes can be done internally, however you will have to force flashrom:
flashrom -c "<yourchip>" -p internal:laptop=force_I_want_a_brick <-r/-w> file.rom
See also In-System Programming
Bigger SPI ROM
Soldering in a bigger SPI ROM from the same manufacturer with the same specs except for size just works. I used a Winbond W25Q128FVSG and flashed the existing coreboot ROM for a 64mbit chip, due to the way the Intel Flash Descriptor works it still boots with a smaller image. For soldering I recommend a heat soldering gun. Disassemble the whole device, so the plasic doesn't melt, you could try using tin foil to protect the case and other components so you do not have to disassemble everything, but I do not recommend this, especially considering how easy it is to disassemble a thinkpad. If you try the tinfoil method and do not take the speakers out of the case they WILL melt. It looks like lenovo used lead free solder, so this will take a while until the solder is hot enough. Be careful not to heat the surrounding elements, you could accidentally dislodge them. CAREFULLY lift the chip, if the solder is not fully molten on both sides and you apply too much force, you will damage the board.
To actually benefit from the bigger chip you need to modify the Intel Flash Descriptor. There are two changes you need to make:
1. Change the flash layout to encompass the whole chip.
2. change the chip density in the descriptor to the new size.
You can do both with ifdtool, as long as it is recent enough. (I patched it to do 2. in early march 2016)
For 1. run `ifdtool --layout layout.txt coreboot.rom`, edit the layout file and update it with `ifdtool --newlayout layout.txt coreboot.rom`. You may need to remove the overlap check in ifdtool as somehow that sometimes fails and prevents you from changing the layout. Make sure you run this on an actual image, not just the 4kb descriptor or ifdtool will segfault, as it tries to actually move the sections, not just change the layout in the header. In this case also pad the file to 16MB as we're increasing the size, this is not needed if you change to a smaller chip.
00000000:00000fff fd 00500000:00ffffff bios 00003000:004fffff me 00001000:00002fff gbe 00fff000:00000fff pd 00fff000:00ffffff res1 00fff000:00ffffff res2 00fff000:00ffffff res3 00000000:00a0bfff ec
if you use a smaller ME than the stock 5MB one you can also reduce the size of the me area:
00000000:00000fff fd 00183000:00ffffff bios 00003000:00182fff me 00001000:00002fff gbe 00fff000:00000fff pd 00fff000:00ffffff res1 00fff000:00ffffff res2 00fff000:00ffffff res3 00000000:00a0bfff ec
Layout of this file is:
<start address>:<end address> <section name>
Start addresses need to end in 000 and end addresses in fff, due to the way the addresses are stored in the IFD. Note that the fd section needs to be at the start. Ignore pd, res[1,2,3] and ec.
This should result in a coreboot.rom.new file.
2. Run `ifdtool -D 16 coreboot.rom.new` to change the chip density to 128mbit. You can select a chip using -C but this doesn't matter because if there is no second chip the density is ignored and you cannot set it to 0 in this version of the IFD.
Soldering in a second SPI chip doesn't just work because lenovo was cheap and left out a few required resistors, if you are up for an adventure you can try soldering them also in, but they are tiny smd ones. Theoretically should work.
Now you can extract the new IFD (first 4k bytes) from the (probably now broken) coreboot image and build a new Image using it.
Now you can flash it externally as internal flashing doesn't work with an IFD smaller than the chip present. From now on internal flashing should work.
All of these steps can be done beforehand or on a different computer, but I did it in this order because I only got that one laptop and a raspberry pi for external flashing.