Rework programmer detection; add image support
This commit is contained in:
@@ -72,7 +72,7 @@ run_full_install() {
|
|||||||
_start="${1:-1}"
|
_start="${1:-1}"
|
||||||
|
|
||||||
[ "$_start" -le 1 ] && run_step 1 "Install Dependencies" install_dependencies
|
[ "$_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 3 ] && run_step 3 "Extract Original BIOS" step_extract_bios
|
||||||
[ "$_start" -le 4 ] && run_step 4 "Verify BIOS Backups" step_backup_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
|
[ "$_start" -le 5 ] && run_step 5 "Combine BIOS Images" step_combine_bios
|
||||||
|
|||||||
@@ -1,31 +1,53 @@
|
|||||||
#!/bin/sh
|
#!/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() {
|
step_attach_ch341a() {
|
||||||
section "Verify CH341A Programmer"
|
section "Connect CH341A Programmer"
|
||||||
|
|
||||||
info "Make sure your CH341A programmer is:"
|
info "Before continuing:"
|
||||||
echo " 1. Connected to your computer via USB"
|
echo " 1. Plug the CH341A into a USB port"
|
||||||
echo " 2. Set to 3.3V (NOT 5V!)"
|
echo " 2. Set the voltage jumper to 3.3V (NEVER 5V)"
|
||||||
echo " 3. Ribbon cable seated in the correct orientation"
|
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 ""
|
echo ""
|
||||||
warn "Using 5V WILL damage your BIOS chip permanently!"
|
|
||||||
|
|
||||||
prompt_continue
|
prompt_continue
|
||||||
|
|
||||||
info "Checking if flashrom detects the CH341A programmer..."
|
info "Checking USB for CH341A (id $CH341A_USB_ID)..."
|
||||||
if run_cmd "flashrom --programmer ch341a_spi"; then
|
|
||||||
success "CH341A programmer detected!"
|
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
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
error "CH341A programmer not detected."
|
error "CH341A not found on USB bus."
|
||||||
echo ""
|
echo ""
|
||||||
echo " Troubleshooting:"
|
echo " Troubleshooting:"
|
||||||
echo " - Ensure the programmer is plugged in"
|
echo " - Re-plug the programmer (try a different USB port)"
|
||||||
echo " - Try a different USB port"
|
echo " - Check with: lsusb | grep $CH341A_USB_ID"
|
||||||
echo " - Check the driver: lsusb | grep 1a86:5512"
|
echo " - If lsusb sees it under a different ID, the device may be"
|
||||||
echo " - Make sure you have permissions (try with sudo)"
|
echo " a clone with different firmware — note the ID and retry"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
if prompt_yes_no "Retry detection?"; then
|
if prompt_yes_no "Retry detection?"; then
|
||||||
|
|||||||
@@ -1,41 +1,74 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Step: Extract original BIOS from both EEPROM chips
|
# 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() {
|
step_extract_bios() {
|
||||||
section "Extract Original BIOS"
|
section "Extract Original BIOS"
|
||||||
|
|
||||||
info "The T440p has two EEPROM chips that need to be read:"
|
info "The T440p has two EEPROM chips beside the SODIMM slots:"
|
||||||
echo " - 4MB (top) chip"
|
echo " - 4MB (top) — smaller SOIC-8, farther from CPU"
|
||||||
echo " - 8MB (bottom) chip"
|
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 ""
|
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
|
cd "$WORK_DIR" || return 1
|
||||||
|
|
||||||
# --- 4MB chip ---
|
# --- 4MB chip (do first: smaller = faster iteration on setup) ---
|
||||||
echo ""
|
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
|
prompt_continue
|
||||||
|
|
||||||
info "Reading 4MB chip (read 1 of 2)..."
|
_read_with_retry "4mb_backup1.bin" "4MB chip (read 1 of 2)" || return 1
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -r 4mb_backup1.bin" || return 1
|
_read_with_retry "4mb_backup2.bin" "4MB chip (read 2 of 2)" || return 1
|
||||||
|
|
||||||
info "Reading 4MB chip (read 2 of 2)..."
|
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -r 4mb_backup2.bin" || return 1
|
|
||||||
|
|
||||||
success "4MB chip reads complete."
|
success "4MB chip reads complete."
|
||||||
|
|
||||||
# --- 8MB chip ---
|
# --- 8MB chip ---
|
||||||
echo ""
|
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
|
prompt_continue
|
||||||
|
|
||||||
info "Reading 8MB chip (read 1 of 2)..."
|
_read_with_retry "8mb_backup1.bin" "8MB chip (read 1 of 2)" || return 1
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -r 8mb_backup1.bin" || return 1
|
_read_with_retry "8mb_backup2.bin" "8MB chip (read 2 of 2)" || return 1
|
||||||
|
|
||||||
info "Reading 8MB chip (read 2 of 2)..."
|
|
||||||
run_cmd "sudo flashrom --programmer ch341a_spi -r 8mb_backup2.bin" || return 1
|
|
||||||
|
|
||||||
success "8MB chip reads complete."
|
success "8MB chip reads complete."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,31 +7,32 @@ install_dependencies() {
|
|||||||
case "$DISTRO" in
|
case "$DISTRO" in
|
||||||
arch)
|
arch)
|
||||||
info "Installing packages via pacman..."
|
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)
|
debian)
|
||||||
info "Installing packages via apt..."
|
info "Installing packages via apt..."
|
||||||
run_cmd "sudo apt update"
|
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)
|
fedora)
|
||||||
info "Installing packages via dnf..."
|
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)
|
gentoo)
|
||||||
info "Installing packages via emerge..."
|
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)
|
nix)
|
||||||
info "Installing packages via nix-env..."
|
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."
|
warn "Could not detect your distribution."
|
||||||
echo ""
|
echo ""
|
||||||
echo " Please install these packages manually:"
|
echo " Please install these packages manually:"
|
||||||
echo " build-essential/base-devel, curl, git, gcc-ada/gnat,"
|
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 ""
|
echo ""
|
||||||
prompt_continue
|
prompt_continue
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -79,6 +79,74 @@ run_cmd() {
|
|||||||
return $_status
|
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 step failure - ask user how to proceed
|
||||||
handle_failure() {
|
handle_failure() {
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
Reference in New Issue
Block a user