Skip to content

0. 环境与现象

  • 设备:eMMC(/dev/mmcblk0
  • 分区:p1~p5 为引导/固件;p5 是只读 squashfs/romp6 是数据分区(先前只有 ~57 GiB)
  • 报错:The primary GPT table is corrupt, but the backup appears OK…

1) 修复 GPT(只修元数据,不动分区内容)

sh
opkg update
opkg install sgdisk

# 备份当前 GPT(以防回滚)
sgdisk -b /root/mmcblk0.gpt.bak /dev/mmcblk0

# 校验现状(此时会有多条 GPT 不一致提示)
sgdisk -v /dev/mmcblk0

# 一键修复:把备份 GPT 挪回盘尾,并重建主表
sgdisk -e /dev/mmcblk0

# 再验证,应显示 No problems found
sgdisk -v /dev/mmcblk0

reboot

验证盘面与空闲区(重启后):

sh
parted /dev/mmcblk0 unit GiB print free
sgdisk -p /dev/mmcblk0
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,TYPE /dev/mmcblk0

2) 吃满剩余空间(两选一)

方案 A:把 p6 扩到盘尾(最简单)

p6 已挂载,先 umount /dev/mmcblk0p6(若已作为 /overlay 使用,请在维护窗口操作)。

sh
parted -s /dev/mmcblk0 resizepart 6 100%
partprobe /dev/mmcblk0 2>/dev/null || true   # 刷新分区表,不行就 reboot

方案 B(兜底):保持起始不变,删并重建同号分区到盘尾

不会动到数据起始位置,但务必确认 p6 起始扇区

sh
sgdisk -p /dev/mmcblk0    # 记下 p6 的 Start(例如 1131520)
umount /dev/mmcblk0p6 2>/dev/null || true
sgdisk -d 6 /dev/mmcblk0
sgdisk -n 6:<起始LBA>:0 /dev/mmcblk0   # 0 表示一直到盘尾
partprobe /dev/mmcblk0 || true

3) 建/扩文件系统并挂载为下载盘(F2FS)

BT 下载盘推荐 F2FS。若你已有数据且 FS 已存在,请走“扩容”分支。

全新建立:

sh
opkg update
opkg install kmod-fs-f2fs f2fsck mkfs.f2fs block-mount

# 给 p6 创建 F2FS(会清空 p6)
mkfs.f2fs -l data /dev/mmcblk0p6

若要保留现有 F2FS 数据只扩容:

sh
opkg install f2fsck
fsck.f2fs -f /dev/mmcblk0p6
resize.f2fs /dev/mmcblk0p6

挂载点与挂载:

sh
mkdir -p /mnt/data
mount -t f2fs -o rw,noatime /dev/mmcblk0p6 /mnt/data
df -h /mnt/data

设为开机自挂 + BT 优化参数:

BT 下载盘推荐参数:

noatime,lazytime,nodiscard,background_gc=on,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,fsync_mode=posix
sh
# 创建一条新的 fstab 条目(用 label=data 更稳)
uci add fstab mount
uci set fstab.@mount[-1].label='data'
uci set fstab.@mount[-1].target='/mnt/data'
uci set fstab.@mount[-1].fstype='f2fs'
uci set fstab.@mount[-1].options='noatime,lazytime,nodiscard,background_gc=on,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,fsync_mode=posix'
uci set fstab.@mount[-1].enabled='1'
uci commit fstab
/etc/init.d/fstab enable
/etc/init.d/fstab restart

mount | grep /mnt/data

说明:关闭实时 discard,改用定期 fstrim,通常能减少卡顿;lazytime 降低元数据同步写;其余选项旨在减少写放大与碎片。


4) 每周自动 fstrim(替代实时 discard)

sh
opkg update && opkg install fstrim

CRON_LINE='0 4 * * 0 /usr/sbin/fstrim -av 2>&1 | logger -t fstrim-weekly'
grep -qxF "$CRON_LINE" /etc/crontabs/root || echo "$CRON_LINE" >> /etc/crontabs/root

/etc/init.d/cron enable
/etc/init.d/cron restart

# 手动验证一次
fstrim -av
logread | grep fstrim-weekly

如需改时间,把 0 4 * * 0(周日 04:00)换成你想要的 cron 表达式即可。


5) (可选)把 overlay 迁到大分区

只在你想让系统可写层更大时需要。

sh
# 假设 p6 已是 F2FS 且空
mkdir -p /mnt/new
mount -t f2fs /dev/mmcblk0p6 /mnt/new

# 复制现有 overlay 内容(保持权限/属性)
tar -C /overlay -cpf - . | tar -C /mnt/new -xpf -
sync

# 改 fstab:目标改为 /overlay
uci add fstab mount
uci set fstab.@mount[-1].label='data'
uci set fstab.@mount[-1].target='/overlay'
uci set fstab.@mount[-1].fstype='f2fs'
uci set fstab.@mount[-1].options='noatime,lazytime,nodiscard,background_gc=on,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=reuse,fsync_mode=posix'
uci set fstab.@mount[-1].enabled='1'
uci commit fstab

reboot

mount | grep overlay
df -h | grep overlay

6) 备份分区表为 U-Boot 可恢复GPT_single_boot.bin

按 GPT 规范,前 34 个扇区包含保护 MBR + 主 GPT 头 + 主分区表(128 项时 = 32 扇区),备份表在盘尾(最后 33 个扇区)。

在系统中备份:

sh
# 盘头 34 扇区 -> U-Boot 可直接写回
dd if=/dev/mmcblk0 of=/root/GPT_single_boot.bin bs=512 count=34 conv=sync,fsync

# (可选)盘尾 33 扇区
SECTORS=$(blockdev --getsz /dev/mmcblk0)
START=$((SECTORS - 33))
dd if=/dev/mmcblk0 of=/root/GPT_backup_tail.bin bs=512 skip=$START count=33 conv=sync,fsync

sha256sum /root/GPT_single_boot.bin /root/GPT_backup_tail.bin

7) 常见坑位与回滚

  • 千万别动 p1~p5(引导/固件/只读根)。
  • partprobe 刷新不到位就 重启
  • 若使用方案 B(删并重建分区),起始 LBA 必须与原来一致
  • 开启压缩对 BT 下载盘通常收益不大(多媒体/压缩包为主)。
  • 任何涉及分区/格式化的操作均有风险,重要数据请先备份。

到这里,你已经:

  1. 修复了损坏的 GPT;
  2. 吃满了 eMMC 的全部空间;
  3. 用 F2FS + 合理参数挂载为 BT 下载盘;
  4. 配好了每周自动 fstrim
  5. 导出了可被 U-Boot 恢复的 GPT_single_boot.bin