Skip to content

Commit 41de8eb

Browse files
committed
boards: add Dell OptiPlex 9020 SFF support
Add a new board configuration for the Dell OptiPlex 9020 SFF, the first Heads port for this hardware. The 9020 SFF is a Haswell + Lynx Point desktop that shares its platform with the already-supported ThinkPad T440p, but differs in the embedded controller (SMSC SCH555x) and uses a two-chip 8 MB + 4 MB SPI layout. Blob-minimized configuration: - No MRC blob (uses Native RAM Initialization via CONFIG_USE_NATIVE_RAMINIT) - No FSP (Haswell does not use it) - Intel ME neutralized and soft-disabled via me_cleaner (-S -r -t -d), shrunk from 6 MB to ~120 KB (FTPR bring-up module only) - IFD and GbE configuration blobs are extracted by each user from their own Dell BIOS backup (no third-party downloads) Verified on hardware: coreboot builds cleanly, the Heads payload boots to the GUI menu, and USB input works with CONFIG_USB_KEYBOARD_REQUIRED. Files added: - boards/dell-optiplex-9020-sff/dell-optiplex-9020-sff.config - config/coreboot-dell-optiplex-9020-sff.config (derived from t440p) - blobs/optiplex_9020/extract, README.md Signed-off-by: Michael Gogiashvili <gogiaschvili@protonmail.com>
1 parent 420d71e commit 41de8eb

4 files changed

Lines changed: 1021 additions & 0 deletions

File tree

blobs/optiplex_9020/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# OptiPlex 9020 SFF Blobs
2+
3+
- [Overview](#overview)
4+
- [Blob Strategy](#blob-strategy)
5+
- [Using Your Own Blobs](#using-your-own-blobs)
6+
7+
## Overview
8+
9+
Heads on the Dell OptiPlex 9020 SFF requires three small binary blobs, all
10+
extracted from the user's own Dell BIOS backup. **No proprietary code blobs
11+
are downloaded from third parties** — everything comes from your hardware.
12+
13+
| Blob | Size | What it is |
14+
|-----------|----------|-----------------------------------------------------------|
15+
| `ifd.bin` | 4 KB | Intel Flash Descriptor (resized: ME shrunk, BIOS grown) |
16+
| `me.bin` | ~120 KB | Intel ME, **neutralized + soft-disabled** via me_cleaner |
17+
| `gbe.bin` | 16 KB | Intel Gigabit Ethernet config (incl. LAN MAC address) |
18+
19+
**Notably NOT required** (this is the blob-minimized setup):
20+
21+
- `mrc.bin`**eliminated**. Haswell native RAM initialization (NRI) is used
22+
instead, via coreboot's `CONFIG_USE_NATIVE_RAMINIT=y`. No proprietary
23+
memory-init blob.
24+
- FSP — Haswell does not use Intel Firmware Support Package.
25+
- Intel ME in full — only the ~120 KB FTPR bring-up module remains; all AMT,
26+
networking, anti-theft and backdoor modules removed.
27+
28+
## Blob Strategy
29+
30+
The Intel ME on the 9020 (Lynx Point, ME 9.x) is **neutralized and
31+
soft-disabled** using [me_cleaner](https://github.com/corna/me_cleaner)
32+
with the flags `-S -r -t -d`:
33+
34+
- `-S` sets the AltMeDisable bit (HAP) in PCHSTRP10 → ME disabled after boot
35+
- `-r` removes non-essential ME modules (TDT, FPF, HOSTCOMM, SESSMGR, ...)
36+
- `-t` truncates the ME region to the minimum bootable size (~120 KB)
37+
- `-d` additionally deactivates ME features
38+
39+
Result: ME shrunk from 6 MB → ~120 KB, **98% reduction**. The remaining FTPR
40+
module is required for power/clock management during boot; it cannot be
41+
removed without bricking the board. The ME's RSA signature remains valid
42+
(verified by me_cleaner), so the board boots.
43+
44+
> **Note on "completely removing" the ME:** The ME is physically present in
45+
> the Lynx Point PCH silicon. Software cannot remove hardware. me_cleaner's
46+
> neutralization is the maximum achievable on this platform.
47+
48+
## Using Your Own Blobs
49+
50+
If you have a different Dell 9020 SFF (or want to re-extract from a fresh
51+
backup), first build Heads at least once to download the coreboot sources,
52+
then run the extraction script:
53+
54+
```console
55+
$ make BOARD=dell-optiplex-9020-sff # downloads coreboot sources
56+
57+
$ export COREBOOT_DIR="./build/x86/coreboot-25.09/"
58+
$ ./blobs/optiplex_9020/extract /path/to/original_dell_bios.bin ./blobs/optiplex_9020
59+
60+
$ make BOARD=dell-optiplex-9020-sff # rebuild with your blobs
61+
```
62+
63+
The extraction script performs the same operations that produced the blobs
64+
shipped here. Your MAC address will differ; if you want anonymity, override
65+
it to `00:de:ad:c0:ff:ee` using [nvmutil](https://libreboot.org/docs/install/nvmutil.html).

blobs/optiplex_9020/extract

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env bash
2+
# =============================================================================
3+
# Extract Intel firmware blobs (IFD, ME, GbE) from an original Dell OptiPlex
4+
# 9020 SFF BIOS backup, and neutralize the Intel ME.
5+
#
6+
# Usage: ./extract <path_to_original_rom.bin> <path_to_output_directory>
7+
#
8+
# Produces in the output directory:
9+
# ifd.bin - Intel Flash Descriptor (resized: ME region shrunk, BIOS grown)
10+
# me.bin - Intel ME firmware (neutralized + soft-disabled + truncated)
11+
# gbe.bin - Intel Gigabit Ethernet configuration (incl. LAN MAC address)
12+
#
13+
# Modelled on blobs/t440p/extract. Requires COREBOOT_DIR pointing at a built
14+
# coreboot source tree (for util/me_cleaner and util/ifdtool).
15+
# =============================================================================
16+
set -e
17+
18+
function usage() {
19+
echo -n \
20+
"Usage: $(basename "$0") path_to_original_rom path_to_output_directory
21+
Extract Intel firmware from the original Dell OptiPlex 9020 SFF BIOS backup.
22+
Neutralizes the ME via me_cleaner (-S -r -t -d) and shrinks the IFD regions.
23+
"
24+
}
25+
26+
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
27+
if [[ "${1:-}" == "--help" ]]; then
28+
usage
29+
else
30+
if [[ -z "${COREBOOT_DIR}" ]]; then
31+
echo "ERROR: No COREBOOT_DIR variable defined."
32+
echo " Export COREBOOT_DIR=/path/to/built/coreboot source tree."
33+
exit 1
34+
fi
35+
36+
original_rom="$(realpath "$1")"
37+
output_dir="$(realpath "${2:-./}")"
38+
39+
if [[ ! -f "${original_rom}" ]]; then
40+
echo "ERROR: original ROM not found: ${original_rom}"
41+
exit 1
42+
fi
43+
44+
echo ">>> Source ROM: ${original_rom} ($(stat -c%s "${original_rom}") bytes)"
45+
echo ">>> Output dir: ${output_dir}"
46+
echo
47+
48+
# Step 1: Neutralize Intel ME + resize the IFD regions in one pass.
49+
# Flags (same as t440p reference):
50+
# -S soft-disable (set AltMeDisable / HAP bit in PCHSTRP10)
51+
# -r remove (strip non-essential ME modules)
52+
# -t truncate (shrink ME region to minimum bootable size)
53+
# -d deactivate (additionally disable ME features)
54+
# -O output full image (descriptor + neutered ME)
55+
# -D output shrinked descriptor
56+
# -M output truncated ME image
57+
echo ">>> me_cleaner: neutralizing + soft-disabling Intel ME..."
58+
pushd "${COREBOOT_DIR}/util/me_cleaner"
59+
60+
python me_cleaner.py -S -r -t -d \
61+
-O out.bin \
62+
-D ifd_shrinked.bin \
63+
-M me_shrinked.bin \
64+
"${original_rom}"
65+
66+
mv ifd_shrinked.bin "${output_dir}/ifd.bin"
67+
mv me_shrinked.bin "${output_dir}/me.bin"
68+
rm -f ./*.bin
69+
70+
popd
71+
echo " -> ifd.bin ($(stat -c%s "${output_dir}/ifd.bin") bytes)"
72+
echo " -> me.bin ($(stat -c%s "${output_dir}/me.bin") bytes)"
73+
74+
# Step 2: Extract the Intel Gigabit Ethernet (GbE) configuration blob
75+
# (contains the LAN MAC address) using ifdtool.
76+
echo ">>> ifdtool: extracting GbE configuration blob..."
77+
pushd "${COREBOOT_DIR}/util/ifdtool"
78+
79+
make
80+
./ifdtool -x "${original_rom}"
81+
82+
mv flashregion_3_gbe.bin "${output_dir}/gbe.bin"
83+
rm -f flashregion_*.bin
84+
85+
popd
86+
echo " -> gbe.bin ($(stat -c%s "${output_dir}/gbe.bin") bytes)"
87+
88+
echo
89+
echo ">>> Done. Blobs in ${output_dir}:"
90+
ls -la "${output_dir}"/ifd.bin "${output_dir}"/me.bin "${output_dir}"/gbe.bin
91+
fi
92+
fi
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# WARNING: This system remains perpetually vulnerable to Spectre v2 (CVE-2017-5715).
2+
# Mitigations and microcode updates previously applied are now known to be ineffective
3+
# due to QSB-107 and related CVEs. If Spectre v2 is a concern in your threat model,
4+
# consider migrating to a platform with ongoing microcode support. Proper OPSEC for
5+
# Memory Use MUST be followed:
6+
# https://www.anarsec.guide/posts/qubes/#appendix-opsec-for-memory-use
7+
#
8+
# Configuration for a Dell OptiPlex 9020 SFF running Qubes OS and other
9+
# Linux-based OSes through kexec.
10+
#
11+
# Hardware specifications:
12+
# - CPU: LGA 1150, Intel Haswell (4th Gen) -- Celeron/Pentium/Core i3/i5/i7,
13+
# up to Core i7-4790 (4C/8T, 3.6 GHz base / 4.0 GHz boost)
14+
# - Chipset: Intel Q87 Express (Lynx Point)
15+
# - RAM: 2x DDR3-1600 UDIMM, up to 16 GB per slot (32 GB max), dual-channel
16+
# - Storage: 2x SATA 6 Gb/s; NVMe via PCIe adapter in x16 slot
17+
# - PCIe: 1x PCIe 3.0 x16, 1x PCIe 3.0 x1 (half-height SFF brackets)
18+
# - Video: 1x VGA + 1x DisplayPort 1.2 (Intel HD Graphics 4600, Haswell GT2)
19+
# - Ethernet: Intel I217-LM Gigabit
20+
# - Audio: Realtek ALC3221 HD Audio
21+
# - TPM: Infineon TPM 1.2 (soldered, supports measured boot)
22+
# - Form factor: Small Form Factor (SFF)
23+
#
24+
# Platform notes (vs. the t440p reference, which is also Haswell + Lynx Point):
25+
# - Northbridge/southbridge/CPU/ME: identical to t440p
26+
# - Embedded Controller: SMSC SCH555x (Dell) instead of Lenovo H8/EC
27+
# - Super I/O handled by the same sch555x driver
28+
# - SATA port map: 0x33 (ports 0 and 5 active on SFF)
29+
# - VGA BIOS ID: Haswell GT2 desktop variant
30+
# - ROM: 12 MB split into an 8 MB bottom chip and a 4 MB top chip
31+
#
32+
# Blob strategy (blob-minimized):
33+
# - MRC blob: none. Uses Native RAM Initialization (CONFIG_USE_NATIVE_RAMINIT).
34+
# - FSP: none. Haswell does not use Intel Firmware Support Package.
35+
# - Intel ME: neutralized and soft-disabled via me_cleaner (-S -r -t -d).
36+
# AltMeDisable bit set in PCHSTRP10. ME shrunk from 6 MB to ~120 KB.
37+
# Only the bring-up module (FTPR) remains; all AMT/networking/backdoor
38+
# modules (TDT, FPF, HOSTCOMM, SESSMGR, ...) removed.
39+
# - IFD/GbE: small configuration blobs (4 KB / 16 KB), not executable firmware.
40+
# Each user extracts these from their own Dell BIOS backup.
41+
42+
# Coreboot + Linux versions (match the t440p reference for Haswell)
43+
export CONFIG_COREBOOT=y
44+
export CONFIG_COREBOOT_VERSION=25.09
45+
export CONFIG_LINUX_VERSION=6.1.8
46+
47+
CONFIG_COREBOOT_CONFIG=config/coreboot-dell-optiplex-9020-sff.config
48+
CONFIG_LINUX_CONFIG=config/linux-t440p.config
49+
50+
# --- Blob handling -----------------------------------------------------------
51+
# The Coreboot build depends on the three blobs extracted from the Dell BIOS
52+
# backup: ifd.bin (resized descriptor), me.bin (neutralized ME), gbe.bin.
53+
$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \
54+
$(pwd)/blobs/optiplex_9020/ifd.bin \
55+
$(pwd)/blobs/optiplex_9020/me.bin \
56+
$(pwd)/blobs/optiplex_9020/gbe.bin
57+
58+
# When the blobs are missing, run the extract script to pull IFD/ME/GbE out
59+
# of the original Dell BIOS backup and neutralize the ME.
60+
$(pwd)/blobs/optiplex_9020/ifd.bin $(pwd)/blobs/optiplex_9020/me.bin $(pwd)/blobs/optiplex_9020/gbe.bin:
61+
COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \
62+
$(pwd)/blobs/optiplex_9020/extract "$(pwd)/blobs/optiplex_9020/original_dell_bios.bin" "$(pwd)/blobs/optiplex_9020"
63+
64+
# --- Modules packed into tools.cpio ------------------------------------------
65+
CONFIG_CRYPTSETUP2=y
66+
CONFIG_FLASHPROG=y
67+
CONFIG_FLASHTOOLS=y
68+
CONFIG_GPG2=y
69+
CONFIG_KEXEC=y
70+
CONFIG_UTIL_LINUX=y
71+
CONFIG_LVM2=y
72+
CONFIG_MBEDTLS=y
73+
CONFIG_PCIUTILS=y
74+
75+
# --- Remote attestation support (TPM 1.2) ------------------------------------
76+
export CONFIG_TPM=y
77+
CONFIG_POPT=y
78+
CONFIG_QRENCODE=y
79+
CONFIG_TPMTOTP=y
80+
# HOTP-based remote attestation for a USB security dongle
81+
# (Nitrokey Pro 2 / Librem Key). Enable in a -hotp-maximized variant.
82+
#CONFIG_HOTPKEY=y
83+
84+
# --- Platform locking finalization (PR0) -------------------------------------
85+
# Prevents SPI from being writeable outside of Heads.
86+
CONFIG_IO386=y
87+
export CONFIG_FINALIZE_PLATFORM_LOCKING=y
88+
89+
# --- GUI Support (FBWhiptail-based, graphical) -------------------------------
90+
CONFIG_CAIRO=y
91+
CONFIG_FBWHIPTAIL=y
92+
93+
# --- Additional hardware support for the Linux payload -----------------------
94+
# USB support is mandatory on this board: it has no built-in keyboard.
95+
# CONFIG_USB_KEYBOARD_REQUIRED forces the xHCI/EHCI/HID drivers to be built
96+
# into the kernel (=y) rather than as loadable modules (=m), so they are
97+
# available immediately at boot -- before the initrd runs. Without this, USB
98+
# keyboards and mice (including wireless dongles) are dead in the Heads menu.
99+
export CONFIG_USB_KEYBOARD_REQUIRED=y
100+
CONFIG_LINUX_USB=y
101+
CONFIG_LINUX_E1000E=y
102+
CONFIG_MOBILE_TETHERING=y
103+
104+
# --- Additional tools (tools.cpio) -------------------------------------------
105+
# SSH server (requires ethernet drivers, e.g. CONFIG_LINUX_E1000E above)
106+
CONFIG_DROPBEAR=y
107+
108+
# --- Runtime configuration ---------------------------------------------------
109+
export CONFIG_AUTO_BOOT_TIMEOUT=5
110+
export CONFIG_DEBUG_OUTPUT=n
111+
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n
112+
export CONFIG_TPM2_CAPTURE_PCAP=n
113+
export CONFIG_QUIET_MODE=y
114+
export CONFIG_BOOTSCRIPT=/bin/gui-init.sh
115+
export CONFIG_BOOT_REQ_HASH=n
116+
export CONFIG_BOOT_REQ_ROLLBACK=n
117+
# Kernel cmdline tweaks for the Heads payload kernel (not the target OS kernel)
118+
export CONFIG_BOOT_KERNEL_ADD=""
119+
export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off"
120+
# Default boot device; adjust to the target OS installation.
121+
export CONFIG_BOOT_DEV="/dev/sda1"
122+
export CONFIG_BOARD_NAME="Dell OptiPlex 9020 SFF"
123+
export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal"
124+
125+
# --- Board targets -----------------------------------------------------------
126+
# The 9020 SFF uses two SPI chips: an 8 MB bottom chip (IFD + ME + part of
127+
# coreboot) and a 4 MB top chip (rest of coreboot + reset vector). The build
128+
# produces two files: *-bottom.rom and *-top.rom.
129+
BOARD_TARGETS += split_8mb4mb

0 commit comments

Comments
 (0)