Add support for multiple winbond chip versions
This commit is contained in:
@@ -20,6 +20,12 @@ SIZE_4MB=4194304
|
|||||||
SIZE_8MB=8388608
|
SIZE_8MB=8388608
|
||||||
SIZE_12MB=12582912
|
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 <chipname>.
|
||||||
|
CHIP_4MB="${CHIP_4MB:-}"
|
||||||
|
CHIP_8MB="${CHIP_8MB:-}"
|
||||||
|
|
||||||
# Detect the Linux distribution
|
# Detect the Linux distribution
|
||||||
detect_distro() {
|
detect_distro() {
|
||||||
if [ -f /etc/os-release ]; then
|
if [ -f /etc/os-release ]; then
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Step: Verify BIOS backup integrity (with per-chip retry)
|
# 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() {
|
_reread_chip() {
|
||||||
_label="$1" # "4mb" or "8mb"
|
_label="$1" # "4mb" or "8mb"
|
||||||
_desc="$2" # human-readable description
|
_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
|
while true; do
|
||||||
warn "$_desc reads do NOT match. The chip may not be reading reliably."
|
warn "$_desc reads do NOT match. The chip may not be reading reliably."
|
||||||
@@ -17,9 +24,9 @@ _reread_chip() {
|
|||||||
case "$_choice" in
|
case "$_choice" in
|
||||||
1)
|
1)
|
||||||
info "Re-reading $_desc chip (read 1 of 2)..."
|
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)..."
|
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
|
if diff "${_label}_backup1.bin" "${_label}_backup2.bin" >/dev/null 2>&1; then
|
||||||
success "$_desc reads now match."
|
success "$_desc reads now match."
|
||||||
return 0
|
return 0
|
||||||
@@ -41,14 +48,14 @@ step_backup_bios() {
|
|||||||
if diff 4mb_backup1.bin 4mb_backup2.bin >/dev/null 2>&1; then
|
if diff 4mb_backup1.bin 4mb_backup2.bin >/dev/null 2>&1; then
|
||||||
success "4MB chip reads are identical."
|
success "4MB chip reads are identical."
|
||||||
else
|
else
|
||||||
_reread_chip "4mb" "4MB (top)" || return 1
|
_reread_chip "4mb" "4MB (top)" "$CHIP_4MB" || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
info "Verifying 8MB chip reads match..."
|
info "Verifying 8MB chip reads match..."
|
||||||
if diff 8mb_backup1.bin 8mb_backup2.bin >/dev/null 2>&1; then
|
if diff 8mb_backup1.bin 8mb_backup2.bin >/dev/null 2>&1; then
|
||||||
success "8MB chip reads are identical."
|
success "8MB chip reads are identical."
|
||||||
else
|
else
|
||||||
_reread_chip "8mb" "8MB (bottom)" || return 1
|
_reread_chip "8mb" "8MB (bottom)" "$CHIP_8MB" || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate file sizes
|
# Validate file sizes
|
||||||
|
|||||||
@@ -4,16 +4,93 @@
|
|||||||
# Order rationale: read 4MB (top) chip first — smaller, faster,
|
# Order rationale: read 4MB (top) chip first — smaller, faster,
|
||||||
# surfaces setup issues (clip alignment, voltage, ribbon) sooner.
|
# 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.
|
# Read a chip with inline retry on failure.
|
||||||
# $1 = output filename
|
# $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() {
|
_read_with_retry() {
|
||||||
_out="$1"
|
_out="$1"
|
||||||
_label="$2"
|
_label="$2"
|
||||||
|
_chip="$3"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
info "Reading $_label ..."
|
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
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -56,9 +133,10 @@ step_extract_bios() {
|
|||||||
info "Align the red ribbon wire with the dot/notch on the chip (pin 1)."
|
info "Align the red ribbon wire with the dot/notch on the chip (pin 1)."
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
_read_with_retry "4mb_backup1.bin" "4MB chip (read 1 of 2)" || return 1
|
_resolve_chip CHIP_4MB || return 1
|
||||||
_read_with_retry "4mb_backup2.bin" "4MB chip (read 2 of 2)" || return 1
|
_read_with_retry "4mb_backup1.bin" "4MB chip (read 1 of 2)" "$CHIP_4MB" || return 1
|
||||||
success "4MB chip reads complete."
|
_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 ---
|
# --- 8MB chip ---
|
||||||
echo ""
|
echo ""
|
||||||
@@ -68,7 +146,8 @@ step_extract_bios() {
|
|||||||
info "Re-check pin 1 alignment before pressing down."
|
info "Re-check pin 1 alignment before pressing down."
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
_read_with_retry "8mb_backup1.bin" "8MB chip (read 1 of 2)" || return 1
|
_resolve_chip CHIP_8MB || return 1
|
||||||
_read_with_retry "8mb_backup2.bin" "8MB chip (read 2 of 2)" || return 1
|
_read_with_retry "8mb_backup1.bin" "8MB chip (read 1 of 2)" "$CHIP_8MB" || return 1
|
||||||
success "8MB chip reads complete."
|
_read_with_retry "8mb_backup2.bin" "8MB chip (read 2 of 2)" "$CHIP_8MB" || return 1
|
||||||
|
success "8MB chip reads complete ($CHIP_8MB)."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,11 @@ step_flash_bios() {
|
|||||||
info "Attach the programmer to the 4MB (top) chip."
|
info "Attach the programmer to the 4MB (top) chip."
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
info "Flashing 4MB chip..."
|
if [ -z "$CHIP_4MB" ]; then
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -w top.rom" || return 1
|
_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."
|
success "4MB chip flashed."
|
||||||
|
|
||||||
# Flash 8MB (bottom) chip
|
# Flash 8MB (bottom) chip
|
||||||
@@ -51,8 +54,11 @@ step_flash_bios() {
|
|||||||
info "Now attach the programmer to the 8MB (bottom) chip."
|
info "Now attach the programmer to the 8MB (bottom) chip."
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
info "Flashing 8MB chip..."
|
if [ -z "$CHIP_8MB" ]; then
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -w bottom.rom" || return 1
|
_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."
|
success "8MB chip flashed."
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@@ -49,8 +49,11 @@ _revert_external() {
|
|||||||
info "Attach the programmer to the 4MB (top) chip."
|
info "Attach the programmer to the 4MB (top) chip."
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
info "Flashing original 4MB chip..."
|
if [ -z "$CHIP_4MB" ]; then
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -w top.rom" || return 1
|
_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."
|
success "4MB chip restored."
|
||||||
|
|
||||||
# Flash 8MB (bottom) chip
|
# Flash 8MB (bottom) chip
|
||||||
@@ -58,8 +61,11 @@ _revert_external() {
|
|||||||
info "Now attach the programmer to the 8MB (bottom) chip."
|
info "Now attach the programmer to the 8MB (bottom) chip."
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
info "Flashing original 8MB chip..."
|
if [ -z "$CHIP_8MB" ]; then
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -w bottom.rom" || return 1
|
_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."
|
success "8MB chip restored."
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
Reference in New Issue
Block a user