Thinkpad X220 – Shrink the ME Region

Despite vaguely reading the opposite, it is possible to truncate the ME region to the last byte that me_cleaner left untouched. This (on my image) freed about 4 MiB of flash – combined with the fact that coreboot’s default size is 1 MiB (when the region is 3 MiB wide) meant that I now have 7 meg of space to screw around with in CBFS.

Here’s how:

Preparation

  • Dump the rom
  • Run me_cleaner on the rom
  • Use ifdtool to extract the individual regions
    • ifdtool -x <image>

Truncation

Find the last relevant byte

Hexdump will automatically hide large sections of 0xFF – use hexdump on the ME region file:

  • hexdump <me_region>

Here you can see the last relevant line starts with 0x00dbef0 – therefore the last byte is 0x00dbeff.

Truncate the ME region file

We can use dd to truncate the file – but first we need to convert the hex value into a decimal number. Use your calculator of choice (google in my case). For 0x00dbeff it’s 900863

  • dd if=x220_me.bin of=x220_me_trunc.bin bs=1 count=900864

Just double check the size using ls:

  • -rw-r--r-- 1 nroach44 nroach44 900864 Jan 24 15:50 x220_me_trunc.bin

Adjust the Firmware Descriptor

We’ve shrunk the ME region, but we need to inform the chipset that the BIOS region can be bigger.

Extract the layout using ifdtool

  • ifdtool -f layout.txt <full image>

layout.txt will look like the following:

00000000:00000fff fd
00500000:007fffff bios
00003000:004fffff me
00001000:00002fff gbe

You need to edit it so that the ME region ends earlier. The file is simply

<Start address>:<End address> <region type>

So, we need to change the end address for the ME region, and the start address of the BIOS region.

The ME end address needs to be 0x3000 with 0xDBEFF added – so again using your calculator of choice, this comes to 0xDEEFF.

The BIOS start address needs to be one more than that – so 0xDEF00.

Note: The end addresses should end in 3 Fs, and starts should end in 3 0s – https://github.com/corna/me_cleaner/issues/20 – You’ll need to ensure that your addresses comply with this rule. This means the start address of the BIOS region should be one more than the new end address of the ME region

This gets me the following layout.txt:

00000000:00000fff fd
000df000:007fffff bios
00003000:000defff me
00001000:00002fff gbe

We then need to build the new descriptor with this layout file:

  • ifdtool -n layout.txt <full image>

IFDTool will spit out some info that you should sanity check, and also warn you that the ME region is shrinking, this is the whole point.

Then extract the new descriptor:

  • ifdtool -x <full image>

Build coreboot again

Use the new descriptor that you just extracted, and the truncate ME region file in your coreboot config.

You will also need to adjust the CBFS_SIZE option – this can be the size of the BIOS region – you shouldn’t need to do any maths here for padding or overhead. I simply just used 0x700000 as it was easier, but you should be able to just use the whole size. So that would be 0x7fffff – 0xDF000 = 0x720FFF

Flash the image and reboot – you shouldn’t have any issue with the ME forcing a reboot after 30 minutes.

Addendum

Using the 1.5MiB image from the coreboot wiki (thanks github/u/alegru here) it is possible to shrink the region down to ~300KiB:

nroach44@normandy:~/local/tmp/meshrink2$ ~/media/code/coreboot/me_cleaner-git/me_cleaner.py flashregion_2_intel_me15.bin
ME/TXE image detected
Found FPT header at 0x10
Found 11 partition(s)
Found FTPR header: FTPR partition spans from 0x37000 to 0xa1000
Removing extra partitions…
Removing extra partition entries in FPT…
Removing EFFS presence flag…
Correcting checksum (0x05)…
ME/TXE firmware version 7.1.80.1214
Reading FTPR modules list…
UPDATE           (LZMA   , 0x07ba31 – 0x07bac3): removed
BUP              (Huffman, fragmented data    ): NOT removed, essential
KERNEL           (Huffman, fragmented data    ): removed
POLICY           (Huffman, fragmented data    ): removed
HOSTCOMM         (LZMA   , 0x07bac3 – 0x08105a): removed
RSA              (LZMA   , 0x08105a – 0x085b07): removed
CLS              (LZMA   , 0x085b07 – 0x08a519): removed
TDT              (LZMA   , 0x08a519 – 0x0906c0): removed
FTCS             (Huffman, fragmented data    ): removed
The ME minimum size is 294912 bytes (0x48000 bytes)
Checking FTPR RSA signature… VALID
Done! Good luck!

nroach44@normandy:~/local/tmp/meshrink2$ cat layout
00000000:00000fff fd
0004b000:007fffff bios
00003000:0004afff me
00001000:00002fff gbe

nroach44@normandy:~/local/tmp/meshrink2$ ifdtool -n layout 02_shrunk.rom
File 02_shrunk.rom is 8388608 bytes
DANGER: Region Intel ME is shrinking.
The region will be truncated to fit.
This may result in an unusable image.
Copy Descriptor 0 (Flash Descriptor) (4096 bytes)
from 00000000+00000000:00000fff (      4096)
to 00000000+00000000:00000fff (      4096)
Copy Descriptor 1 (BIOS) (7475200 bytes)
from 000df000+00000000:007fffff (   7475200)
to 0004b000+00094000:007fffff (   8081408)
Copy Descriptor 2 (Intel ME) (294912 bytes)
from 00003000+00094000:000defff (    901120)
to 00003000+00000000:0004afff (    294912)
Copy Descriptor 3 (GbE) (8192 bytes)
from 00001000+00000000:00002fff (      8192)
to 00001000+00000000:00002fff (      8192)
Writing new image to 02_shrunk.rom.new

Leave a Reply

Your email address will not be published. Required fields are marked *