xplayer-ota/emmc_backup_from_sd.sh
2025-09-01 18:26:32 +08:00

143 lines
4.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#===============================================================================
# 从SD卡操作eMMC备份脚本
#===============================================================================
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
error_msg() { echo -e "${RED}[ERROR] $1${NC}" >&2; exit 1; }
info_msg() { echo -e "${GREEN}[INFO] $1${NC}"; }
warn_msg() { echo -e "${YELLOW}[WARN] $1${NC}"; }
[[ $EUID -eq 0 ]] || error_msg "需要root权限"
EMMC_DEV="/dev/mmcblk0"
USB_DIR="/mnt/XIN_USB/rock5c"
OUTPUT_FILE="${USB_DIR}/rock5c_emmc_$(date +%Y%m%d_%H%M%S).img"
info_msg "从SD卡备份eMMC..."
info_msg "eMMC设备: ${EMMC_DEV}"
info_msg "输出到: ${OUTPUT_FILE}"
# 检查设备
[[ -b "${EMMC_DEV}" ]] || error_msg "eMMC设备不存在: ${EMMC_DEV}"
[[ -d "${USB_DIR}" ]] || error_msg "USB目录不存在: ${USB_DIR}"
# 检查eMMC没有被挂载
if mount | grep -q mmcblk0; then
error_msg "eMMC还在使用中请确保从SD卡启动"
fi
info_msg "✅ eMMC设备可安全操作"
# 步骤1: 检查eMMC分区信息
info_msg "步骤1: 分析eMMC分区..."
parted -s ${EMMC_DEV} unit MB print
# 检查eMMC上的数据大小
info_msg "检查eMMC数据使用量..."
TEMP_MOUNT="/tmp/check_emmc"
mkdir -p "${TEMP_MOUNT}"
# 临时挂载检查使用量
mount ${EMMC_DEV}p2 "${TEMP_MOUNT}" -o ro
EMMC_USED=$(df --block-size=1M "${TEMP_MOUNT}" | tail -1 | awk '{print $3}')
umount "${TEMP_MOUNT}"
mount ${EMMC_DEV}p1 "${TEMP_MOUNT}" -o ro
EMMC_BOOT_USED=$(df --block-size=1M "${TEMP_MOUNT}" | tail -1 | awk '{print $3}')
umount "${TEMP_MOUNT}"
rm -rf "${TEMP_MOUNT}"
info_msg "eMMC使用情况: Root ${EMMC_USED}MB + Boot ${EMMC_BOOT_USED}MB"
# 步骤2: 智能收缩eMMC分区
info_msg "步骤2: 智能收缩eMMC分区..."
# 文件系统检查
e2fsck -f -y ${EMMC_DEV}p2
# 先尝试收缩到最小值
info_msg "计算文件系统最小大小..."
resize2fs -M ${EMMC_DEV}p2
# 获取收缩后的实际大小
FS_SIZE_BLOCKS=$(dumpe2fs -h ${EMMC_DEV}p2 2>/dev/null | grep "^Block count:" | awk '{print $3}')
FS_SIZE_MB=$(( (FS_SIZE_BLOCKS * 4) / 1024 + 200 )) # 块大小4KB + 200MB缓冲
info_msg "文件系统最小大小: ${FS_SIZE_MB}MB"
# 扩展一点给缓冲空间
SHRINK_TARGET=$((FS_SIZE_MB + 300))
resize2fs ${EMMC_DEV}p2 ${SHRINK_TARGET}M
# 收缩分区
P2_START=$(parted -s ${EMMC_DEV} unit B print | grep "^ 2" | awk '{print $2}' | sed 's/B$//')
NEW_P2_END=$((P2_START + SHRINK_TARGET * 1048576))
# 记录原始分区信息
parted -s ${EMMC_DEV} unit B print > "${USB_DIR}/emmc_original_layout.txt"
ORIGINAL_P2_END=$(parted -s ${EMMC_DEV} unit B print | grep "^ 2" | awk '{print $3}' | sed 's/B$//')
# 重新创建收缩的分区
parted -s ${EMMC_DEV} rm 2
parted -s ${EMMC_DEV} mkpart primary ext4 ${P2_START}B ${NEW_P2_END}B
info_msg "✅ eMMC分区已收缩"
# 步骤3: 备份收缩后的eMMC
info_msg "步骤3: 备份收缩后的eMMC..."
BACKUP_SIZE_MB=$(( (NEW_P2_END / 1048576) + 100 ))
dd if=${EMMC_DEV} of="${OUTPUT_FILE}" bs=1M count=${BACKUP_SIZE_MB} status=progress
info_msg "✅ eMMC备份完成"
# 步骤4: 恢复eMMC原始大小
info_msg "步骤4: 恢复eMMC原始分区大小..."
parted -s ${EMMC_DEV} rm 2
parted -s ${EMMC_DEV} mkpart primary ext4 ${P2_START}B ${ORIGINAL_P2_END}B
resize2fs ${EMMC_DEV}p2
info_msg "✅ eMMC已恢复原始大小"
# 验证备份镜像
info_msg "步骤5: 验证备份镜像..."
LOOP_DEV=$(losetup -P -f --show "${OUTPUT_FILE}")
sleep 3
if [[ -b "${LOOP_DEV}p1" ]] && [[ -b "${LOOP_DEV}p2" ]]; then
info_msg "✅ 备份镜像分区表完整"
parted -s "${LOOP_DEV}" print
# 检查文件系统
e2fsck -n "${LOOP_DEV}p1" && echo "✅ Boot分区文件系统正常"
e2fsck -n "${LOOP_DEV}p2" && echo "✅ Root分区文件系统正常"
else
warn_msg "❌ 备份镜像分区表有问题"
fi
losetup -d "${LOOP_DEV}"
FINAL_SIZE=$(du -h "${OUTPUT_FILE}" | cut -f1)
FINAL_SIZE_ACTUAL=$(du --apparent-size -h "${OUTPUT_FILE}" | cut -f1)
info_msg "========================================="
info_msg "🎉 eMMC备份成功完成!"
info_msg "========================================="
info_msg "📁 备份文件: ${OUTPUT_FILE}"
info_msg "📏 实际大小: ${FINAL_SIZE}"
info_msg "📐 逻辑大小: ${FINAL_SIZE_ACTUAL}"
info_msg "💾 eMMC已恢复原状"
info_msg ""
info_msg "🚀 部署到新设备:"
info_msg " dd if=$(basename ${OUTPUT_FILE}) of=/dev/mmcblk0 bs=4M status=progress"
info_msg ""
info_msg "✅ 包含完整分区表和bootloader"
info_msg "✅ 保持所有原始配置不变"
info_msg "✅ 可在任意Rock5c上启动"
info_msg "========================================="