diff --git a/coreboot-t440p/config.sh b/coreboot-t440p/config.sh index b094335..235d81f 100755 --- a/coreboot-t440p/config.sh +++ b/coreboot-t440p/config.sh @@ -20,6 +20,12 @@ SIZE_4MB=4194304 SIZE_8MB=8388608 SIZE_12MB=12582912 +# Resolved flashrom chip names (set at runtime by _resolve_chip). +# Needed because some Winbond variants share a silicon ID and flashrom +# refuses to pick one without an explicit -c . +CHIP_4MB="${CHIP_4MB:-}" +CHIP_8MB="${CHIP_8MB:-}" + # Detect the Linux distribution detect_distro() { if [ -f /etc/os-release ]; then diff --git a/coreboot-t440p/steps/backup_bios.sh b/coreboot-t440p/steps/backup_bios.sh index 7f4901b..2ad9990 100755 --- a/coreboot-t440p/steps/backup_bios.sh +++ b/coreboot-t440p/steps/backup_bios.sh @@ -1,10 +1,17 @@ #!/bin/sh # Step: Verify BIOS backup integrity (with per-chip retry) -# Re-read a single chip until two reads match or user gives up +# Re-read a single chip until two reads match or user gives up. +# Uses the chip variant resolved during extraction (CHIP_4MB / CHIP_8MB). _reread_chip() { _label="$1" # "4mb" or "8mb" _desc="$2" # human-readable description + _chip="$3" # flashrom -c chip name + + if [ -z "$_chip" ]; then + error "No chip variant recorded for $_desc. Re-run the extract step." + return 1 + fi while true; do warn "$_desc reads do NOT match. The chip may not be reading reliably." @@ -17,9 +24,9 @@ _reread_chip() { case "$_choice" in 1) info "Re-reading $_desc chip (read 1 of 2)..." - run_cmd "sudo flashrom --programmer ch341a_spi -r ${_label}_backup1.bin" || return 1 + run_cmd "sudo flashrom --programmer ch341a_spi -c \"$_chip\" -r ${_label}_backup1.bin" || return 1 info "Re-reading $_desc chip (read 2 of 2)..." - run_cmd "sudo flashrom --programmer ch341a_spi -r ${_label}_backup2.bin" || return 1 + run_cmd "sudo flashrom --programmer ch341a_spi -c \"$_chip\" -r ${_label}_backup2.bin" || return 1 if diff "${_label}_backup1.bin" "${_label}_backup2.bin" >/dev/null 2>&1; then success "$_desc reads now match." return 0 @@ -41,14 +48,14 @@ step_backup_bios() { if diff 4mb_backup1.bin 4mb_backup2.bin >/dev/null 2>&1; then success "4MB chip reads are identical." else - _reread_chip "4mb" "4MB (top)" || return 1 + _reread_chip "4mb" "4MB (top)" "$CHIP_4MB" || return 1 fi info "Verifying 8MB chip reads match..." if diff 8mb_backup1.bin 8mb_backup2.bin >/dev/null 2>&1; then success "8MB chip reads are identical." else - _reread_chip "8mb" "8MB (bottom)" || return 1 + _reread_chip "8mb" "8MB (bottom)" "$CHIP_8MB" || return 1 fi # Validate file sizes diff --git a/coreboot-t440p/steps/extract_bios.sh b/coreboot-t440p/steps/extract_bios.sh index 12118b2..032571c 100755 --- a/coreboot-t440p/steps/extract_bios.sh +++ b/coreboot-t440p/steps/extract_bios.sh @@ -4,16 +4,93 @@ # Order rationale: read 4MB (top) chip first — smaller, faster, # surfaces setup issues (clip alignment, voltage, ribbon) sooner. +# Probe the currently-clipped chip and resolve the flashrom chip name. +# $1 = variable name to populate (e.g. "CHIP_4MB") +# Handles the "Multiple flash chip definitions match" case by prompting. +_resolve_chip() { + _var="$1" + + eval _cur=\"\$$_var\" + if [ -n "$_cur" ]; then + info "Using previously-selected chip for this size: $_cur" + return 0 + fi + + _log=$(mktemp) + printf " ${DIM}\$ sudo flashrom --programmer ch341a_spi${NC}\n" + sudo flashrom --programmer ch341a_spi >"$_log" 2>&1 + _st=$? + + # Unambiguous success: one "Found ... chip \"NAME\"" line, exit 0. + if [ $_st -eq 0 ]; then + _chip=$(sed -nE 's/.*Found .* flash chip "([^"]+)".*/\1/p' "$_log" | head -1) + if [ -n "$_chip" ]; then + eval "$_var=\"\$_chip\"" + info "Detected chip: $_chip" + rm -f "$_log" + return 0 + fi + fi + + # Ambiguous match: flashrom lists candidates but refuses to pick. + if grep -q "Multiple flash chip definitions match" "$_log"; then + _candidates=$(sed -nE 's/.*Found .* flash chip "([^"]+)".*/\1/p' "$_log") + _count=$(printf '%s\n' "$_candidates" | wc -l | tr -d ' ') + echo "" + warn "Flashrom read the chip but multiple variants match the same silicon ID." + info "This is normal for Winbond W25Q* parts. Pick one (the newest is safe):" + echo "" + _i=1 + for _c in $_candidates; do + if [ "$_i" = "$_count" ]; then + echo " $_i) $_c ${DIM}(default — newest)${NC}" + else + echo " $_i) $_c" + fi + _i=$((_i+1)) + done + echo "" + + _picked="" + while [ -z "$_picked" ]; do + printf "${CYAN}Choice [1-%s] (Enter = %s):${NC} " "$_count" "$_count" + read -r _sel + [ -z "$_sel" ] && _sel="$_count" + case "$_sel" in + ''|*[!0-9]*) echo "Enter a number."; continue ;; + esac + if [ "$_sel" -lt 1 ] || [ "$_sel" -gt "$_count" ]; then + echo "Out of range." + continue + fi + _picked=$(printf '%s\n' "$_candidates" | sed -n "${_sel}p") + done + eval "$_var=\"\$_picked\"" + info "Using chip definition: $_picked" + rm -f "$_log" + return 0 + fi + + # Real failure (no chip, clip bad, etc.) — show the log and fail. + echo "" + error "Chip probe failed. flashrom output:" + sed 's/^/ /' "$_log" + rm -f "$_log" + return 1 +} + # Read a chip with inline retry on failure. # $1 = output filename -# $2 = human label (e.g. "4MB (top) — read 1 of 2") +# $2 = human label +# $3 = chip name (from _resolve_chip) _read_with_retry() { _out="$1" _label="$2" + _chip="$3" while true; do info "Reading $_label ..." - if run_cmd "sudo flashrom --programmer ch341a_spi -r $_out"; then + if run_cmd "sudo flashrom --programmer ch341a_spi -c \"$_chip\" -r $_out"; then return 0 fi @@ -56,9 +133,10 @@ step_extract_bios() { info "Align the red ribbon wire with the dot/notch on the chip (pin 1)." prompt_continue - _read_with_retry "4mb_backup1.bin" "4MB chip (read 1 of 2)" || return 1 - _read_with_retry "4mb_backup2.bin" "4MB chip (read 2 of 2)" || return 1 - success "4MB chip reads complete." + _resolve_chip CHIP_4MB || return 1 + _read_with_retry "4mb_backup1.bin" "4MB chip (read 1 of 2)" "$CHIP_4MB" || return 1 + _read_with_retry "4mb_backup2.bin" "4MB chip (read 2 of 2)" "$CHIP_4MB" || return 1 + success "4MB chip reads complete ($CHIP_4MB)." # --- 8MB chip --- echo "" @@ -68,7 +146,8 @@ step_extract_bios() { info "Re-check pin 1 alignment before pressing down." prompt_continue - _read_with_retry "8mb_backup1.bin" "8MB chip (read 1 of 2)" || return 1 - _read_with_retry "8mb_backup2.bin" "8MB chip (read 2 of 2)" || return 1 - success "8MB chip reads complete." + _resolve_chip CHIP_8MB || return 1 + _read_with_retry "8mb_backup1.bin" "8MB chip (read 1 of 2)" "$CHIP_8MB" || return 1 + _read_with_retry "8mb_backup2.bin" "8MB chip (read 2 of 2)" "$CHIP_8MB" || return 1 + success "8MB chip reads complete ($CHIP_8MB)." } diff --git a/coreboot-t440p/steps/flash_bios.sh b/coreboot-t440p/steps/flash_bios.sh index 320fe4b..9974e0f 100755 --- a/coreboot-t440p/steps/flash_bios.sh +++ b/coreboot-t440p/steps/flash_bios.sh @@ -42,8 +42,11 @@ step_flash_bios() { info "Attach the programmer to the 4MB (top) chip." prompt_continue - info "Flashing 4MB chip..." - run_cmd "sudo flashrom --programmer ch341a_spi -w top.rom" || return 1 + if [ -z "$CHIP_4MB" ]; then + _resolve_chip CHIP_4MB || return 1 + fi + info "Flashing 4MB chip ($CHIP_4MB)..." + run_cmd "sudo flashrom --programmer ch341a_spi -c \"$CHIP_4MB\" -w top.rom" || return 1 success "4MB chip flashed." # Flash 8MB (bottom) chip @@ -51,8 +54,11 @@ step_flash_bios() { info "Now attach the programmer to the 8MB (bottom) chip." prompt_continue - info "Flashing 8MB chip..." - run_cmd "sudo flashrom --programmer ch341a_spi -w bottom.rom" || return 1 + if [ -z "$CHIP_8MB" ]; then + _resolve_chip CHIP_8MB || return 1 + fi + info "Flashing 8MB chip ($CHIP_8MB)..." + run_cmd "sudo flashrom --programmer ch341a_spi -c \"$CHIP_8MB\" -w bottom.rom" || return 1 success "8MB chip flashed." echo "" diff --git a/coreboot-t440p/steps/revert_bios.sh b/coreboot-t440p/steps/revert_bios.sh index 1fd835c..956e9fc 100755 --- a/coreboot-t440p/steps/revert_bios.sh +++ b/coreboot-t440p/steps/revert_bios.sh @@ -49,8 +49,11 @@ _revert_external() { info "Attach the programmer to the 4MB (top) chip." prompt_continue - info "Flashing original 4MB chip..." - run_cmd "sudo flashrom --programmer ch341a_spi -w top.rom" || return 1 + if [ -z "$CHIP_4MB" ]; then + _resolve_chip CHIP_4MB || return 1 + fi + info "Flashing original 4MB chip ($CHIP_4MB)..." + run_cmd "sudo flashrom --programmer ch341a_spi -c \"$CHIP_4MB\" -w top.rom" || return 1 success "4MB chip restored." # Flash 8MB (bottom) chip @@ -58,8 +61,11 @@ _revert_external() { info "Now attach the programmer to the 8MB (bottom) chip." prompt_continue - info "Flashing original 8MB chip..." - run_cmd "sudo flashrom --programmer ch341a_spi -w bottom.rom" || return 1 + if [ -z "$CHIP_8MB" ]; then + _resolve_chip CHIP_8MB || return 1 + fi + info "Flashing original 8MB chip ($CHIP_8MB)..." + run_cmd "sudo flashrom --programmer ch341a_spi -c \"$CHIP_8MB\" -w bottom.rom" || return 1 success "8MB chip restored." echo ""