Skip to content

Commit

Permalink
add configuration for w541
Browse files Browse the repository at this point in the history
closes #1389
  • Loading branch information
gaspar-ilom committed Oct 16, 2023
1 parent bd2a8eb commit df1b656
Show file tree
Hide file tree
Showing 10 changed files with 3,989 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,20 @@ workflows:
requires:
- x230-hotp-maximized

- build:
name: w541-maximized
target: w541-maximized
subcommand: ""
requires:
- x230-hotp-maximized

- build:
name: w541-hotp-maximized
target: w541-hotp-maximized
subcommand: ""
requires:
- x230-hotp-maximized

- build:
name: qemu-coreboot-fbwhiptail-tpm2-hotp
target: qemu-coreboot-fbwhiptail-tpm2-hotp
Expand Down
40 changes: 40 additions & 0 deletions blobs/w541/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# W541 Blobs

- [Overview](#overview)
- [Using Your Own Blobs](#using-your-own-blobs)

## Overview

Coreboot on the W541 requires the following binary blobs:

- `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).
- `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.
- `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).
- `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).

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.

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.

## Using Your Own Blobs

You can compile Heads using the Intel ME, GbE, and and IFD blobs from your original ROM.

First, make sure you've built Heads at least once in order to download the Coreboot sources:

```console
$ make BOARD=w541-hotp-maximized
```

Then, supply the path to the Coreboot sources via the `COREBOOT_DIR` environment variable, and run the blob-extraction script:

```console
$ export COREBOOT_DIR="./build/x86/coreboot-4.17/"
$ ./blobs/w541/extract /path/to/original_rom.bin ./blobs/w541
```

Now, you can rebuild Heads:

```console
$ make BOARD=w541-hotp-maximized
```
57 changes: 57 additions & 0 deletions blobs/w541/download-clean-me
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

set -e

function usage() {
echo -n \
"Usage: $(basename "$0") path_to_output_directory
Download Intel ME firmware from Lenovo, neutralize, and shrink.
"
}

ME_BIN_HASH="b7cf4c0cf514bbf279d9fddb12c34fca5c1c23e94b000c26275369b924ab9c25"

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
if [[ "${1:-}" == "--help" ]]; then
usage
else
if [[ -z "${COREBOOT_DIR}" ]]; then
echo "ERROR: No COREBOOT_DIR variable defined."
exit 1
fi

output_dir="$(realpath "${1:-./}")"

if [[ ! -f "${output_dir}/me.bin" ]]; then
# Unpack Lenovo's Windows installer into a temporary directory and
# extract the Intel ME blob.
pushd "$(mktemp -d)"

curl -O https://download.lenovo.com/pccbbs/mobiles/glrg22ww.exe
innoextract glrg22ww.exe

mv app/ME9.1_5M_Production.bin "${COREBOOT_DIR}/util/me_cleaner"

popd

# Neutralize and shrink Intel ME. Note that this doesn't include
# --soft-disable to set the "ME Disable" or "ME Disable B" (e.g.,
# High Assurance Program) bits, as they are defined within the Flash
# Descriptor.
# https://github.com/corna/me_cleaner/wiki/External-flashing#neutralize-and-shrink-intel-me-useful-only-for-coreboot
pushd "${COREBOOT_DIR}/util/me_cleaner"

python me_cleaner.py -r -t -O me_shrinked.bin ME9.1_5M_Production.bin

mv me_shrinked.bin "${output_dir}/me.bin"
rm ./*.bin

popd
fi

if ! echo "${ME_BIN_HASH} ${output_dir}/me.bin" | sha256sum --check; then
echo "ERROR: SHA256 checksum for me.bin doesn't match."
exit 1
fi
fi
fi
48 changes: 48 additions & 0 deletions blobs/w541/extract
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash

set -e

function usage() {
echo -n \
"Usage: $(basename "$0") path_to_original_rom path_to_output_directory
Extract Intel firmware from the original ROM.
"
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
if [[ "${1:-}" == "--help" ]]; then
usage
else
if [[ -z "${COREBOOT_DIR}" ]]; then
echo "ERROR: No COREBOOT_DIR variable defined."
exit 1
fi

original_rom="$(realpath "$1")"
output_dir="$(realpath "${2:-./}")"

# Neutralize Intel ME and resize the Intel Flash Descriptor (IFD)
# layout.
# https://github.com/corna/me_cleaner/wiki/External-flashing#neutralize-and-shrink-intel-me-useful-only-for-coreboot
pushd "${COREBOOT_DIR}/util/me_cleaner"

python me_cleaner.py -S -r -t -d -O out.bin -D ifd_shrinked.bin -M me_shrinked.bin "${original_rom}"

mv ifd_shrinked.bin "${output_dir}/ifd.bin"
mv me_shrinked.bin "${output_dir}/me.bin"
rm ./*.bin

popd

# Extract the Intel Gigabit Ethernet (GbE) firmware.
pushd "${COREBOOT_DIR}/util/ifdtool"

make
./ifdtool -x "${original_rom}"

mv flashregion_3_gbe.bin "${output_dir}/gbe.bin"
rm ./*.bin

popd
fi
fi
Binary file added blobs/w541/gbe.bin
Binary file not shown.
Binary file added blobs/w541/ifd.bin
Binary file not shown.
6 changes: 6 additions & 0 deletions boards/w541-hotp-maximized/w541-hotp-maximized.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Inherit the rest from the base W541 config.
include $(pwd)/boards/w541-maximized/w541-maximized.config

CONFIG_HOTPKEY=y

export CONFIG_BOARD_NAME="ThinkPad W541-hotp-maximized"
65 changes: 65 additions & 0 deletions boards/w541-maximized/w541-maximized.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Configuration for a ThinkPad W541.
CONFIG_COREBOOT_CONFIG=config/coreboot-w541.config
# TODO: Make a ThinkPad-common Linux config file.
CONFIG_LINUX_CONFIG=config/linux-w541.config

export CONFIG_COREBOOT=y
export CONFIG_COREBOOT_VERSION=4.19
export CONFIG_LINUX_VERSION=5.10.5

CONFIG_CRYPTSETUP2=y
CONFIG_FLASHROM=y
CONFIG_FLASHTOOLS=y
CONFIG_GPG2=y
CONFIG_KEXEC=y
CONFIG_UTIL_LINUX=y
CONFIG_LVM2=y
CONFIG_MBEDTLS=y
CONFIG_PCIUTILS=y
CONFIG_POPT=y
CONFIG_QRENCODE=y
CONFIG_TPMTOTP=y

#platform locking finalization (PR0)
CONFIG_IO386=y
export CONFIG_FINALIZE_PLATFORM_LOCKING_PRESKYLAKE=y


# Dependencies for a graphical menu. Enable CONFIG_SLANG and CONFIG_NEWT instead
# for a console-based menu.
CONFIG_CAIRO=y
CONFIG_FBWHIPTAIL=y

CONFIG_LINUX_USB=y

export CONFIG_TPM=y
export CONFIG_BOOTSCRIPT=/bin/gui-init
export CONFIG_BOOT_REQ_HASH=n
export CONFIG_BOOT_REQ_ROLLBACK=n
export CONFIG_BOOT_DEV="/dev/sda1"
export CONFIG_BOARD_NAME="ThinkPad W541-maximized"
export CONFIG_FLASHROM_OPTIONS="-p internal"

# Make the Coreboot build depend on the following 3rd party blobs:
$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \
$(pwd)/blobs/haswell/mrc.bin $(pwd)/blobs/w541/me.bin

$(pwd)/blobs/haswell/mrc.bin:
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \
$(pwd)/blobs/haswell/obtain-mrc $(pwd)/blobs/haswell

$(pwd)/blobs/w541/me.bin:
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \
$(pwd)/blobs/w541/download-clean-me $(pwd)/blobs/w541

# Haswell boards have an 8 MiB and 4 MiB SPI flash chip. So, we split the
# Coreboot ROM into two files to flash one on each chip.
all: $(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-bottom.rom
$(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-bottom.rom: $(board_build)/$(CB_OUTPUT_FILE)
$(call do,DD 8MB,$@,dd of=$@ if=$< bs=65536 count=128 skip=0 status=none)
@sha256sum $@ | tee -a "$(HASHES)"

all: $(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-top.rom
$(board_build)/heads-$(BOARD)-$(HEADS_GIT_VERSION)-top.rom: $(board_build)/$(CB_OUTPUT_FILE)
$(call do,DD 4MB,$@,dd of=$@ if=$< bs=65536 count=64 skip=128 status=none)
@sha256sum $@ | tee -a "$(HASHES)"
Loading

0 comments on commit df1b656

Please sign in to comment.