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