Skip to content

Commit f540f2a

Browse files
authored
Merge pull request #1430 from gaspar-ilom/w541-support
Support Thinkpad W541
2 parents 1733552 + 2e8239c commit f540f2a

File tree

10 files changed

+3989
-0
lines changed

10 files changed

+3989
-0
lines changed

.circleci/config.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,20 @@ workflows:
474474
requires:
475475
- x230-hotp-maximized
476476

477+
- build:
478+
name: w541-maximized
479+
target: w541-maximized
480+
subcommand: ""
481+
requires:
482+
- x230-hotp-maximized
483+
484+
- build:
485+
name: w541-hotp-maximized
486+
target: w541-hotp-maximized
487+
subcommand: ""
488+
requires:
489+
- x230-hotp-maximized
490+
477491
- build:
478492
name: qemu-coreboot-fbwhiptail-tpm2-hotp
479493
target: qemu-coreboot-fbwhiptail-tpm2-hotp

blobs/w541/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# W541 Blobs
2+
3+
- [Overview](#overview)
4+
- [Using Your Own Blobs](#using-your-own-blobs)
5+
6+
## Overview
7+
8+
Coreboot on the W541 requires the following binary blobs:
9+
10+
- `mrc.bin` - Consists of Intel’s Memory Reference Code (MRC) and [is used to initialize the DRAM](https://doc.coreboot.org/northbridge/intel/haswell/mrc.bin.html).
11+
- `me.bin` - Consists of Intel’s Management Engine (ME), which we modify using [me_cleaner](https://github.com/corna/me_cleaner) to remove all but the modules which are necessary for the CPU to function.
12+
- `gbe.bin` - Consists of hardware/software configuration data for the Gigabit Ethernet (GbE) controller. Intel publishes the data structure [here](https://web.archive.org/web/20230122164346/https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/i-o-controller-hub-8-9-nvm-map-guide.pdf), and an [ImHex](https://github.com/WerWolv/ImHex) hex editor pattern is available [here](https://github.com/rbreslow/ImHex-Patterns/blob/rb/intel-ich8/patterns/intel/ich8_lan_nvm.hexpat).
13+
- `ifd.bin` - Consists of the Intel Flash Descriptor (IFD). Intel publishes the data structure [here](https://web.archive.org/web/20221208011432/https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/io-controller-hub-8-datasheet.pdf), and an ImHex hex editor pattern is available [here](https://github.com/rbreslow/ImHex-Patterns/blob/rb/intel-ich8/patterns/intel/ich8_flash_descriptor.hexpat).
14+
15+
Heads supplies an IFD and GbE blob, which we extracted from a donor board. We changed the MAC address of the GbE blob to `00:de:ad:c0:ff:ee` using [nvmutil](https://libreboot.org/docs/install/nvmutil.html), to support anonymity and build reproducibility.
16+
17+
When building any W541 board variant with `make`, the build system will download a copy of the MRC and Intel ME. We extract `mrc.bin` from a Chromebook firmware image and `me.bin` from a Lenovo firmware update.
18+
19+
## Using Your Own Blobs
20+
21+
You can compile Heads using the Intel ME, GbE, and and IFD blobs from your original ROM.
22+
23+
First, make sure you've built Heads at least once in order to download the Coreboot sources:
24+
25+
```console
26+
$ make BOARD=w541-hotp-maximized
27+
```
28+
29+
Then, supply the path to the Coreboot sources via the `COREBOOT_DIR` environment variable, and run the blob-extraction script:
30+
31+
```console
32+
$ export COREBOOT_DIR="./build/x86/coreboot-4.17/"
33+
$ ./blobs/w541/extract /path/to/original_rom.bin ./blobs/w541
34+
```
35+
36+
Now, you can rebuild Heads:
37+
38+
```console
39+
$ make BOARD=w541-hotp-maximized
40+
```

blobs/w541/download-clean-me

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
function usage() {
6+
echo -n \
7+
"Usage: $(basename "$0") path_to_output_directory
8+
Download Intel ME firmware from Lenovo, neutralize, and shrink.
9+
"
10+
}
11+
12+
ME_BIN_HASH="b7cf4c0cf514bbf279d9fddb12c34fca5c1c23e94b000c26275369b924ab9c25"
13+
14+
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
15+
if [[ "${1:-}" == "--help" ]]; then
16+
usage
17+
else
18+
if [[ -z "${COREBOOT_DIR}" ]]; then
19+
echo "ERROR: No COREBOOT_DIR variable defined."
20+
exit 1
21+
fi
22+
23+
output_dir="$(realpath "${1:-./}")"
24+
25+
if [[ ! -f "${output_dir}/me.bin" ]]; then
26+
# Unpack Lenovo's Windows installer into a temporary directory and
27+
# extract the Intel ME blob.
28+
pushd "$(mktemp -d)"
29+
30+
curl -O https://download.lenovo.com/pccbbs/mobiles/glrg22ww.exe
31+
innoextract glrg22ww.exe
32+
33+
mv app/ME9.1_5M_Production.bin "${COREBOOT_DIR}/util/me_cleaner"
34+
35+
popd
36+
37+
# Neutralize and shrink Intel ME. Note that this doesn't include
38+
# --soft-disable to set the "ME Disable" or "ME Disable B" (e.g.,
39+
# High Assurance Program) bits, as they are defined within the Flash
40+
# Descriptor.
41+
# https://github.com/corna/me_cleaner/wiki/External-flashing#neutralize-and-shrink-intel-me-useful-only-for-coreboot
42+
pushd "${COREBOOT_DIR}/util/me_cleaner"
43+
44+
python me_cleaner.py -r -t -O me_shrinked.bin ME9.1_5M_Production.bin
45+
46+
mv me_shrinked.bin "${output_dir}/me.bin"
47+
rm ./*.bin
48+
49+
popd
50+
fi
51+
52+
if ! echo "${ME_BIN_HASH} ${output_dir}/me.bin" | sha256sum --check; then
53+
echo "ERROR: SHA256 checksum for me.bin doesn't match."
54+
exit 1
55+
fi
56+
fi
57+
fi

blobs/w541/extract

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
function usage() {
6+
echo -n \
7+
"Usage: $(basename "$0") path_to_original_rom path_to_output_directory
8+
Extract Intel firmware from the original ROM.
9+
"
10+
}
11+
12+
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
13+
if [[ "${1:-}" == "--help" ]]; then
14+
usage
15+
else
16+
if [[ -z "${COREBOOT_DIR}" ]]; then
17+
echo "ERROR: No COREBOOT_DIR variable defined."
18+
exit 1
19+
fi
20+
21+
original_rom="$(realpath "$1")"
22+
output_dir="$(realpath "${2:-./}")"
23+
24+
# Neutralize Intel ME and resize the Intel Flash Descriptor (IFD)
25+
# layout.
26+
# https://github.com/corna/me_cleaner/wiki/External-flashing#neutralize-and-shrink-intel-me-useful-only-for-coreboot
27+
pushd "${COREBOOT_DIR}/util/me_cleaner"
28+
29+
python me_cleaner.py -S -r -t -d -O out.bin -D ifd_shrinked.bin -M me_shrinked.bin "${original_rom}"
30+
31+
mv ifd_shrinked.bin "${output_dir}/ifd.bin"
32+
mv me_shrinked.bin "${output_dir}/me.bin"
33+
rm ./*.bin
34+
35+
popd
36+
37+
# Extract the Intel Gigabit Ethernet (GbE) firmware.
38+
pushd "${COREBOOT_DIR}/util/ifdtool"
39+
40+
make
41+
./ifdtool -x "${original_rom}"
42+
43+
mv flashregion_3_gbe.bin "${output_dir}/gbe.bin"
44+
rm ./*.bin
45+
46+
popd
47+
fi
48+
fi

blobs/w541/gbe.bin

8 KB
Binary file not shown.

blobs/w541/ifd.bin

4 KB
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Inherit the rest from the base W541 config.
2+
include $(pwd)/boards/w541-maximized/w541-maximized.config
3+
4+
CONFIG_HOTPKEY=y
5+
6+
export CONFIG_BOARD_NAME="ThinkPad W541-hotp-maximized"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Configuration for a ThinkPad W541.
2+
CONFIG_COREBOOT_CONFIG=config/coreboot-w541.config
3+
# TODO: Make a ThinkPad-common Linux config file.
4+
CONFIG_LINUX_CONFIG=config/linux-w541.config
5+
6+
export CONFIG_COREBOOT=y
7+
export CONFIG_COREBOOT_VERSION=4.19
8+
export CONFIG_LINUX_VERSION=5.10.5
9+
10+
CONFIG_CRYPTSETUP2=y
11+
CONFIG_FLASHROM=y
12+
CONFIG_FLASHTOOLS=y
13+
CONFIG_GPG2=y
14+
CONFIG_KEXEC=y
15+
CONFIG_UTIL_LINUX=y
16+
CONFIG_LVM2=y
17+
CONFIG_MBEDTLS=y
18+
CONFIG_PCIUTILS=y
19+
CONFIG_POPT=y
20+
CONFIG_QRENCODE=y
21+
CONFIG_TPMTOTP=y
22+
23+
#platform locking finalization (PR0)
24+
CONFIG_IO386=y
25+
export CONFIG_FINALIZE_PLATFORM_LOCKING_PRESKYLAKE=y
26+
27+
28+
# Dependencies for a graphical menu. Enable CONFIG_SLANG and CONFIG_NEWT instead
29+
# for a console-based menu.
30+
CONFIG_CAIRO=y
31+
CONFIG_FBWHIPTAIL=y
32+
33+
CONFIG_LINUX_USB=y
34+
35+
export CONFIG_TPM=y
36+
export CONFIG_BOOTSCRIPT=/bin/gui-init
37+
export CONFIG_BOOT_REQ_HASH=n
38+
export CONFIG_BOOT_REQ_ROLLBACK=n
39+
export CONFIG_BOOT_DEV="/dev/sda1"
40+
export CONFIG_BOARD_NAME="ThinkPad W541-maximized"
41+
export CONFIG_FLASHROM_OPTIONS="-p internal"
42+
43+
# Make the Coreboot build depend on the following 3rd party blobs:
44+
$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \
45+
$(pwd)/blobs/haswell/mrc.bin $(pwd)/blobs/w541/me.bin
46+
47+
$(pwd)/blobs/haswell/mrc.bin:
48+
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \
49+
$(pwd)/blobs/haswell/obtain-mrc $(pwd)/blobs/haswell
50+
51+
$(pwd)/blobs/w541/me.bin:
52+
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \
53+
$(pwd)/blobs/w541/download-clean-me $(pwd)/blobs/w541
54+
55+
# Haswell boards have an 8 MiB and 4 MiB SPI flash chip. So, we split the
56+
# Coreboot ROM into two files to flash one on each chip.
57+
all: $(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-bottom.rom
58+
$(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-bottom.rom: $(board_build)/$(CB_OUTPUT_FILE)
59+
$(call do,DD 8MB,$@,dd of=$@ if=$< bs=65536 count=128 skip=0 status=none)
60+
@sha256sum $@ | tee -a "$(HASHES)"
61+
62+
all: $(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-top.rom
63+
$(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-top.rom: $(board_build)/$(CB_OUTPUT_FILE)
64+
$(call do,DD 4MB,$@,dd of=$@ if=$< bs=65536 count=64 skip=128 status=none)
65+
@sha256sum $@ | tee -a "$(HASHES)"

0 commit comments

Comments
 (0)