Rework programmer detection; add image support

This commit is contained in:
2026-04-14 09:08:44 -07:00
parent 21af45674e
commit 52999f4799
5 changed files with 166 additions and 42 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ run_full_install() {
_start="${1:-1}"
[ "$_start" -le 1 ] && run_step 1 "Install Dependencies" install_dependencies
[ "$_start" -le 2 ] && run_step 2 "Verify CH341A Programmer" step_attach_ch341a
[ "$_start" -le 2 ] && run_step 2 "Connect CH341A Programmer" step_attach_ch341a
[ "$_start" -le 3 ] && run_step 3 "Extract Original BIOS" step_extract_bios
[ "$_start" -le 4 ] && run_step 4 "Verify BIOS Backups" step_backup_bios
[ "$_start" -le 5 ] && run_step 5 "Combine BIOS Images" step_combine_bios
+37 -15
View File
@@ -1,31 +1,53 @@
#!/bin/sh
# Step: Verify CH341A programmer connection
# Step: Confirm CH341A programmer is connected to USB
# CH341A USB vendor:product ID
CH341A_USB_ID="1a86:5512"
step_attach_ch341a() {
section "Verify CH341A Programmer"
section "Connect CH341A Programmer"
info "Make sure your CH341A programmer is:"
echo " 1. Connected to your computer via USB"
echo " 2. Set to 3.3V (NOT 5V!)"
echo " 3. Ribbon cable seated in the correct orientation"
info "Before continuing:"
echo " 1. Plug the CH341A into a USB port"
echo " 2. Set the voltage jumper to 3.3V (NEVER 5V)"
echo " 3. Leave the SOIC-8 clip UNATTACHED for now"
echo ""
warn "Using 5V WILL permanently damage the BIOS chips on the T440p."
echo ""
info "Clip orientation rules (applies later when reading/writing chips):"
echo " - The red wire on the ribbon = pin 1"
echo " - The dot/notch on the EEPROM chip = pin 1"
echo " - These MUST align, or the chip will be misread or damaged"
echo ""
# Show reference image (cached locally, rendered inline if possible)
show_image "spi_flasher_assembly.png" "Reference: CH341A + SOIC-8 clip assembly"
echo ""
warn "Using 5V WILL damage your BIOS chip permanently!"
prompt_continue
info "Checking if flashrom detects the CH341A programmer..."
if run_cmd "flashrom --programmer ch341a_spi"; then
success "CH341A programmer detected!"
info "Checking USB for CH341A (id $CH341A_USB_ID)..."
if ! check_command lsusb; then
warn "lsusb not found. Install usbutils to enable programmer detection."
if prompt_yes_default "Continue without USB verification?"; then
return 0
fi
return 1
fi
if lsusb | grep -qi "$CH341A_USB_ID"; then
success "CH341A detected on USB bus."
return 0
fi
error "CH341A programmer not detected."
error "CH341A not found on USB bus."
echo ""
echo " Troubleshooting:"
echo " - Ensure the programmer is plugged in"
echo " - Try a different USB port"
echo " - Check the driver: lsusb | grep 1a86:5512"
echo " - Make sure you have permissions (try with sudo)"
echo " - Re-plug the programmer (try a different USB port)"
echo " - Check with: lsusb | grep $CH341A_USB_ID"
echo " - If lsusb sees it under a different ID, the device may be"
echo " a clone with different firmware — note the ID and retry"
echo ""
if prompt_yes_no "Retry detection?"; then
+53 -20
View File
@@ -1,41 +1,74 @@
#!/bin/sh
# Step: Extract original BIOS from both EEPROM chips
#
# Order rationale: read 4MB (top) chip first — smaller, faster,
# surfaces setup issues (clip alignment, voltage, ribbon) sooner.
# Read a chip with inline retry on failure.
# $1 = output filename
# $2 = human label (e.g. "4MB (top) — read 1 of 2")
_read_with_retry() {
_out="$1"
_label="$2"
while true; do
info "Reading $_label ..."
if run_cmd "sudo flashrom --programmer ch341a_spi -r $_out"; then
return 0
fi
echo ""
warn "Read failed. Most common causes:"
echo " - Clip not seated flush on chip (try pressing down gently)"
echo " - Pin 1 misaligned (red wire must match chip's dot/notch)"
echo " - Laptop still has residual power (remove battery + CMOS)"
echo " - Cheap SOIC-8 clips can make intermittent contact"
echo ""
echo " 1) Re-seat clip and retry"
echo " 2) Abort"
echo ""
printf "${CYAN}Choice [1-2]:${NC} "
read -r _choice
case "$_choice" in
1) continue ;;
*) return 1 ;;
esac
done
}
step_extract_bios() {
section "Extract Original BIOS"
info "The T440p has two EEPROM chips that need to be read:"
echo " - 4MB (top) chip"
echo " - 8MB (bottom) chip"
info "The T440p has two EEPROM chips beside the SODIMM slots:"
echo " - 4MB (top) — smaller SOIC-8, farther from CPU"
echo " - 8MB (bottom) — larger SOIC-8, closer to CPU (holds ME firmware)"
echo ""
info "Each chip is read twice so we can diff the results and catch flaky reads."
echo ""
# Show reference image for chip locations
show_image "eeprom_chips_location.png" "Reference: EEPROM chip locations on T440p mainboard"
echo ""
info "Each chip will be read twice to verify data integrity."
warn "Make sure the programmer is attached to the correct chip!"
cd "$WORK_DIR" || return 1
# --- 4MB chip ---
# --- 4MB chip (do first: smaller = faster iteration on setup) ---
echo ""
info "Attach the programmer to the 4MB (top) chip."
info "Clip the CH341A onto the ${BOLD}4MB (top)${NC} chip."
info "Align the red ribbon wire with the dot/notch on the chip (pin 1)."
prompt_continue
info "Reading 4MB chip (read 1 of 2)..."
run_cmd "sudo flashrom --programmer ch341a_spi -r 4mb_backup1.bin" || return 1
info "Reading 4MB chip (read 2 of 2)..."
run_cmd "sudo flashrom --programmer ch341a_spi -r 4mb_backup2.bin" || return 1
_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."
# --- 8MB chip ---
echo ""
info "Now attach the programmer to the 8MB (bottom) chip."
info "Now move the clip to the ${BOLD}8MB (bottom)${NC} chip."
info "Re-check pin 1 alignment before pressing down."
prompt_continue
info "Reading 8MB chip (read 1 of 2)..."
run_cmd "sudo flashrom --programmer ch341a_spi -r 8mb_backup1.bin" || return 1
info "Reading 8MB chip (read 2 of 2)..."
run_cmd "sudo flashrom --programmer ch341a_spi -r 8mb_backup2.bin" || return 1
_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."
}
+7 -6
View File
@@ -7,31 +7,32 @@ install_dependencies() {
case "$DISTRO" in
arch)
info "Installing packages via pacman..."
run_cmd "sudo pacman -S --needed base-devel curl git gcc-ada ncurses zlib nasm sharutils unzip flashrom"
run_cmd "sudo pacman -S --needed base-devel curl git gcc-ada ncurses zlib nasm sharutils unzip flashrom usbutils chafa"
;;
debian)
info "Installing packages via apt..."
run_cmd "sudo apt update"
run_cmd "sudo apt install -y build-essential curl git gnat libncurses-dev zlib1g-dev nasm sharutils unzip flashrom"
run_cmd "sudo apt install -y build-essential curl git gnat libncurses-dev zlib1g-dev nasm sharutils unzip flashrom usbutils chafa"
;;
fedora)
info "Installing packages via dnf..."
run_cmd "sudo dnf install -y @development-tools curl git gcc-gnat ncurses-devel zlib-devel nasm sharutils unzip flashrom"
run_cmd "sudo dnf install -y @development-tools curl git gcc-gnat ncurses-devel zlib-devel nasm sharutils unzip flashrom usbutils chafa"
;;
gentoo)
info "Installing packages via emerge..."
run_cmd "sudo emerge --ask sys-devel/base-devel net-misc/curl dev-vcs/git sys-devel/gcc ncurses dev-libs/zlib dev-lang/nasm app-arch/sharutils app-arch/unzip sys-apps/flashrom"
run_cmd "sudo emerge --ask sys-devel/base-devel net-misc/curl dev-vcs/git sys-devel/gcc ncurses dev-libs/zlib dev-lang/nasm app-arch/sharutils app-arch/unzip sys-apps/flashrom sys-apps/usbutils media-gfx/chafa"
;;
nix)
info "Installing packages via nix-env..."
run_cmd "nix-env -i stdenv curl git gcc gnat ncurses zlib nasm sharutils unzip flashrom"
run_cmd "nix-env -i stdenv curl git gcc gnat ncurses zlib nasm sharutils unzip flashrom usbutils chafa"
;;
*)
warn "Could not detect your distribution."
echo ""
echo " Please install these packages manually:"
echo " build-essential/base-devel, curl, git, gcc-ada/gnat,"
echo " ncurses, zlib, nasm, sharutils, unzip, flashrom"
echo " ncurses, zlib, nasm, sharutils, unzip, flashrom, usbutils"
echo " Optional: chafa (for inline image previews in this script)"
echo ""
prompt_continue
return 0
+68
View File
@@ -79,6 +79,74 @@ run_cmd() {
return $_status
}
# --- Inline image rendering ---
# Base URL for blog assets (override via env if needed).
IMAGE_BASE_URL="${IMAGE_BASE_URL:-https://timmypidashev.dev/blog/thinkpad-t440p-coreboot-guide}"
# Attempt to render $1 inline. Returns 0 on success, 1 if no supported backend.
_render_image() {
_path="$1"
# chafa handles kitty / iterm2 / sixel / ANSI fallback automatically
if check_command chafa; then
chafa --size=60x25 "$_path" 2>/dev/null && return 0
fi
# Native kitty icat
if [ -n "$KITTY_WINDOW_ID" ] && check_command kitty; then
kitty +kitten icat --align=left "$_path" 2>/dev/null && return 0
fi
# iTerm2 / WezTerm inline image protocol
case "$TERM_PROGRAM" in
iTerm.app|WezTerm)
if check_command base64; then
_b64=$(base64 < "$_path" | tr -d '\n')
_sz=$(wc -c < "$_path")
printf '\033]1337;File=inline=1;size=%s:%s\a\n' "$_sz" "$_b64"
return 0
fi
;;
esac
return 1
}
# show_image <filename> [caption]
# Downloads $IMAGE_BASE_URL/<filename> into $WORK_DIR/.images/,
# renders inline if possible, otherwise prints the URL.
show_image() {
_name="$1"
_caption="$2"
_url="$IMAGE_BASE_URL/$_name"
_cache="${WORK_DIR:-/tmp}/.images"
_local="$_cache/$_name"
mkdir -p "$_cache"
if [ ! -f "$_local" ]; then
if ! curl -fsSL "$_url" -o "$_local" 2>/dev/null; then
rm -f "$_local"
info "Reference image: $_url"
[ -n "$_caption" ] && info "$_caption"
return 1
fi
fi
if _render_image "$_local"; then
[ -n "$_caption" ] && printf " ${DIM}%s${NC}\n" "$_caption"
return 0
fi
# No renderer available
info "Reference image: $_url"
if ! check_command chafa; then
info "(Install 'chafa' for inline image previews: sudo pacman -S chafa)"
fi
[ -n "$_caption" ] && info "$_caption"
}
# Handle step failure - ask user how to proceed
handle_failure() {
echo ""