Following up my previous post on installing coreboot on X230, I decided to completely liberate my laptop. The method that I was using only covers the BIOS, leaving the other portion of the laptop firmware would remain untouched. While I would want to let the low-level stuff (e.g. firmwares for the EC, Ethernet, LEDs, etc) as is, I would like to remove the part that activates the Intel Management Engine. To cover for this, the guide on installing Skulls also comes with the method for flashing externally.

For this, I needed:

  • a spare computer running Linux with flashrom installed
  • a CH341a flasher along with SOIC-8 test clip
  • a good screwdriver

I'll be honest with you, my previous attempts with external BIOS flashing have been mostly failures. So to ensure that my tools work properly, I did some kind of dummy run. I happen to have some spare SOIC-8 SPI flash chips (leftover from previous unsuccessful projects).

After clipping it to the test clip, I ran flashrom -p ch341a_spi

flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Macronix flash chip "MX25L6405" (8192 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L6406E/MX25L6408E" (8192 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E/MX25L6473F" (8192 kB, SPI) on ch341a_spi.
Multiple flash chip definitions match the detected chip(s): "MX25L6405", "MX25L6405D", "MX25L6406E/MX25L6408E", "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E/MX25L6473F"
Please specify which chip definition to use with the -c <chipname> option.

Good enough for me!

Without further ado, I made my move inside the laptop chassis. Taking the screws is an easy process. The screw holes are marked for which to remove for what. I only removed the ones that holds the keyboard and the palmrest.

keyboard-palmrest-removed

And... I'm in!

There are two flash chips that holds the firmware. They are covered by a black vinyl cover held together by adhesive. It's sticking quite hard so an adequate force was needed to pull it off the flash chips.

exposing-flash-chips

There we go!

The next tricky part was clipping the test clip to the flash chips. The leads on the chip must be in contact with the leads on the clip, and they're all so tiny. The fact that each chip is mounted and cannot be moved did not help with this process.

attaching-clip

I started by the top chip.

To test whether or not it's connected properly, I simply ran flashrom -p ch341a_spi as root and saw if there's any chip detected. Everytime I need to reseat the clip, I made sure to turn unplug the CH341a from the USB port to turn it off. That way I won't accidentally fry the chip thru improper connection.

flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
No EEPROM/flash device found.
Note: flashrom can never write if the flash chip isn't found automatically.

This took me multiple attempts to get right.

flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q032..3E" (4096 kB, SPI) on ch341a_spi.
No operations were specified.

After getting the above output and reseating the clip several times, I knew I finally hit the right spot.

I then moved on to the flashing process by going into the skulls directory and running ./external_install_top.sh -f ch341a -b x230.

1) ./x230_coreboot_seabios_d5c31acee4_top.rom
2) ./x230_coreboot_seabios_free_d5c31acee4_top.rom
3) Quit
Please select a file to flash or start with the -i option to use a different one:

I typed 1 and pressed enter.

trying to detect the chip...
chip not detected.
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q032..3E" (4096 kB, SPI) on ch341a_spi.
No operations were specified.
Please find it manually in the list above and rerun with the -c parameter.

Quite a cryptic output if you ask me.

I figured out that I needed but to run ./external_install_top.sh -f ch341a -b x230 -c N25Q032..3E -k ../bios-top.img. And after selecting the file to flash:

verifying SPI connection by reading 2 times. please wait.
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q032..3E" (4096 kB, SPI) on ch341a_spi.
Reading flash... done.
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q032..3E" (4096 kB, SPI) on ch341a_spi.
Reading flash... done.
current image saved as ../bios-top.img
connection ok. flashing x230_coreboot_seabios_d5c31acee4_top.rom
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q032..3E" (4096 kB, SPI) on ch341a_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
DONE

Moving on to the bottom chip, which actually contains the ME firmware...

This time, I ran ./external_install_bottom.sh -f ch341a -m -k ../bios-bottom.img -c N25Q064..3E. The process itself is quite similar, tho there's no laptop model or ROM option to choose.

Ok. Connect a CH341A programmer
make: Entering directory '/home/kenno/Project/skulls-1.0.5/util/ifdtool'
gcc -O2 -g -Wall -Wextra -Wmissing-prototypes -Werror -I../commonlib/include -c -o ifdtool.o ifdtool.c
gcc -o ifdtool ifdtool.o
make: Leaving directory '/home/kenno/Project/skulls-1.0.5/util/ifdtool'
Intel ME will be cleaned.
The flash ROM will be unlocked.
Start reading 2 times. Please be patient...
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q064..3E" (8192 kB, SPI) on ch341a_spi.
Reading flash... done.
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q064..3E" (8192 kB, SPI) on ch341a_spi.
Reading flash... done.
current image saved as ../bios-bottom.img
connection ok
start unlocking ...
Full image detected
The ME/TXE region goes from 0x3000 to 0x500000
Found FPT header at 0x3010
Found 23 partition(s)
Found FTPR header: FTPR partition spans from 0x180000 to 0x24a000
ME/TXE firmware version 8.1.0.1265
Public key match: Intel ME, firmware versions 7.x.x.x, 8.x.x.x
The AltMeDisable bit is NOT SET
Reading partitions list...
 ???? (0x000003c0 - 0x000000400, 0x00000040 total bytes): removed
 FOVD (0x00000400 - 0x000001000, 0x00000c00 total bytes): removed
 MDES (0x00001000 - 0x000002000, 0x00001000 total bytes): removed
 FCRS (0x00002000 - 0x000003000, 0x00001000 total bytes): removed
 EFFS (0x00003000 - 0x0000df000, 0x000dc000 total bytes): removed
 BIAL (NVRAM partition, no data, 0x0000add0 total bytes): nothing to remove
 BIEL (NVRAM partition, no data, 0x00003000 total bytes): nothing to remove
 BIIS (NVRAM partition, no data, 0x00036000 total bytes): nothing to remove
 NVCL (NVRAM partition, no data, 0x00010511 total bytes): nothing to remove
 NVCM (NVRAM partition, no data, 0x0000493f total bytes): nothing to remove
 NVCP (NVRAM partition, no data, 0x0000a553 total bytes): nothing to remove
 NVJC (NVRAM partition, no data, 0x00004000 total bytes): nothing to remove
 NVKR (NVRAM partition, no data, 0x0001257d total bytes): nothing to remove
 NVOS (NVRAM partition, no data, 0x00034ab9 total bytes): nothing to remove
 NVSH (NVRAM partition, no data, 0x00007609 total bytes): nothing to remove
 NVTD (NVRAM partition, no data, 0x00001eac total bytes): nothing to remove
 PLDM (NVRAM partition, no data, 0x0000a000 total bytes): nothing to remove
 GLUT (0x000df000 - 0x0000e3000, 0x00004000 total bytes): removed
 LOCL (0x000e3000 - 0x0000e7000, 0x00004000 total bytes): removed
 WCOD (0x000e7000 - 0x000140000, 0x00059000 total bytes): removed
 MDMV (0x00140000 - 0x000180000, 0x00040000 total bytes): removed
 FTPR (0x00180000 - 0x00024a000, 0x000ca000 total bytes): NOT removed
 NFTP (0x0024a000 - 0x0004a4000, 0x0025a000 total bytes): removed
Removing partition entries in FPT...
Removing EFFS presence flag...
Correcting checksum (0xef)...
Reading FTPR modules list...
 UPDATE           (LZMA   , 0x1cc428 - 0x1cc5e6       ): removed
 ROMP             (Huffman, fragmented data, ~2 KiB   ): NOT removed, essential
 BUP              (Huffman, fragmented data, ~56 KiB  ): NOT removed, essential
 KERNEL           (Huffman, fragmented data, ~135 KiB ): removed
 POLICY           (Huffman, fragmented data, ~91 KiB  ): removed
 HOSTCOMM         (LZMA   , 0x1cc5e6 - 0x1d3302       ): removed
 RSA              (LZMA   , 0x1d3302 - 0x1d8557       ): removed
 CLS              (LZMA   , 0x1d8557 - 0x1ddce8       ): removed
 TDT              (LZMA   , 0x1ddce8 - 0x1e43cd       ): removed
 FTCS             (Huffman, fragmented data, ~18 KiB  ): removed
 ClsPriv          (LZMA   , 0x1e43cd - 0x1e47ae       ): removed
 SESSMGR          (LZMA   , 0x1e47ae - 0x1f30b7       ): removed
The ME minimum size should be 1667072 bytes (0x197000 bytes)
The ME region can be reduced up to:
 00003000:00199fff me
Setting the AltMeDisable bit in PCHSTRP10 to disable Intel ME...
Removing ME/TXE R/W access to the other flash regions...
Checking the FTPR RSA signature... VALID
Done! Good luck!
File /tmp/tmp.EBwMRD8MxB/work.rom is 8388608 bytes
Writing new image to /tmp/tmp.EBwMRD8MxB/work.rom.new
ifdtool and me_cleaner ok
make: Entering directory '/home/kenno/Project/skulls-1.0.5/util/ifdtool'
rm -f ifdtool *.o *~ .dependencies
make: Leaving directory '/home/kenno/Project/skulls-1.0.5/util/ifdtool'
start writing...
flashrom v1.2 on Linux 5.14.21-150400.24.21-default (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Micron/Numonyx/ST flash chip "N25Q064..3E" (8192 kB, SPI) on ch341a_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
DONE

After I rebooted, I noticed no difference, which is a good thing. The boot felt a bit faster -- this might have been due to the disabled ME, or it might have been just me...