#+TITLE: Coreboot for x230
#+DESCRIPTION: Getting Coreboot onto Lenovo x230
#+TAGS: Coreboot
#+TAGS: GNU/Linux
#+TAGS: BIOS
#+TAGS: Hardware
#+TAGS: Levnovo
#+TAGS: x230
#+TAGS: Raspberry-Pi
#+DATE: 2017-01-31
#+SLUG: coreboot-x230
#+LINK: coreboot https://www.coreboot.org
#+LINK: lenovo-x230 http://shop.lenovo.com/us/en/laptops/thinkpad/x-series/x230/
#+LINK: wiki-bios https://en.wikipedia.org/wiki/BIOS
#+LINK: seabios https://www.seabios.org/SeaBIOS
#+LINK: tianocore http://www.tianocore.org/
#+LINK: memtest http://www.memtest.org/
#+LINK: ddg-whitelist-bios https://duckduckgo.com/?q=lenovo+whitelist+bios
#+LINK: wiki-intel-amt https://en.wikipedia.org/wiki/Intel_Active_Management_Technology
#+LINK: flashrom https://www.flashrom.org/Flashrom
#+LINK: raspberry-pi-2 https://www.raspberrypi.org/products/raspberry-pi-2-model-b/
#+LINK: sparkfun-soic-clip https://www.sparkfun.com/products/13153
#+LINK: ebay https://eBay.com
#+LINK: amazon-cables https://www.amazon.com/Elegoo-120pcs-Multicolored-Breadboard-arduino/dp/B01EV70C78
#+LINK: amazon-opening-tools https://www.amazon.com/Professional-Non-Abrasive-Spudgers-Anti-Static-Tweezers/dp/B00PHNMEMC
#+LINK: myfixguide-lenovo-x230 http://www.myfixguide.com/manual/lenovo-thinkpad-x230-disassembly-clean-cooling-fan-remove-keyboard/
#+LINK: ifixit-x230 https://www.ifixit.com/Device/Lenovo_Thinkpad_x230
#+LINK: raspberry-pi-gpio-data-sheet http://www.raspberrypi-spy.co.uk/wp-content/uploads/2014/07/Raspberry-Pi-GPIO-Layout-Worksheet.pdf
#+LINK: alldatasheet http://www.alldatasheet.com
#+LINK: alldatasheet-MX25L3208EM2I12G http://html.alldatasheet.com/html-pdf/575458/MCNIX/MX25L3208EM2I12G/1149/7/MX25L3208EM2I12G.html
#+LINK: coreboot-build-howto https://www.coreboot.org/Build_HOWTO
#+LINK: coreboot-downloads https://www.coreboot.org/downloads.html
#+LINK: coreboot-downloads https://www.coreboot.org/downloads.html
#+LINK: ericholzbach-x230-coreboot https://www.ericholzbach.net/blog/x230_coreboot/
#+LINK: flashrom-spi https://www.flashrom.org/ISP
#+LINK: coreboot-irc irc://irc.freenode.net/coreboot
#+LINK: freenode https://freenode.net/
#+LINK: coreboot-mailinglist https://www.coreboot.org/Mailinglist
#+ATTR_HTML: :align center
#+HTML:
#+BEGIN_PREVIEW
In this post, we will go through the steps to get [[coreboot][coreboot]]
compiled and installed on a [[lenovo-x230][Lenovo x230]] laptop. This is a
somewhat lengthy and involved process that is not for the faint of heart. /It
is very possible to ruin or otherwise brick your laptop performing these steps
improperly or even properly!/ You have been warned.
#+END_PREVIEW
** Coreboot
#+BEGIN_QUOTE
coreboot is an extended firmware platform that delivers a lightning fast and
secure boot experience on modern computers and embedded systems
--[[coreboot][coreboot project]]
#+END_QUOTE
Coreboot is an OpenSource firmware alternative that supports a number of modern
computers and embedded systems. It can replace your system's
[[wiki-bios][BIOS]] with a faster and more secure platform. It can be preloaded
with a number of payloads, e.g., [[seabios][SeaBIOS]] or
[[tianocore][tianocore]], and/or it can come with some additional payloads,
e.g., [[memtest][memtest86+]].
** Motivation
Why replace the default BIOS image in the first place? There are several
motivations for doing this. For one, it's [[ddg-whitelist-biso][well
documented]] that Lenovo installs a device whitelist onto its systems,
disabling the computer if a third-party peripheral is installed, which can
include WiFi cards and SSD's. If you're more adventurous and want to replace
the x230 screen with that of an x240, the whitelist will also get in the way.
By replacing the BIOS entirely, this whitelist problem will be avoided.
Furthermore, in older laptops, x200/1 for example, it's possible to replace the
disastrous [[wiki-intel-amt][Intel ME]] platform. This is, unfortunately,
(currently) impossible on the x230 and later. That is, removing the ME code
will make the laptop effectively unusable.
** Necessary Equipment
Before we go into the actual steps, let's take a moment to gather all the
necessary equipment. Disassembly is necessary because the BIOS chip is locked
and not accessible from software flashers like [[flashrom][flashrom]].
However, desoldering will not be necessary.
- SPI Flash Programmer
This guide will perform the ROM flashing via the GPIO headers of a
[[raspberry-pi-2][Raspberry Pi 2]] (RPI-1 should work, but different pinouts
are required).
- [[sparkfun-soic-clip][SOIC-8 Clip]]
This clip will be used for interfacing with the BIOS chip and the SPI
programmer. They are sometimes available for less (with longer shipping
times) from [[ebay][eBay]].
- Some [[amazon-cables][/short/ cables]]
These cables will connect the SOIC chip to the GPIO headers of the Raspberry
Pi. It is important that they are short, no more than 25cm or so.
- [[amazon-opening-tools][Plastic opening tools]]
After not having these for too long, I can't recommend these enough for
opening up laptops and other devices.
- A precision Phillips screwdriver
A percision set will be better, used for disassembling the laptop.
- A magnifying lens
The specific chip found in /your/ x230 may be different from mine. A
magnifying lens will be helpful in determining the exact version.
** Disassembly and BIOS Access
[[myfixguide-lenovo-x230][Steps]] and [[ifixit-x230][manuals]] for
disassembling the laptop can be found with a simple search. However, it's only
necessary to remove the keyboard and the palm rest to gain access to the BIOS
chip. Of course, remove the battery and power supply before opening the
laptop. I personally, removed the hard drive and WiFi card as well, I wanted
nothing attached while working.
#+ATTR_HTML: :align center
#+HTML:
You will notice there are two chips in the above figure. The combination of
these two chips is what makes up the BIOS (and the Intel ME) for the x230. /We
will be dealing exclusively with the /top/ chip/ (one closest to the screen).
Once we have physical access to the top chip, use the magnifying glass to read
the /tiny/ print of the chip. We need to know the precise version of the chip
to remove any future guesswork from the process, especially for disaster
recovery.
If you are unable to read the version of the chip, there are steps we can take
to proceed, but it will be far more tedious and less comfortable.
*** Connecting the Raspberry Pi to the SOIC Clip
Next, we will be connecting the Raspberry Pi with the cables and clips to the
BIOS chip.
#+BEGIN_QUOTE
I found this to be the most difficult of the entire process. Finding a solid
source for the documentation on the chip and the GPIO headers was incredibly
difficult the first time around.
#+END_QUOTE
First, get [[raspberry-pi-gpio-data-sheet][GPIO header diagram]] for your
Raspberry Pi model.
Next, cross-reference the header diagram with your chip's spec sheet. It
should be in the list at [[alldatasheet][All Data Sheet]]. Specifically, I
found mine [[alldatasheet-MX25L3208EM2I12G][here]]. It's very likely, yours
will be similar. Cross reference the "Pin Configuration" page with the GPIO
header diagram to discern the proper connections.
The pin arrangement that I used was the following (using the notch on the chip
for starting):
- 1: GPIO 26
- 2: GPIO 19
- 3: Not Connected
- 4: GPIO 17
- 5: GPIO 21
- 6: GPIO 23
- 7: Not Connected
- 8: GPIO 25
*** Using the Raspberry Pi
#+ATTR_HTML: :align center
#+HTML:
#+BEGIN_QUOTE
Before connecting the clip, it's imperative to remove all external power
sources. The Raspberry Pi will be providing power to the ROM chip, any
external current can and most likely /will/ brick your laptop.
#+END_QUOTE
Attach the clip to the chip and power on the Raspberry Pi. Before you are able
to read the chip, you may need to install [[flashrom][flashrom]] and ensure
your kernel has SPI enabled. Most distributions will have it on by default. An
easy way to check is to list the contents of ~/dev~ and look for ~spi~ devices,
since the chip is connected, there should be one.
Before we begin the process of flashing, let's inspect the ROM itself. First,
simply run flashrom, specifying the SPI device as the programmer:
#+BEGIN_EXAMPLE
# flashrom --programmer linux_spi:dev=/dev/spidev0.0
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
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 linux_spi.
Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on linux_spi.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
Found Macronix flash chip "MX25L3273E" (4096 kB, SPI) on linux_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 option.
#+END_EXAMPLE
#+BEGIN_QUOTE
If you are seeing numbers like 8192 kB, you're reading the wrong chip!
Disconnect and attach to the other.
#+END_QUOTE
If you were able to read the chip number, pass it along, and try again:
#+BEGIN_EXAMPLE
# flashrom --programmer linux_spi:dev=/dev/spidev0.0 \
--chip "MX25L3206E/MX25L3208E"
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
#+END_EXAMPLE
Now, we will want to create a back up image of the ROM, but we also want to
verify we are reading correctly:
#+BEGIN_EXAMPLE
# flashrom --programmer linux_spi:dev=/dev/spidev0.0 \
--chip "MX25L3206E/MX25L3208E" \
--read original.1.rom
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
Reading flash... done.
# flashrom --programmer linux_spi:dev=/dev/spidev0.0 \
--chip "MX25L3206E/MX25L3208E" \
--read original.2.rom
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
Reading flash... done.
# diff original.1.rom original.2.rom
#+END_EXAMPLE
#+BEGIN_QUOTE
Again, if the size of ~original.1.rom~ and ~original.2.rom~ are 8MB, you're
reading the wrong chip, move the clip to the other chip and repeat the above
steps!
#+END_QUOTE
If you get no output from the last command, we should be set, or it means we're
reading both incorrectly. However, it's more likely flashrom will complain
first.
Keep at least one of the images around just in case this fails and you need to
attempt recovery.
#+BEGIN_QUOTE
If you were unable to read the serial number off the chip, perform the read 4
to 8 times, once or twice for each chip type.
#+END_QUOTE
** Configuration and Compilation
Half the battle to getting Coreboot onto your system is properly putting
together the build-tools and compiling the coreboot image. There already
exists a [[coreboot-build-howto][guide for configuring and building]] the
Coreboot tool-chain, but for completeness, the basic steps will be copied here.
#+BEGIN_QUOTE
I'll assume a certain comfortability with GNU/Linux and the GNU GCC and Make
tools.
#+END_QUOTE
First up, get a copy of the [[coreboot-downloads][Coreboot Source]]:
#+BEGIN_EXAMPLE
% git clone --recursive https://review.coreboot.org/coreboot.git
#+END_EXAMPLE
This will get the latest source code of the Coreboot project and also
initialize the project's submodules.
Next, we will need to download the blobs archive:
#+BEGIN_EXAMPLE
% curl -SLO https://www.coreboot.org/releases/coreboot-blobs-4.5.tar.xz
#+END_EXAMPLE
#+BEGIN_QUOTE
The link can be found from the
[[coreboot-downloads][Coreboot Downloads]] page.
#+END_QUOTE
Now, unpack the blobs into the ~coreboot/3rdparty/blobs~ folder:
#+BEGIN_EXAMPLE
% tar -xf coreboot-blobs-4.5.tar.xz --strip-components=1 -C coreboot
#+END_EXAMPLE
Now, we can move onto configuring the tool-chain, building the tool-chain, and
finally building the coreboot image itself.
*** Configuration
#+BEGIN_EXAMPLE
% cd coreboot
#+END_EXAMPLE
We'll start by configuring the compile options for coreboot:
#+BEGIN_EXAMPLE
± make menuconfig
#+END_EXAMPLE
OR
#+BEGIN_EXAMPLE
± make nconfig
#+END_EXAMPLE
Set the following options:
#+BEGIN_EXAMPLE
general --|
|-[*] Compress ramstage with LZMA
|-[*] Include the coreboot .config file into the ROM image
mainboard -|
|-Mainboard vendor (Lenovo)
|-Mainboard model (ThinkPad X230)
|-ROM chip size (12288 KB (12 MB))
|-(0x100000) Size of CBFS filesystem in ROM
devices ---|
|-[*] Use native graphics initialization
generic ---|
|-[*] PS/2 keyboard init
console ---|
|-[*] Squelch AP CPUs from early console.
|-[*] Send console output to a CBMEM buffer
|-[*] Send POST codes to an external device
|-[*] Send POST codes to an IO port
sys table -|
|-[*] Generate SMBIOS tables
payload ---|
|-Add a payload (SeaBIOS)
|-SeaBIOS version (master)
|-(10) 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
#+END_EXAMPLE
These configuration options were borrowed from
[[ericholzbach-x230-coreboot][Unix Blather]].
*** Compilation
#+BEGIN_QUOTE
If you were thinking of compiling the ROM on the Pi, I recommend you
reconsider. If you have an exorbitant amount of time to kill, go for it, but
you'll prefer a machine with more power.
#+END_QUOTE
From here, we can build the tool-chain:
#+BEGIN_EXAMPLE
± make crossgcc-x64 CPUS=$(nproc)
#+END_EXAMPLE
This will only build the tool-chain for the x64 architecture, update as
necessary.
~CPUS=#~ is used to specify the parallelization of the tool-build. This is
unfortunately different from the usual ~--jobs|-j~ argument of ~make~, but has
the same effect.
Now, we can build the coreboot image itself:
#+BEGIN_EXAMPLE
± make -j$(nproc)
#+END_EXAMPLE
This will create ~build/coreboot.rom~ image.
However, this will /not/ be the image we flash onto our laptop! Because the
Lenovo x230 comes with the [[wiki-intel-amt][nasty Intel ME]] and we built the
coreboot image using a stub for the Intel ME section, we need to create a new
image that contains only the Coreboot contents. To do this, we will use ~dd~
to skip the first 8MB of the image, and only grab the last 4:
#+BEGIN_EXAMPLE
± dd if=build/coreboot.rom bs=1M of=/tmp/x230.rom skip=8
#+END_EXAMPLE
This will create a 4MB file in ~/tmp/~ named ~x230.rom~. Finally, copy the new
image to the Raspberry Pi.
** Flashing the New Image
After the image is copied to the Pi, we can use flashrom to write the new
image:
#+BEGIN_EXAMPLE
# flashrom --programmer linux_spi:dev=/dev/spidev0.0
--chip "MX25L3206E/MX25L3208E"
--write /tmp/x230.rom
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
#+END_EXAMPLE
Flashrom will read back the new contents and verify it was successful, however,
I like the comfort of having done this myself. This can be accomplished two
ways: using flashrom's ~--verify~ option, or reading the image and running
~diff~:
#+BEGIN_EXAMPLE
# flashrom --programmer linux_spi:dev=/dev/spidev0.0
--chip "MX25L3206E/MX25L3208E"
--verify /tmp/x230.rom
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
Reading old flash chip contents... done.
Verifying flash... VERIFIED.
#+END_EXAMPLE
OR
#+BEGIN_EXAMPLE
# flashrom --programmer linux_spi:dev=/dev/spidev0.0 \
--chip "MX25L3206E/MX25L3208E" \
--read /tmp/x230.2.rom
flashrom v0.9.9-r1955 on Linux 4.4.10-1-ARCH (armv7l)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on linux_spi.
Reading flash... done.
# diff /tmp/x230.rom /tmp/x230.2.rom
#+END_EXAMPLE
If you get "VERIFIED" or no output, respectively, the contents of the BIOS chip
should be replaced with the Coreboot image.
All that's next is to disconnect the chip, reassemble the laptop and hope it
works!
** Common Problems
If you're having issues flashing or reading your BIOS, check the following:
- The chip is getting sufficient power
- The wires used to connect the Raspberry Pi and the chip are not /too long/
- Make sure your pinout is correct
For some more information, check Flashrom's [[flashrom-spi][in system
programming]].
** Summary and Auxiliary Advice
Hopefully, you're now booting into your x230 with Coreboot. Enjoy your new
BIOS, whitelist free and awesome!
However, if you have issues, e.g., the flashing doesn't go as planned: /DO NOT
POWER OFF THE CHIP!/ Get help from the [[coreboot-irc][#coreboot]] IRC channel
on [[freenode][freenode]] or [[coreboot-mailinglist][email the mailing list]].
** References
- [[coreboot][coreboot homepage]]
- [[lenovo-x230][x230 product page]]
- [[raspberry-pi-2][Raspberry Pi 2 Model B]]
- [[sparkfun-soic-clip][IC Test Clip - SOIC 8-Pin]]
- [[wiki-intel-amt][Intel Active Management Technology Wikipedia Post]]
- [[coreboot-build-howto][Coreboot Build HOWTO]]
- [[coreboot-downloads][Coreboot Downloads]]
- [[flashrom][Flashrom Project Homepage]]
- [[raspberry-pi-gpio-data-sheet][Raspberry Pi GPIO Header Sheet B/B+]]
- [[ericholzbach-x230-coreboot][Unix Blather: Coreboot on the Lenovo x230]]