Librebooting X230

Posted on Sep 29, 2025

I recently got a X230 for free from my dorm’s recycle bin. It has a i5-3360M, MC8355 3G WWAN, BCM20702 WiFi adapter, and comes bootable. Unfortunately, the stock Lenovo firmware has the stupid WWAN / WiFi card whitelist that only accepts a short range of cards, making the laptop unfeasible for daily use.

Luckily, X230 is old enough (Ivy Bridge) to have amazing Libreboot support. Then I think it’s a perfect chance to hack it, especially for me who never flashed BIOS myself before :)

Libreboot Background

If you never heard anything of “Libreboot” or “Coreboot” before, TLDR they are just open-source third-party firmware implementations for computers. For us who hack the personal computers, they are meant to replace the stock, proprietary firmware, although Coreboot is actually the stock firmware for Chromebook’s.

Coreboot is not completely free and contains binary blobs to support a wider range of computers. On the other hand, Libreboot, being a “libre” fork of Coreboot, aims at being completely free from binary blobs. Even though Libreboot does contain some binary blobs, see below.

Coreboot supports UEFI as a payload, where Libreboot does not. I am picking Libreboot at this time because 1) the X230 is not my primary workspace, so I don’t need the advanced security UEFI Secure Boot has to offer; 2) building TianoCore is just too slow; 3) I want to try SeaBIOS on a physical machine other than cloud servers. Both Coreboot and Libreboot has other payloads like SeaBIOS (yeah, the i386 BIOS), Grub (built into the firmware), and U-Boot (yes, U-Boot for your amd64 PC).

TLDR:

  • Libreboot / Coreboot are third-party open-source firmware implementations meant to replace the stock, proprietary firmware.
  • Libreboot is a fork of Coreboot, containing minimal binary blobs, without UEFI support, and lighter. Libreboot still has proprietary blobs.
  • Flashing will wipe the old firmware, its settings, and internal GbE adapter MAC address.

Before continue: Read the Libreboot docs!

This blog post does not provide a comprehensive understanding of Libreboot. It only shows how did I flashed a specific laptop. This post serves as a supplyment to the official docs, which is quite messy and hard to understand for beginners. You must read the official docs before proceeding, or you may brick your device!

Read these first:

Hardware

Considering the hardware, although it is possible to flash Libreboot internally (i.e., without external hardware flasher and jumpers), it is strongly recommended to do it the old way, i.e. use a SPI programmer to flash the firmware chips. I did not attempt the internal flashing model.

ThinkPad X230 comes with two firmware flash chips, 12MiB of storage in total. Simply search “X230 flash BIOS” gives you lots of photos on where to find them. You will find the two chips are aligned vertically:

  1. Top chip: MX25L3206E. 3.3V 4MiB SPI Flash.
  2. Bottom chip: MX25L6406E. 3.3V 8MiB SPI Flash.

It is possible for your X230 to have a slightly different chip model like MX25L3208E instead of MX25L3206E, but they must be 4MiB and 8MiB.

Also, it is important that both chips accept 3.3V only. Many programmers offer 5V, which breaks the chips.

The two chips offer 12MiB combined. Libreboot will also build a 12MiB binary. First 8MiB of the produced binary comes to the bottom flash, while the last 4MiB is for the top.

Overview

Libreboot comes in two parts: the source code and binary blobs. You download both of them and run a script to build Libreboot and inject proprietary blobs. This gives you a 12MiB binary.

To flash, you will need a SOP-8 clip, so you can attach the programmer to the chip without soldering it. A SPI programmer is also required. Besudes traditional SPI programmers, you can also use SoC that has built-in SPI peripherals like Raspberry Pi, or even Flipper Zero would do the trick. I do not have access to a SPI programmer at the time, so I used the Flipper Zero instead.

TLDR what’s needed:

  1. Libreboot source code and build scripts: https://codeberg.org/libreboot/lbmk.git.
  2. X230 binary blobs from Libreboot mirror. Look for libreboot-25.06_x230_12mb.tar.xz. There is also a 16MiB version, which I do not know what is it used for.
  3. A SOP-8 clip. Make sure you test its wiring before connection!
  4. A 3.3V SPI programmer. I am using the Flipper Zero, but others are fine. Do your own research on how to use other programmers and the flashrom(1) utility.
  5. Wires.

Flipper Zero sounds like a toy, but it is quite useful for me when I did not have access to other programmers and only need to flash SPI occasionally. It has 3.3V output and a built-in wiring diagram that allows you to easily identify what to connect.

Note that the internal GbE adapter’s MAC address is determined by the firmware. If you want to preserve the old MAC address, boot before flashing to copy down its MAC address.

Build Libreboot

Place the ROM tar xz whatever you like and go to the cloned lbmk directory.

You may take a look at the contents of the ROM tar. It should contain many DO NOT FLASH YET files. That’s because you need to inject this tar using the mk script inside the source tree. The mk script automatically reads binary blobs inside the ROM tar, builds the Libreboot source code, and combine them together. It will then modify the tar file so the files inside the tar are ready to be flashed.

Then, execute:

# 'mk inject' will:
# 1. Read the tar for proprietary binaries
# 2. Pull Libreboot source from various Git repo and build
# 3. Combine them together
# 4. Write updated files back to the tar and remove DO NOT FLASH YET names.
# You can run 'mk inject' many times on the same source tree / tar.

# Build and set MAC address
$ ./mk inject path/to/libreboot-25.06_x230_12mb.tar.xz setmac 11:45:14:19:19:81

# Build and randomize MAC address
$ ./mk inject path/to/libreboot-25.06_x230_12mb.tar.xz

# Build and randomize partial MAC address
$ ./mk inject path/to/libreboot-25.06_x230_12mb.tar.xz setmac 11:45:14:XX:XX:XX

For more on ‘mk inject’ or MAC address, read Libreboot docs.

Note: The mk script tries to do git-commit(1) while lacks proper support for pinentry. If you have GPG signing enabled for git commits, consider disabling that before running mk inject!

The resulting tar contains the files ready to flash. You only need to pick one, and I picked the seabios_x230_12mb_libgfxinit_corebootfb.rom. You may try others too. Notice the resulting tar no longer has DO NOT FLASH YET labels because they had been removed by the mk script.

All produced binaries are 12MiB. As said before, X230 has a 4MiB chip on the top and a 8MiB chip on the bottom. The first 8MiB of the 12MiB file goes to the bottom chip, so run:

$ dd if=./seabios_x230_12mb_libgfxinit_corebootfb.rom bs=1M skip=8 of=./top.bin
$ dd if=./seabios_x230_12mb_libgfxinit_corebootfb.rom bs=1M count=8 of=./bottom.bin

to split it into two files for flashing.

ThinkPad hardware setup

Before doing anything, disconnect X230 from battery and AC power.

First, open up X230 and find the two chips. Try your best to confirm their labels (they are hard to read!)

Then, confirm their pinout:

           KEYBOARD

     ┌──────────────────┐     
MOSI │5                4│ GND 
     │                  │     
CLK  │6    Top Chip    3│ N/C 
     │                  │     
N/C  │7   MX25L3206E   2│ MISO
     │                  │     
VCC  │8              * 1│ CS  
     └──────────────────┘     

     ┌──────────────────┐     
MOSI │5                4│ GND 
     │                  │     
CLK  │6    Bot Chip    3│ N/C 
     │                  │     
N/C  │7   MX25L6406E   2│ MISO
     │                  │     
VCC  │8              * 1│ CS  
     └──────────────────┘     

       BOTTOM OF LAPTOP

(From https://wiki.chucknemeth.com/laptop/lenovo-x230/flash-lenovo-x230-coreboot)

If the chips are slightly different, don’t panic! If is possible if your chips are MX25L3208E and MX25L6408E, but they must be 4 + 8MiB 3.3V SPI flashes!

Lastly, confirm the pinout of your SOP-8 clip before connecting it. You may use a multimeter or anything you like to test which pin is connected to which wire.

SPI programmer setup (Flipper Zero)

To prepare the Flipper, install SPI Mem Manager. Open this app (from the GPIO directory) and click on its wiring diagram then connect accordingly. Notes:

  1. No need to connect the resistor. Just connect 3.3V from Flipper to the chip.
  2. GND needs to be connected to multiple GND pins from the Flipper.

Backup and Flash

The Flipper GUI is intuitive enough, so I do not need to say too much about it.

If your hardware setup goes well, press “Read” from Flipper, and it will automatically detect the vendor of your SPI flash chip. You still gotta confirm the specific model of your chip.

Read the up and bottom chips at least twice and compare them to see if your results are the same. It is crucial to backup the stock firmware and make sure the SPI read correctly before proceeding! Otherwise you risk breaking the device.

Then, flash the two binary files accordingly. Again, first 8MiB goes to the bottom, and last 4MiB goes to the top.

If everything is perfect, Flipper will show you a nice SUCCESS figure :)

Flash, Libre, Boot!

Boot up your laptop and enjoy your Libreboot. It has a built-in Grub and U-boot, but I have no idea on how to use them and am not planning to use them anytime soon.

The network adapter whitelist should now gone, and I can finally boot my X230 with EG25-G LTE card and a decent 802.11ac WiFi card.

I am having trouble with FreeBSD resolution though. Seems like it is trying to display the console to a very thin range of the screen at the top. I am using Arch Linux now, so this shouldn’t be a problem.

Thanks for reading.

Acknowledgement