Block-Level NOR Backups on OpenWrt
- 1. Configuration backup versus MTD backup
- 2. Identify the flash type and layout
- 3. Create ART backup
- 4. Back up the bootloader separately
- 5. Create full MTD backup over SSH
- 6. Create full MTD backup from OpenWrt/UART to a host
- 7. Verify and store the backup
- 8. Restore from a bootloader console
- 9. Restore from the OpenWrt console
- 10. Conclusion
This guide covers block-level flash backups on NOR-based OpenWrt devices. It is different from sysupgrade -b, which archives configuration files. The goal is to preserve MTD partition contents for analysis or targeted recovery.
Warning: Confirm that the device uses NOR before following this procedure. Do not use
ddcasually on NAND; NAND requires tools that understand ECC and bad-block handling. Never write a dump from another device. Bootloader, ART/NVRAM, factory/calibration, and similar partitions may contain device-specific data; losing them can remove Wi-Fi calibration or MAC data and may prevent booting.
Source reference: OpenWrt Wiki – Generic NOR backup.
1. Configuration backup versus MTD backup
sysupgrade -b creates an archive of files listed by the sysupgrade configuration. It is not a raw flash backup. An MTD backup reads raw partition contents such as bootloader, art, firmware, or mtdX.
OpenWrt normally manages the firmware part. It does not normally write the bootloader, ART/NVRAM, or calibration areas. Those areas must therefore be backed up separately before experimenting with bootloaders, flash layouts, or unusual firmware images.
2. Identify the flash type and layout
- Log in through SSH or a UART console.
- Record board and release information:
ubus call system boardcat /etc/openwrt_release
- Inspect the kernel log:
dmesg | grep -iE 'spi-nor|spi-nand|nand|mtd'
- Print the MTD table:
cat /proc/mtd
A table may look like this:
dev: size erasesize namemtd0: 00040000 00010000 "u-boot"mtd1: 00010000 00010000 "art"mtd2: 00100000 00010000 "firmware"
Names and numbers vary by model. Never infer mtdX from this example; use the router’s actual output. Record partition names, sizes, erase sizes, and the backup date.
3. Create ART backup
ART is wireless calibration data on some devices, especially Atheros/QCA platforms. Not every device has an art partition; some use factory or another layout. If no art partition exists, do not run a command that expands to /dev/ and do not guess an equivalent partition.
- Find a partition named
art:
sed -n -e '/:.*"art"/s///p' /proc/mtd
- If the output identifies the correct device, create the ART backup:
dd if=/dev/$(sed -n -e '/:.*"art"/s///p' /proc/mtd) of=/tmp/art.backup
- Check the file:
ls -l /tmp/art.backupsha256sum /tmp/art.backup
- Copy it to a separate computer before rebooting:
scp root@OPENWRT:/tmp/art.backup ./art.backupsha256sum ./art.backup
Replace OPENWRT with the real hostname or IP. Keep at least two safe copies. Do not commit a dump to Git or upload it to a public repository.
4. Back up the bootloader separately
If the bootloader is damaged, the router may lose its UART bootloader console; recovery may require JTAG or removing the flash chip. Once the correct bootloader partition has been confirmed from /proc/mtd, create a separate backup:
dd if=/dev/mtd0 of=/tmp/boot.backup
mtd0 is only an example. Substitute the device identified in the actual layout. Check and copy it out:
ls -l /tmp/boot.backupsha256sum /tmp/boot.backupscp root@OPENWRT:/tmp/boot.backup ./boot.backup
Do not flash a bootloader dump merely because its partition name looks familiar. It may contain model-specific MAC data, environment, board data, or offsets.
5. Create full MTD backup over SSH
This method runs from a Unix-like host or WSL with Bash and root SSH access to the router. It reads every MTD device, stores each dump separately, and compresses them into mtd_backup.tgz.
- Create the script on the computer:
cat << "EOF" > mtdbk.sh#!/bin/bashset -efunction die() { echo "${@}" >&2; exit 2; }OUTPUT_FILE="mtd_backup.tgz"OPENWRT="[email protected]"TMPDIR=$(mktemp -d)BACKUP_DIR="${TMPDIR}/mtd_backup"SSH_CONTROL="${TMPDIR}/ssh_control"mkdir -p "${BACKUP_DIR}"function cleanup() { set +e echo "Closing master SSH connection" "${SSH_CMD[@]}" -O stop echo "Removing temporary backup files" rm -r "${TMPDIR}"}trap cleanup EXITSSH_CMD=(ssh -o "ControlMaster=no" -o "ControlPath=${SSH_CONTROL}" -n "${OPENWRT}")echo "Opening master SSH connection"ssh -o "ControlMaster=yes" -o "ControlPath=${SSH_CONTROL}" -o "ControlPersist=10" -n -N "${OPENWRT}""${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})" "${SSH_CMD[@]}" "dd if='/dev/${MTD_DEV}ro'" > "${BACKUP_DIR}/${MTD_DEV}_${MTD_NAME}.backup" || die "dd failed, aborting..."doneecho "Compressing backup files to \"${OUTPUT_FILE}\""(cd "${TMPDIR}" && tar czf - "$(basename "${BACKUP_DIR}")") > "${OUTPUT_FILE}" || die 'tar failed, aborting...'echo -e "\nMTD backup complete. Extract the files using:\ntar xzf \"${OUTPUT_FILE}\""EOFchmod +x mtdbk.sh./mtdbk.sh
- Change
OPENWRTto the real account, hostname, or IP before running. Do not put a real password, private key, or token in a repository script. - The script uses one master SSH connection so it does not authenticate for every partition. The binary output of
ddgoes directly to a file; do not print extra text to that stdout stream. - Extract and inspect the result:
tar tzf mtd_backup.tgztar xzf mtd_backup.tgzfind mtd_backup -type f -exec sha256sum {} \;
Files will look like mtd0_u-boot.backup, mtd1_art.backup, and so on, depending on the layout. Compare every file size with the size column in /proc/mtd.
6. Create full MTD backup from OpenWrt/UART to a host
Use this method when the router has a UART console but convenient root SSH access is unavailable. The router reads each MTD device and pipes it over SSH to the backup computer.
- On the backup host, ensure that the receiving SSH user exists and has enough storage.
- On the router, create
/tmp/backup.sh:
cat << "EOF" > /tmp/backup.sh#!/bin/shBACKUP_HOST="pc.lan"BACKUP_USER="root"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"doneEOFchmod +x /tmp/backup.shsh /tmp/backup.sh
- Change
BACKUP_HOSTandBACKUP_USERfor the real host. Do not put a password in the script. SSH may ask for the host password for every MTD device; key authentication is safer when available. - Watch the destination host while the backup runs:
watch -n 0.2 ls -l --block-size=K ~
- Check size and hashes after completion. If the pipe or SSH command fails, consider the backup incomplete and repeat it; never restore a partial file.
{{< ads >}}
7. Verify and store the backup
- Compare file sizes with the
sizevalues in/proc/mtd. - Calculate SHA-256 hashes on the files after copying them to the PC.
- Record model, hardware revision, stock/OpenWrt version,
/proc/mtd, flash type, and backup date. - Keep an original read-only/offline copy and another separate copy.
- Do not modify dumps or rename a partition in order to flash it to another device.
8. Restore from a bootloader console
Bootloaders may provide MTD commands, but their partition layout is not necessarily identical to the kernel layout in /proc/mtd. Some bootloaders use offsets and lengths rather than partition names.
Before restoring, have the correct model/revision dump, the bootloader offset/size map recorded during backup, a stable console and power source, and a fallback recovery method. Never guess an erase address or length. If the model documentation does not provide a clear recovery procedure, stop at backup and find the exact model-specific debrick instructions.
9. Restore from the OpenWrt console
For ART, the source documents the basic method:
mtd write art.backup art
However, the art partition is often marked read-only by the kernel, so the command may fail. Do not force it with -F or substitute another partition. The documentation notes that a custom kernel with an appropriate change may be required to make the partition writable, followed by booting that image before writing.
Safety rules:
- Put the verified backup at
/tmpor another checked path. - Confirm its hash and size before writing.
- Match the partition name on the actual device.
- Do not write a full MTD dump to a firmware partition without confirming the layout and offset.
- Prefer the vendor’s official recovery method or model-specific debrick procedure.
- After restoring, check boot, Ethernet, Wi-Fi calibration, MAC data, and services before another reboot.
10. Conclusion
Create ART backup and Create full MTD backup solve different problems. ART/factory/calibration data must be preserved per device; a full MTD backup preserves the complete layout for analysis or recovery. A configuration archive does not replace either backup, and dd is not the right tool for NAND.
Comments & Discussion
Share your thoughts, ask questions and feedback