Re: Fwd: Flash firmware clé USB sous debian Trixie

[email protected] Wed, 29 Jul 2026 19:19:12 +0200
Newsgroups gmane.linux.debian.user.french
Message-ID <[email protected]>
salut la liste,

j'ai vibe coder un script de récupération, mais j'ai peur que sans r  
é-écriture du firmware il n'y ai pas grand chose a faire.

je n'ai malheureusement pas d'ordinateur windows pour réparer ce 
firrmware déféctueux, peut-être qu'un firmware libre pour les clé usb 
serai un bonne chose.

ne serai-ce pour lui redonner une seconde vie, mais comme dis Basile 
toute puces sicilium, si elle est de mauvaise qualité s'use, ne serai-ce 
par les échange micro éléctrique.

je poste ici mon script zsh, s'il peut servir a la communauté, il est 
sous GPLv3 :

=======================================================
#!/usr/bin/zsh
# 
=============================================================================
# rescue_transcend.zsh - Script de recuperation pour cle USB Transcend 
JetFlash
# Copyright (C) 2026 Jean-Christophe Enee
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# 
=============================================================================

setopt NO_GLOB_SUBST

export PATH="/usr/bin:/bin:/usr/sbin:/sbin"
HOME_DIR="/home/jean-christophe"
DEFAULT_IMG="$HOME_DIR/transcend_rescue.img"
DEFAULT_LOG="$HOME_DIR/transcend_rescue.log"
MOUNT_POINT="$HOME_DIR/rescue_mount"
USB_VID="8564"
USB_PID="1000"
DEVICE=""
TARGET_IMG=""
TARGET_LOG=""
DRY_RUN=false
FORCE=false

if [[ -t 1 ]]; then
     RED=$'\033[0;31m'
     GREEN=$'\033[0;32m'
     YELLOW=$'\033[1;33m'
     BLUE=$'\033[0;34m'
     NC=$'\033[0m'
else
     RED=""
     GREEN=""
     YELLOW=""
     BLUE=""
     NC=""
fi

log_info() { builtin echo "${GREEN}[INFO]${NC} $1"; }
log_warn() { builtin echo "${YELLOW}[WARNING]${NC} $1"; }
log_error() { builtin echo "${RED}[ERROR]${NC} $1"; }
log_step() { builtin echo "${BLUE}[STEP]${NC} $1"; }

check_root() {
     [[ $EUID -ne 0 ]] && { log_error "Root requis. Utilisez sudo."; exit 
1; }
}

install_dependencies() {
     log_step "Verification des dependances..."
     local packages=("usbutils" "gawk" "coreutils" "gddrescue" 
"util-linux")
     local missing=()
     for pkg in "${packages[@]}"; do
         /usr/bin/dpkg -l "$pkg" 2>/dev/null | /usr/bin/grep -q "^ii" || 
missing+=("$pkg")
     done
     if (( ${#missing} > 0 )); then
         log_info "Installation: ${missing}"
         /usr/bin/apt-get update -qq >/dev/null 2>&1
         /usr/bin/apt-get install -y -qq "${missing[@]}" >/dev/null 2>&1
         for pkg in "${missing[@]}"; do
             /usr/bin/dpkg -l "$pkg" 2>/dev/null | /usr/bin/grep -q "^ii" 
|| { log_error "Echec: $pkg"; exit 1; }
         done
         log_info "Dependances installees."
     else
         log_info "Toutes les dependances sont presentes."
     fi
}

check_commands() {
     local required=(
         "/usr/bin/lsusb"
         "/usr/bin/awk"
         "/usr/bin/cut"
         "/usr/bin/ddrescue"
         "/usr/bin/lsblk"
         "/usr/sbin/blockdev"
         "/usr/bin/mount"
         "/usr/bin/umount"
         "/usr/bin/mountpoint"
         "/usr/bin/grep"
     )
     for cmd in "${required[@]}"; do
         [[ ! -x "$cmd" ]] && { log_error "Commande manquante: 
${cmd##*/}"; exit 1; }
     done
}

setup_mount_point() {
     [[ ! -d "$MOUNT_POINT" ]] && /usr/bin/mkdir -p "$MOUNT_POINT" || { 
log_error "Impossible de creer $MOUNT_POINT"; exit 1; }
}

force_unmount_usb() {
     log_step "Demontage force des peripheriques USB..."
     local devs
     devs=$(/usr/bin/lsblk -d -n -o NAME,TRAN 2>/dev/null | /usr/bin/grep 
-i usb | /usr/bin/awk '{print "/dev/"$1}')
     for dev in $devs; do
         /usr/bin/mountpoint -q "$dev" 2>/dev/null && /usr/bin/umount -f 
"$dev" 2>/dev/null || log_warn "Echec demontage $dev"
     done
     local parts
     parts=$(/usr/bin/lsblk -l -n -o NAME,TRAN 2>/dev/null | 
/usr/bin/grep -i usb | /usr/bin/awk '{print "/dev/"$1}')
     for part in $parts; do
         /usr/bin/mountpoint -q "$part" 2>/dev/null && /usr/bin/umount -f 
"$part" 2>/dev/null || log_warn "Echec demontage $part"
     done
     /usr/bin/sleep 1
}

force_unbind_usb_drivers() {
     log_step "Detachement force des pilotes USB..."
     if [[ -d "/sys/bus/usb/drivers/usb-storage" ]]; then
         for usb_dev in /sys/bus/usb/drivers/usb-storage/*:1.0(N); do
             [[ -e "$usb_dev" ]] && builtin echo "${usb_dev##*/}" > 
/sys/bus/usb/drivers/usb-storage/unbind 2>/dev/null && log_info 
"Detache: ${usb_dev##*/}"
         done
     fi
     if [[ -d "/sys/class/scsi_host" ]]; then
         for scsi_host in /sys/class/scsi_host/host*(N); do
             [[ -e "$scsi_host/scan" ]] && builtin echo "- - -" > 
"$scsi_host/scan" 2>/dev/null && log_info "SCSI reset: ${scsi_host##*/}"
         done
         for scsi_dev in /sys/bus/scsi/devices/*(N); do
             [[ -e "$scsi_dev/delete" ]] && builtin echo 1 > 
"$scsi_dev/delete" 2>/dev/null && log_info "SCSI deconnecte: 
${scsi_dev##*/}"
         done
     else
         log_info "Aucun controleur SCSI (normal)."
     fi
     /usr/bin/sleep 2
}

find_usb_device() {
     local path
     path=$(/usr/bin/lsusb -d "$USB_VID:$USB_PID" 2>/dev/null | 
/usr/bin/awk '{print $2}' | /usr/bin/cut -d: -f1)
     [[ -z "$path" ]] && { log_error "Cle Transcend 
(VID:PID=$USB_VID:$USB_PID) introuvable. Branchez-la."; exit 1; }
     log_info "Cle trouvee en: ${path}:1.0"
}

wait_for_device() {
     local max=20 attempt=1
     while [[ $attempt -le $max ]]; do
         DEVICE=$(/usr/bin/lsblk -d -n -o NAME,TRAN 2>/dev/null | 
/usr/bin/grep -i usb | /usr/bin/head -n1 | /usr/bin/awk '{print 
"/dev/"$1}')
         [[ -n "$DEVICE" && -e "$DEVICE" ]] && { log_info "Peripherique 
detecte: $DEVICE"; return 0; }
         log_step "Attente peripherique ($attempt/$max)..."
         /usr/bin/sleep 2
         ((attempt++))
     done
     log_error "Peripherique USB non detecte."
     return 1
}

bind_usb_storage() {
     local usb_bus
     usb_bus=${DEVICE#/dev/}
     if [[ -n "$usb_bus" && -e 
"/sys/bus/usb/drivers/usb-storage/${usb_bus}:1.0" ]]; then
         builtin echo "${usb_bus}:1.0" > 
/sys/bus/usb/drivers/usb-storage/bind 2>/dev/null && log_info "Pilote 
reattache: ${usb_bus}:1.0" || log_warn "Reattachement impossible pour 
${usb_bus}:1.0"
     else
         log_warn "Reattachement impossible"
     fi
}

check_disk_space() {
     local size_bytes
     size_bytes=$(/usr/sbin/blockdev --getsize64 "$DEVICE" 2>/dev/null || 
builtin echo 0)
     local required_gb=$(( size_bytes / 1073741824 + 1 ))
     local available_gb
     available_gb=$(/usr/bin/df -BG "$HOME_DIR" | /usr/bin/awk 'NR==2 
{print $4}' | /usr/bin/tr -d 'G')
     (( required_gb > available_gb )) && { log_error "Espace insuffisant: 
${required_gb}GB > ${available_gb}GB"; return 1; }
     log_info "Espace OK: ${available_gb}GB (necessaire: 
${required_gb}GB)"
     return 0
}

run_ddrescue() {
     local pass=$1 device=$2 image=$3 mapfile=$4
     local cmd=("/usr/bin/ddrescue")
     case $pass in
         1) cmd+=("-f" "-n"); log_info "Passe 1/3: Lecture rapide des 
secteurs sains" ;;
         2) cmd+=("-f" "-r3"); log_info "Passe 2/3: Relire les secteurs 
defectueux (3 tentatives)" ;;
         3) cmd+=("-f" "-R" "-r3"); log_info "Passe 3/3: Passe inverse 
pour les secteurs problematiques" ;;
         *) { log_error "Passe invalide: $pass"; return 1; }
     esac
     cmd+=("$device" "$image" "$mapfile")
     log_step "Execution ddrescue passe $pass"
     log_step "Commande: ${cmd[*]}"
     if [[ "$DRY_RUN" = false ]]; then
         "${cmd[@]}"
         local rc=$?
         case $rc in
             0) log_info "Passe $pass: succes"; return 0 ;;
             1) log_warn "Passe $pass: erreurs (normal)"; return 0 ;;
             *) log_error "Passe $pass: echouee (code $rc)"; return $rc 
;;
         esac
     else
         log_info "[DRY RUN] ${cmd[*]}"
     fi
}

analyze_log() {
     local logfile="$1"
     [[ ! -f "$logfile" ]] && { log_error "Log introuvable: $logfile"; 
return 1; }
     log_step "Analyse des resultats..."
     local total
     total=$(/usr/sbin/blockdev --getsize64 "$DEVICE" 2>/dev/null || 
builtin echo 0)
     local rescued
     rescued=$(/usr/bin/grep -Eo '[0-9]+ bytes rescued' "$logfile" 
2>/dev/null | /usr/bin/tail -n1 | /usr/bin/grep -Eo '[0-9]+' || builtin 
echo 0)
     local errsize
     errsize=$(/usr/bin/grep -Eo '[0-9]+ bytes errsize' "$logfile" 
2>/dev/null | /usr/bin/tail -n1 | /usr/bin/grep -Eo '[0-9]+' || builtin 
echo 0)
     local err_count
     err_count=$(/usr/bin/grep -c "Error" "$logfile" 2>/dev/null || 
builtin echo 0)
     local pct_rescued=0 pct_failed=0
     (( total > 0 )) && pct_rescued=$(( rescued * 100 / total ))
     (( total > 0 )) && pct_failed=$(( errsize * 100 / total ))
     builtin echo ""
     builtin echo "======================================="
     builtin echo "         RAPPORT DE RECUPERATION"
     builtin echo "======================================="
     builtin echo "Peripherique:     $DEVICE"
     builtin echo "Taille:           $((total / 1073741824)) GB"
     builtin echo "Recuperes:       $((rescued / 1073741824)) GB 
(${pct_rescued}%)"
     builtin echo "Erreurs:         $((errsize / 1073741824)) GB 
(${pct_failed}%)"
     builtin echo "Count erreurs:   $err_count"
     builtin echo "Image:            $TARGET_IMG"
     builtin echo "Log:              $TARGET_LOG"
     builtin echo "======================================="
     builtin echo ""
     if (( pct_rescued >= 90 )); then
         log_info "Succes: ${pct_rescued}%!"
     elif (( pct_rescued >= 50 )); then
         log_warn "Partiel: ${pct_rescued}%."
     else
         log_error "Faible: ${pct_rescued}%."
     fi
}

mount_rescue_image() {
     local img_file="$1" mnt_dir="$MOUNT_POINT/image"
     [[ ! -d "$mnt_dir" ]] && /usr/bin/mkdir -p "$mnt_dir" || { log_error 
"Impossible de creer $mnt_dir"; return 1; }
     if /usr/bin/mount -o ro,loop "$img_file" "$mnt_dir" 2>/dev/null; 
then
         log_info "Image montee: $mnt_dir"
         log_info "Contenu:"
         /usr/bin/ls -la "$mnt_dir" 2>/dev/null | /usr/bin/head -n 10 || 
builtin echo "(Aucun fichier)"
         return 0
     else
         log_warn "Montage impossible (FS corrompu?)."
         log_info "Essayez: sudo apt install testdisk && sudo photorec 
$img_file"
         return 1
     fi
}

main() {
     while [[ $# -gt 0 ]]; do
         case "$1" in
             -h|--help)
                 builtin echo "Usage: sudo $0 [OPTIONS] [image.img] 
[mapfile.log]"
                 builtin echo "OPTIONS: -d (dry-run), -f (force), -h 
(help)"
                 exit 0 ;;
             -d|--dry-run) DRY_RUN=true; shift ;;
             -f|--force) FORCE=true; shift ;;
             *)
                 if [[ -z "$TARGET_IMG" ]]; then
                     TARGET_IMG="$1"
                 elif [[ -z "$TARGET_LOG" ]]; then
                     TARGET_LOG="$1"
                 else
                     log_error "Trop d'arguments."; exit 1
                 fi
                 shift ;;
         esac
     done
     [[ -z "$TARGET_IMG" ]] && TARGET_IMG="$DEFAULT_IMG"
     [[ -z "$TARGET_LOG" ]] && TARGET_LOG="$DEFAULT_LOG"
     check_root
     install_dependencies
     check_commands
     setup_mount_point
     log_info "Debut recuperation Transcend JetFlash 
(VID:PID=$USB_VID:$USB_PID)"
     log_info "Image: $TARGET_IMG"
     log_info "Log: $TARGET_LOG"
     [[ "$DRY_RUN" = true ]] && log_warn "MODE SIMULATION"
     log_step "Demontage USB..."
     force_unmount_usb
     log_step "Detachement pilotes..."
     force_unbind_usb_drivers
     log_step "Recherche cle..."
     find_usb_device
     log_step "Attente peripherique..."
     wait_for_device || { bind_usb_storage; exit 1; }
     log_step "Verification espace..."
     check_disk_space || { [[ "$FORCE" = false ]] && { bind_usb_storage; 
exit 1; }; }
     log_step "Lancement ddrescue..."
     run_ddrescue 1 "$DEVICE" "$TARGET_IMG" "$TARGET_LOG" || { 
bind_usb_storage; log_error "Passe 1 echouee."; exit 1; }
     run_ddrescue 2 "$DEVICE" "$TARGET_IMG" "$TARGET_LOG" || { 
bind_usb_storage; log_error "Passe 2 echouee."; exit 1; }
     run_ddrescue 3 "$DEVICE" "$TARGET_IMG" "$TARGET_LOG" || log_warn 
"Passe 3 echouee (normal si cle endommagee)"
     log_step "Reattachement..."
     bind_usb_storage
     analyze_log "$TARGET_LOG"
     [[ "$DRY_RUN" = false ]] && { log_step "Verification image..."; 
mount_rescue_image "$TARGET_IMG" || true; }
     log_info "Termine. Verifiez $TARGET_IMG et $TARGET_LOG."
}

main "$@"
=======================================================

toute suggestion ou patch sur ce code sont les bienvenue, ainsi que pour 
récuperer les données (des photos) sur la clé

ainsi que réécrire le firmware qui est certainement le font du problem.
---
tout problème à ses faille et un homme comme vous est à même de les 
résoudre ;-)
---
Jean-Christophe

Le 2026-07-27 11:13, jean-christophe a écrit :
> Récupérer les données n'est pas la priorité,
> Récupérer le matériel oui.
> 
> On me dit qu'il y a une commande Linux pour flashé la clé
> 
> Il me faut juste le firmware, et c'est plus pour le défi et la
> stupidité de mise en obsolescence.
> 
> Surtout que je sais que cette clé est récupérable.
> 
> Juste pour le défi et la connaissance, j'ai beaucoup de support de
> stockage a récupérer de la même manière, quitte à ce qu'elle soit
> définitivement inutilisable
> 
> https://flashboot.ru/iflash/
> https://usbdev.ru/firmware/
> https://www.eevblog.com/forum/
> 
>> Sur 27 juill. 2026 à 08 h 50, Basile STARYNKEVITCH
>> <[email protected]> a écrit :
>> 
>> On Mon, 2026-07-27 at 02:09 +0200, jean-christophe wrote:
>> 
>> Début du message transféré :
>> 
>> De : jean-christophe <[email protected]>
>> Date : 27 juill. 2026 à 02 h 05
>> To: SmartList <[email protected]>
>> Sujet : Flash firmware clé USB sous debian Trixie
>> 
>> Bonjour,
>> J'ai un clé USB [ID 8564:1000]
>> Elle a était mise en lecture seule, impossible de lire le contenu
>> (secteurs défectueux)
>> 
>> Et impossible de :
>> # dd if=/dev/zero of=/dev/sdX bs=4M status=progress
> 
> Les clefs USB sont un matériel qui s'use très vite. A mon avis il y
> a peu de choses à faire, sauf à être équipé de matériel
> extrêmement onéreux.
> 
> Il est possible que certaines entreprrises vendent à prix d'or
> (plusieurs milliers d'euros) un tel service de récupération
> partielle
> 
> Cordia&lement
> 
> --
> 
> Basile STARYNKEVITCH
> <[email protected]>
> 8 rue de la Faïencerie
> http://starynkevitch.net/Basile/
> 92340 Bourg-la-Reine
> https://github.com/bstarynk
> France
> https://github.com/RefPerSys/RefPerSys
>                   https://orcid.org/0000-0003-0908-5250