简介
适用对象:京东云 BE6500,已刷入可进入 Web U-Boot 的设备。本文记录一次将
rootfs扩容到 2 GiB 时,因 eMMC 实际容量与公开 GPT 模板不一致而出现 GPT 无效的问题及处理方法。风险提示:分区表、U-Boot、ART、factory 都属于高风险操作。操作前必须离线备份自己的 ART(p17)和 factory(p25);不要使用他人的 ART 或 factory 作为长期方案。
众所众知BE6500的磁盘非常大,且CXT已经扩容2GB内存,可以作为一个低功耗设备。
扩容采用数码罗记的相关教程,详情访问。https://godsun.pro/?s=BE6500 查看相关BE6500系列内容。
1. 现象
按公开教程写入前 34 个扇区的 2G GPT:
dd if=gpt_JDCloud-BE6500_2G.bin of=/dev/mmcblk0 bs=512 count=34
sync
随后执行 fdisk -l,只看到一个 ee GPT 保护分区,并出现类似警告:
GPT PMBR size mismatch (244252671 != 240615423)
本机 eMMC 容量为:
240615424 sectors * 512 bytes = 114.73 GiB
最后一个 LBA = 240615423
而模板 GPT 的保护 MBR/备用 GPT 指向的最后 LBA 为 244252671,相当于针对一块更大的 eMMC 制作。此时不能把“只显示一个分区”简单视为缓存未刷新:内核分区缓存确实尚未更新,但磁盘上的 GPT 几何信息也不匹配。
在重启前,CXT采取比较谨慎的方式,也请教了罗总。

请教完想了一下,直接重启的方案,还是不够稳健。那我们就手动修复GPT分区表吧。(罗总听我说:不是不相信老罗,是个人行事偏谨慎,必须要确保无误)
2. 先做不可替代的备份
在旧系统仍正常运行、旧内核分区映射仍存在时,优先备份 ART 和 factory,并立即复制到电脑:
dd if=/dev/mmcblk0p17 of=/tmp/BE6500-ART.bin bs=256k count=4 conv=fsync
dd if=/dev/mmcblk0p25 of=/tmp/BE6500-factory.bin bs=256k count=1 conv=fsync
sha256sum /tmp/BE6500-ART.bin /tmp/BE6500-factory.bin
ls -l /tmp/BE6500-ART.bin /tmp/BE6500-factory.bin
预期大小:
ART 1048576 bytes (1 MiB)
factory 262144 bytes (256 KiB)
/tmp 属于内存文件系统,重启后会丢失;必须离线保存。
3. 新旧分区表对比
本次模板中,p1-p22 的位置没有变化;特别是 U-Boot、ART、HLOS 都不受影响:
p14 APPSBL 16930-18465
p15 APPSBL_1 18466-20001
p17 ART 21026-23073
p21 HLOS 72738-87073
p22 HLOS_1 87074-101409
实际变化从 p23 开始:
| 分区 | 原始范围 | 2G GPT 范围 | 说明 |
|---|---|---|---|
| p23 | 101410-351265 | 101410-4295713 | rootfs 从约 122 MiB 扩大到 2 GiB |
| p24 | 351266-601121 | 4295714-4545569 | rootfs_1 容量不变,仅后移 |
| p25 | 601122-601633 | 4545570-4546081 | factory 后移,必须恢复自己的备份 |
| p26 | 601634-2698785 | 4546082-6643233 | plugin 后移 |
| p27 | 2698786-2960929 | 6643234-6905377 | log 后移 |
| p28 | 2960930-5058081 | 6905378-9002529 | swap 后移 |
| p29 | 5058082-末尾 | 未创建 | 用剩余空间新建数据分区 |
结论:GPT 不会搬移旧数据。旧 rootfs 不能继续启动,p25 也不会自动出现在新位置;必须进 U-Boot 刷新固件,并恢复自己的 factory。
4. 修复 GPT 的容量字段和备用表
本机的模板 GPT 有 32 个、每个 128 字节的分区条目,因此备用条目数组是 8 个扇区;备用 GPT 共占最后 9 个扇区。
对于总扇区数 240615424 的 eMMC,正确位置为:
最后 LBA 240615423
备用条目数组 240615415-240615422
备用 GPT Header 240615423
最后可用 LBA 240615414
修复原则:保持模板中 p1-p28 的条目、GUID 和名称不变,只更新:
- PMBR 的保护分区大小;
- 主 GPT 的备用 Header LBA 与
LastUsableLBA; - 主 GPT Header CRC;
- 位于真实末端的备用条目数组与备用 Header;
- 备用 GPT Header CRC。
写入时先写备用 GPT,再写主 GPT,以便中途断电时至少保留一份可识别的新表:
# gpt-backup-fixed.bin 为 4608 bytes,即 9 个扇区
dd if=/tmp/gpt-backup-fixed.bin of=/dev/mmcblk0 bs=512 seek=240615415 conv=fsync
# gpt-primary-fixed.bin 为 17408 bytes,即前 34 个扇区
dd if=/tmp/gpt-primary-fixed.bin of=/dev/mmcblk0 bs=512 count=34 conv=fsync
sync
验证时不要使用会要求内核重新读取分区表的 partprobe;只读检查即可:
parted -s /dev/mmcblk0 unit s print
fdisk -l /dev/mmcblk0
正确结果应为:两个工具均直接识别 gpt,且不再出现 backup GPT table is corrupt 或 PMBR size mismatch。
5. U-Boot:为何可安全保留/更新
GPT 修复只写入开头 34 个扇区和结尾 9 个扇区,不会覆盖 p14/p15 的 U-Boot。若设备原先可通过“按住 Reset 再通电”进入 Web U-Boot,则仍可采用同样方式。
若希望在重启前使用发布者公开的 U-Boot 文件,先备份当前 p14/p15,再对比哈希:
dd if=/dev/mmcblk0p14 of=/tmp/APPSBL-current.bin bs=256k count=3 conv=fsync
dd if=/dev/mmcblk0p15 of=/tmp/APPSBL1-current.bin bs=256k count=3 conv=fsync
md5sum /tmp/APPSBL-current.bin /tmp/APPSBL1-current.bin
确认候选文件适用于 BE6500、大小正好为 768 KiB 后,写入主备 U-Boot 并清空 BOOTCONFIG:
dd if=/tmp/jdc-be6500-uboot.bin of=/dev/mmcblk0p14 bs=256k conv=fsync
dd if=/tmp/jdc-be6500-uboot.bin of=/dev/mmcblk0p15 bs=256k conv=fsync
dd if=/dev/zero of=/dev/mmcblk0p3 bs=256k count=1 conv=fsync
dd if=/dev/zero of=/dev/mmcblk0p4 bs=256k count=1 conv=fsync
sync
随后读回并校验 p14/p15,确认主备一致后再断电:
dd if=/dev/mmcblk0p14 of=/tmp/APPSBL-check.bin bs=256k count=3 conv=fsync
dd if=/dev/mmcblk0p15 of=/tmp/APPSBL1-check.bin bs=256k count=3 conv=fsync
md5sum /tmp/APPSBL-check.bin /tmp/APPSBL1-check.bin
6. 进 Web U-Boot 刷完整固件
在电脑网线、静态 IP、固件文件都准备好后:
poweroff -f
断电后按住 Reset 通电,使用原先可访问的 Web U-Boot 页面刷入与 2G GPT 布局匹配的完整固件。
不要让旧系统直接启动:旧 p23/p24 内容对应的是旧分区位置和旧容量。新固件启动后,再检查:
fdisk -l /dev/mmcblk0
7. 启动新系统后的收尾
恢复 factory
仅恢复自己的 factory 备份到新 p25;不要长期使用他人 factory,因为会带来重复 MAC、序列号和服务冲突:
dd if=/path/to/BE6500-factory.bin of=/dev/mmcblk0p25 bs=256k count=1 conv=fsync
sync
可以校验恢复结果:
dd if=/dev/mmcblk0p25 bs=256k count=1 2>/dev/null | sha256sum
初始化 swap
p28 的物理位置已变化,确认 swap 没有启用后再初始化:
cat /proc/swaps
mkswap /dev/mmcblk0p28
swapon /dev/mmcblk0p28
建立 p29 数据分区
在新系统中使用 cfdisk /dev/mmcblk0,在末尾 Free Space 创建 p29,选择全部容量并 Write。随后格式化:
mkfs.ext4 /dev/mmcblk0p29
p29 不影响路由器基本启动,但它承载后段的大容量数据空间。
8. ART 与 CDT 的处理边界
- ART 位于 p17,本次 GPT/U-Boot/factory 操作都不应写入它。备份后可用哈希确认其未被后续操作改写。
- ART 是单机射频校准数据。不要把他人 ART 当作性能升级文件;即便能启动,也可能导致功率、稳定性、MAC 或频段行为异常。
- CDT 位于 p11/p12。若系统已经显示约 1.83 GiB 的
MemTotal,通常已经正确识别 2 GiB 物理内存;其余约 174 MiB 是 SoC、无线固件、DMA 和内核保留内存,不应为了让free更接近 2 GiB 而盲目更换 CDT。
9. 最终检查清单

- ART 与 factory 已离线备份。
-
parted/fdisk无 GPT 容量或备用表警告。 - Web U-Boot 可以进入,且新固件已写入。
- 新系统能够启动,p23 显示为 2 GiB。
- 自己的 factory 已恢复到新的 p25。
- p28 已初始化为 swap(如需要)。
- p29 已创建、格式化并按需求挂载。
总结
完成以上步骤后,BE6500 的 2G rootfs 扩容和后段数据盘配置即完成。眼尖的访客还能看到,CXT安装了Docker,下一篇文章讲过程。
感谢罗总在路由器和硬件上的探索和总结经验。看到罗总还安装了Docker,但文章日期较旧,尝试后未成功,CXT就让ChatGPT帮我进行了分析环境、部署Docker并写成脚本。