通用 NOR 备份

  • 本指南介绍了如何通过CLI执行块级备份/恢复。
  • 文件级备份/恢复见备份和恢复

基于 NAND 的设备应使用NAND-aware程序,因为dd不能正确处理 NAND 闪存的纠错或坏块标记。

请查看file_systemflash 布局详细信息,并注意OpenWrt 仅涵盖firmware部分。(引导程序)bootloader分区ART/NVRAM和类似的分区不是OpenWrt的固件的一部分。如果出现问题并且这些分区上的数据意外损坏,您将无法通过公共 OpenWrt 源替换它!

由于 OpenWrt 不会写入这些分区,因此它们不太可能被 OpenWrt 本身损坏。但是,如果您想折腾bootloader部分,当然应该在您的 PC 上创建此数据的副本。否则,万一您丢失了该数据,您将不得不去论坛,让某人备份他们的数据并发送给您,然后您必须更换MAC地址,然后通过port.jtag将刷写,否则您的设备可能无法再启动。

如果您的 ART 分区损坏了,您仍然可以启动 OpenWrt,只是您的无线设备无法正常工作。使用mtd可以轻松修复。

dd if=/dev/$(sed -n -e '/:.*"art"/s///p' /proc/mtd) of=/tmp/art.backup

如果您的引导加载程序分区已损坏,您甚至无法使用bootloader的控制台(该控制台只能通过串行端口访问),唯一的恢复方法是通过JTAG 端口或通过拆焊闪存芯片,请参阅generic.debrick寻求帮助。

但是,一旦您已经准备好再次写入闪存,您仍然需要一些可以写入的东西,会起作用的东西。在这里,您的备份将派上用场:

dd if=/dev/mtd0 of=/tmp/boot.backup

然后通过 scp 或 ssh 将您的备份文件复制到您的 PC 上,并确保它们的安全以供您可能需要它们。

该脚本假设在原生类 Unix 或 WSL 环境中使用Bash 和SSH。如果您更改了路由器的IP地址,请将 OPENWRT 变量值更改为OpenWrt 路由器的主机名/ IP。这会将您的 mtd 内容备份到mtd_backup.tgz与脚本相同的文件夹中的压缩 tarball 文件中。

cat << "EOF" > mtdbk.sh
#!/bin/bash
 
set -e
 
function die() {
    echo "${@}"
    exit 2
}
 
OUTPUT_FILE="mtd_backup.tgz"
OPENWRT="root@openwrt.lan"
TMPDIR=$(mktemp -d)
BACKUP_DIR="${TMPDIR}/mtd_backup"
mkdir -p "${BACKUP_DIR}"
SSH_CONTROL="${TMPDIR}/ssh_control"
 
function cleanup() {
    set +e
 
    echo "Closing master SSH connection"
    "${SSH_CMD[@]}" -O stop
 
    echo "Removing temporary backup files"
    rm -r "${TMPDIR}"
}
trap cleanup EXIT
 
# Open master ssh connection, to avoid the need to authenticate multiple times
echo "Opening master SSH connection"
ssh -o "ControlMaster=yes" -o "ControlPath=${SSH_CONTROL}" -o "ControlPersist=10" -n -N "${OPENWRT}"
 
# This is the command we'll use to reuse the master connection
SSH_CMD=(ssh -o "ControlMaster=no" -o "ControlPath=${SSH_CONTROL}" -n "${OPENWRT}")
 
# List remote mtd devices from /proc/mtd. The first line is just a table
# header, so skip it (using tail)
"${SSH_CMD[@]}" 'cat /proc/mtd' | tail -n+2 | while read; do
    MTD_DEV=$(echo ${REPLY} | cut -f1 -d:)
    MTD_NAME=$(echo ${REPLY} | cut -f2 -d\")
    echo "Backing up ${MTD_DEV} (${MTD_NAME})"
    # It's important that the remote command only prints the actual file
    # contents to stdout, otherwise our backup files will be corrupted. Other
    # info must be printed to stderr instead. Luckily, this is how the dd
    # command already behaves by default, so no additional flags are needed.
    "${SSH_CMD[@]}" "dd if='/dev/${MTD_DEV}ro'" > "${BACKUP_DIR}/${MTD_DEV}_${MTD_NAME}.backup" || die "dd failed, aborting..."
done
 
# Use gzip and tar to compress the backup files
echo "Compressing backup files to \"${OUTPUT_FILE}\""
(cd "${TMPDIR}" && tar czf - "$(basename "${BACKUP_DIR}")") > "${OUTPUT_FILE}" || die 'tar failed, aborting...'
 
# Clean up a little earlier, so the completion message is the last thing the user sees
cleanup
# Reset signal handler
trap EXIT
 
echo -e "\nMTD backup complete. Extract the files using:\ntar xzf \"${OUTPUT_FILE}\""
EOF
chmod +x mtdbk.sh
./mtdbk.sh

上述方法效果很好,但前提是您对路由器具有SSH根访问权限。在某些情况下,当您没有对路由器的SSH根访问权限,但可以从 UART 控制台连接时。例如带有原始官方固件的 TP-Link Archer C9 HW ver 5.0。您可以从路由器备份到您的主机。

# Save the script
cat << "EOF" > /tmp/backup.sh
#!/bin/sh
 
BACKUP_HOST="pc.lan"
BACKUP_USER="root"
echo "Backup host ${BACKUP_HOST}"
 
cat /proc/mtd | tail -n+2 | while read; do
  MTD_DEV=$(echo ${REPLY} | cut -f1 -d:)
  MTD_NAME=$(echo ${REPLY} | cut -f2 -d\")
  echo "Backing up ${MTD_DEV} (${MTD_NAME})"
  dd if=/dev/${MTD_DEV}ro | ssh -y ${BACKUP_USER}@${BACKUP_HOST} "dd of=~/${MTD_DEV}_${MTD_NAME}.backup"
done
EOF
 
# Run the script
sh /tmp/backup.sh

现在,您需要从 PC 为每个 mtd 设备输入5 次或更多次的SSH密码 。

操作完成后,您将在PC 上的用户主目录中找到所有文件。

如果您使用 linux 并希望查看进度,您可以在 PC 上的单独控制台中运行:

watch -n 0.2 ls -l --block-size=K ~

有时可能需要从原始固件备份设置/分区。根据引导加载程序,可能有不同的策略。

闪存芯片被映射到一个起始地址。使用 uboot 它应该在以下设置中:

printenv
bdinfo

内存转储到串口(uboot: md ; redboot: dump)。将转储写入 tftp 或 nfs。

许多引导加载程序允许您使用 mtd 分区,但要注意:它们不必与内核 mtd 分区相同!此外,对于某些引导加载程序,您不能使用 mtd-partition,您必须使用偏移量。在后一种情况下,在进行备份时记下这些正确的偏移量可能是个好主意。

mtd write art.backup art

上述方法可能可以使用,但很可能无法正常使用,因为art分区通常不可写,因此您必须在做一些小修改后编译自己的内核。然后你必须把它刷到你的设备上,启动它,现在分区应该是可写的。

若想在电脑上查看 MTD 备份内容而不将其恢复至 OpenWrt 系统,可使用 jefferson 工具并执行以下命令:

jefferson mtd4_rootfs_data.backup -d rootfs

其中 mtd4_rootfs_data.backup 文件为待分析的 mtd 存储块。通常建议选择 rootfs_data 分区,因为该分区包含了您对 OpenWrt 系统进行的大部分自定义配置。

  • Last modified: 2025/10/30 09:46
  • by starsfall