This sections relates to disabling and removing the ME (Intel Management Engine) on GM45. This was originally done on the ThinkPad X200, and later adapted for the ThinkPad R400/T400/T500. It can in principle be done on any GM45 or GS45 machine.
The ME is a blob that typically must be left inside the flash chip (in the ME region, as outlined by the default descriptor). On GM45, it is possible to remove it without any ill effects. All other parts of coreboot on GM45 machines (provided GMA MHD4500 / Intel graphics) can be blob-free, so removing the ME was the last obstacle to make GM45 a feasible target in libreboot (the machines can also work without the microcode blobs).
The ME is removed and disabled in libreboot by modifying the descriptor. More info about this can be found in the ich9deblob/ich9gen source code in resources/utilities/ich9deblob/ in libreboot, or more generally on this page.
It is no longer necessary to use ich9deblob to generate a deblobbed descriptor+gbe image for GM45 targets. ich9gen is a small utility within ich9deblob that can generate them from scratch, without a factory.bin dump.
Run:
$ ./ich9gen
Running ich9gen this way (without any arguments) generates a default descriptor+gbe image with a generic MAC address. You probably don't want to use the generic one; the ROM images in libreboot contain a descriptor+gbe image by default (already inserted) just to prevent or mitigate the risk of bricking your laptop, but with the generic MAC address (the libreboot project does not know what your real MAC address is).
On GM45 laptops that use flash descriptors, the MAC address
or the onboard ethernet chipset is flashed (inside the ROM image).
You should generate a descriptor+gbe image with your own MAC address
inside (with the Gbe checksum updated to match). Run:
$ ./ich9gen --macaddress XX:XX:XX:XX:XX:XX
(replace the XX chars with the hexadecimal chars in the MAC address that you want)
Two new files will be created:
You can find out your MAC address from ip addr or ifconfig in GNU/Linux. Alternatively, if you are running libreboot already (with the correct MAC address in your ROM), dump it (flashrom -r) and read the first 6 bytes from position 0x1000 (or 0x2000) in a hex editor (or, rename it to factory.rom and run it in ich9deblob: in the newly created mkgbe.c will be the individual bytes of your MAC address). If you are currently running the stock firmware and haven't installed libreboot yet, you can also run that through ich9deblob to get the mac address.
An even simpler way to get the MAC address would be to read what's on the little sticker on the underside. (on the X200, this would be near the VGA port).
A bash script is also included in libreboot_util which will change the mac address (using ich9gen)
on all GM45 ROM images. For instance:
$ ./ich9macchange path/to/libreboot.rom XX:XX:XX:XX:XX:XX romsize
romsize should be 4 or 8, depending on whether the ROM image is for a 4MiB or 8MiB flash chip.
ich9gen executables can be found under ./ich9deblob/ statically compiled in
libreboot_util. If you are using src or git, build ich9gen from source with:
$ ./build module ich9deblob
The executable will appear under resources/utilities/ich9deblob/
Assuming that your libreboot image is named libreboot.rom, copy
the file to where libreboot.rom is located
and then run, for instance:
$ dd if=ich9fdgbe_8m.bin of=libreboot.rom bs=1 count=12k conv=notrunc
or:
$ dd if=ich9fdgbe_4m.bin of=libreboot.rom bs=1 count=12k conv=notrunc
Your libreboot.rom image is now ready to be flashed on the machine. Refer back to ../install/index.html#flashrom for how to flash it.
Look in resources/utilities/ich9deblob/src/descriptor/descript.c for the following lines in the descriptorHostRegionsUnlocked function:
descriptorStruct.masterAccessSection.flMstr1.fdRegionWriteAccess = 0x1; descriptorStruct.masterAccessSection.flMstr1.biosRegionWriteAccess = 0x1; descriptorStruct.masterAccessSection.flMstr1.meRegionWriteAccess = 0x1; descriptorStruct.masterAccessSection.flMstr1.gbeRegionWriteAccess = 0x1; descriptorStruct.masterAccessSection.flMstr1.pdRegionWriteAccess = 0x1;
Change them all to 0x0, then re-compile ich9gen. After you have done that, follow the notes in #ich9gen to generate a new descriptor+gbe image and insert that into your ROM image, then flash it. The next time you boot, the flash chip will be ready-only in software (hardware re-flashing will still work, which you will need for re-flashing the chip after write-protecting it, to clear the write protection or to flash yet another ROM image with write protection set in the descriptor).
For external flashing guides, refer to ../install/index.html.
This is no longer strictly necessary. Libreboot ROM images for GM45 machines now contain the 12KiB descriptor+gbe generated from ich9gen, by default.
This was the tool originally used to disable the ME on X200 (later adapted for other machines that use the GM45 chipset). ich9gen now supersedes it; ich9gen is better because it does not rely on dumping the factory.rom image (whereas, ich9deblob does).
This is what you will use to generate the deblobbed descriptor+gbe regions for your libreboot ROM image.
If you are working with libreboot_src (or git), you can find the source under resources/utilities/ich9deblob/
and will already be compiled if you ran ./build module all or ./build module ich9deblob from the main directory (./),
otherwise you can build it like so:
$ ./build module ich9deblob
An executable file named ich9deblob will now appear under resources/utilities/ich9deblob/
If you are working with libreboot_util release archive, you can find the utility included, statically compiled (for i686 and x86_64 on GNU/Linux) under ./ich9deblob/.
Place the factory.rom from your machine
(can be obtained using the external flashing guides for GM45 targets linked ../install/index.html) in
the directory where you have your ich9deblob executable, then run the tool:
$ ./ich9deblob
A 12kiB file named deblobbed_descriptor.bin will now appear. Keep this and the factory.rom stored in a safe location! The first 4KiB contains the descriptor data region for your machine, and the next 8KiB contains the gbe region (config data for your gigabit NIC). These 2 regions could actually be separate files, but they are joined into 1 file in this case.
Assuming that your libreboot image is named libreboot.rom, copy
the deblobbed_descriptor.bin file to where libreboot.rom is located
and then run:
$ dd if=deblobbed_descriptor.bin of=libreboot.rom bs=1 count=12k conv=notrunc
The utility will also generate 4 additional files:
These are C source files that can re-generate the very same Gbe and Descriptor structs (from ich9deblob/ich9gen). To use these, place them in src/ich9gen/ in ich9deblob, then re-build. The newly built ich9gen executable will be able to re-create the very same 12KiB file from scratch, based on the C structs, this time without the need for a factory.rom dump!
You should now have a libreboot.rom image containing the correct 4K descriptor and 8K gbe regions, which will then be safe to flash. Refer back to ../install/index.html#flashrom for how to flash it.
The sections below are adapted from (mostly) IRC logs related to early development getting the ME removed on GM45. They are useful for background information. This could not have been done without sgsit's help.
Start (hex) End (hex) Length (hex) Area Name ----------- --------- ------------ --------- 00000000 003FFFFF 00400000 Flash Image 00000000 00000FFF 00001000 Descriptor Region 00000004 0000000F 0000000C Descriptor Map 00000010 0000001B 0000000C Component Section 00000040 0000004F 00000010 Region Section 00000060 0000006B 0000000C Master Access Section 00000060 00000063 00000004 CPU/BIOS 00000064 00000067 00000004 Manageability Engine (ME) 00000068 0000006B 00000004 GbE LAN 00000100 00000103 00000004 ICH Strap 0 00000104 00000107 00000004 ICH Strap 1 00000200 00000203 00000004 MCH Strap 0 00000EFC 00000EFF 00000004 Descriptor Map 2 00000ED0 00000EF7 00000028 ME VSCC Table 00000ED0 00000ED7 00000008 Flash device 1 00000ED8 00000EDF 00000008 Flash device 2 00000EE0 00000EE7 00000008 Flash device 3 00000EE8 00000EEF 00000008 Flash device 4 00000EF0 00000EF7 00000008 Flash device 5 00000F00 00000FFF 00000100 OEM Section 00001000 001F5FFF 001F5000 ME Region 001F6000 001F7FFF 00002000 GbE Region 001F8000 001FFFFF 00008000 PDR Region 00200000 003FFFFF 00200000 BIOS Region Start (hex) End (hex) Length (hex) Area Name ----------- --------- ------------ --------- 00000000 003FFFFF 00400000 Flash Image 00000000 00000FFF 00001000 Descriptor Region 00000004 0000000F 0000000C Descriptor Map 00000010 0000001B 0000000C Component Section 00000040 0000004F 00000010 Region Section 00000060 0000006B 0000000C Master Access Section 00000060 00000063 00000004 CPU/BIOS 00000064 00000067 00000004 Manageability Engine (ME) 00000068 0000006B 00000004 GbE LAN 00000100 00000103 00000004 ICH Strap 0 00000104 00000107 00000004 ICH Strap 1 00000200 00000203 00000004 MCH Strap 0 00000ED0 00000EF7 00000028 ME VSCC Table 00000ED0 00000ED7 00000008 Flash device 1 00000ED8 00000EDF 00000008 Flash device 2 00000EE0 00000EE7 00000008 Flash device 3 00000EE8 00000EEF 00000008 Flash device 4 00000EF0 00000EF7 00000008 Flash device 5 00000EFC 00000EFF 00000004 Descriptor Map 2 00000F00 00000FFF 00000100 OEM Section 00001000 00002FFF 00002000 GbE Region 00003000 00202FFF 00200000 BIOS Region Build Settings -------------- Flash Erase Size = 0x1000
It's a utility called 'Flash Image Tool' for ME 4.x that was used for this. You drag a complete image into in and the utility decomposes the various components, allowing you to set soft straps.
This tool is proprietary, for Windows only, but was used to deblob the X200. End justified means, and the utility is no longer needed since the ich9deblob utility (documented on this page) can now be used to create deblobbed descriptors.
Of the 8K, about 95% is 0xFF. The data is the gbe region is fully documented in this public datasheet: http://www.intel.co.uk/content/dam/doc/application-note/i-o-controller-hub-9m-82567lf-lm-v-nvm-map-appl-note.pdf
The only actual content found was:
00 1F 1F 1F 1F 1F 00 08 FF FF 83 10 FF FF FF FF 08 10 FF FF C3 10 EE 20 AA 17 F5 10 86 80 00 00 01 0D 00 00 00 00 05 06 20 30 00 0A 00 00 8B 8D 02 06 40 2B 43 00 00 00 F5 10 AD BA F5 10 BF 10 AD BA CB 10 AD BA AD BA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 40 28 12 07 40 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF D9 F0 20 60 1F 00 02 00 13 00 00 80 1D 00 FF 00 16 00 DD CC 18 00 11 20 17 00 DD DD 18 00 12 20 17 00 00 80 1D 00 00 00 1F
The first part is the MAC address set to all 0x1F. It's repeated haly way through the 8K area, and the rest is all 0xFF. This is all documented in the datasheet.
The GBe region starts at 0x20A000 bytes from the *end* of a factory image and is 0x2000 bytes long. In libreboot (deblobbed) the descriptor is set to put gbe directly after the initial 4K flash descriptor. So the first 4K of the ROM is the descriptor, and then the next 8K is the gbe region.
According to the datasheet, it's supposed to add up to 0xBABA but can actually be others on the X200. https://communities.intel.com/community/wired/blog/2010/10/14/how-to-basic-eeprom-checksums
"One of those engineers loves classic rock music, so he selected 0xBABA"
In honour of the song Baba O'Reilly by The Who apparently. We're not making this stuff up...
0x3ABA, 0x34BA, 0x40BA and more have been observed in the main Gbe regions on the X200 factory.rom dumps. The checksums of the backup regions match BABA, however.
By default, the X200 (as shipped by Lenovo) actually has an invalid main gbe checksum. The backup gbe region is correct, and is what these machines default to. Basically, you should do what you need on the *backup* gbe region, and then correct the main one by copying from the backup.
Look at resources/utilities/ich9deblob/ich9deblob.c.
http://www.intel.co.uk/content/dam/doc/datasheet/io-controller-hub-9-datasheet.pdf from page 850 onwards. This explains everything that is in the flash descriptor, which can be used to understand what libreboot is doing about modifying it.
How to deblob:
There's an interesting parameter called 'ME Alternate disable', which allows the ME to only handle hardware errata in the southbridge, but disables any other functionality. This is similar to the 'ignition' in the 5 series and higher but using the standard firmware instead of a small 128K version. Useless for libreboot, though.
To deblob GM45, you chop out the platform and ME regions and correct the addresses in flReg1-4. Then you set meDisable to 1 in ICHSTRAP0 and MCHSTRAP0.
How to patch the descriptor from the factory.rom dump
This means that libreboot's descriptor region will simply define the following regions:
The data in the descriptor region is little endian, and it represents bits 24:12 of the address (bits 12-24, written this way since bit 24 is nearer to left than bit 12 in the binary representation).
So, x << 12 = address
If it's in descriptor mode, then the first 4 bytes will be 5A A5 F0 0F.
Basically useless for libreboot, since it appears to be a blob. Removing it didn't cause any issues in libreboot.
This is a 32K region from the factory image. It could be data (non-functional) that the original Lenovo BIOS used, but we don't know.
It has only a 448 byte fragment different from 0x00 or 0xFF.
Copyright © 2014, 2015 Francis Rowe <info@gluglug.org.uk>
This document is released under the Creative Commons Attribution-ShareAlike 4.0 International Public License and all future versions.
A copy of the license can be found at ../license.txt.
This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See ../../license.txt for more information.