👁 534
# Radxa Cubie A7Z UFS 启动修复:一个 devnum 引发的血案
手头这块 Radxa Cubie A7Z,全志 A733 八核,8GB 内存 + 256GB 海力士 UFS。刷了 HWRT(HardWareRoute),TF 卡启动一直正常,但拔掉 TF 卡就死活从 UFS 起不来。
折腾了一圈,根因竟然是 boot_package.fex 里一个数字写错了。
## 现象
TF 卡插着 → 正常启动,UFS 分区全部可见,读写正常。
拔掉 TF 卡 → U-Boot 卡在 `sunxi_flash_ufs_boot`,找不到启动设备,进不了内核。
UFS 本身没问题,分区表完好,根文件系统也在。就是 U-Boot 不认。
## UFS 的 LUN 布局
全志 A733 的 UFS 控制器暴露了 4 个 LUN(Logical Unit),Linux 下分别映射为:
| LUN | 设备 | 大小 | 内容 |
|—–|——|——|——|
| 0 | /dev/sda | 32MB | 空 |
| 1 | /dev/sdb | 32MB | 空 |
| 2 | /dev/sdc | 32MB | 空 |
| 3 | /dev/sdd | 238GB | GPT + 4个分区 |
关键点:真正的数据盘是 LUN3(sdd),前三个 LUN 都是空的。U-Boot 的隐藏分区也在 UFS 里,但不走 SCSI LUN 暴露。
## 根因定位
HWRT 的 `platform_install.sh` 里写 U-Boot 的逻辑:
“`bash
dd if=boot0_sdcard.bin of=$DEVICE bs=512 seek=256
dd if=boot0_ufs.bin of=$DEVICE bs=512 seek=2064
dd if=boot_package.fex of=$DEVICE bs=512 seek=24576
“`
boot_package.fex 被写到了 sdd 的 LBA 24576(12MB 偏移),这部分没问题。
问题出在 boot_package.fex 内部的环境变量:
“`
bootcmd_sunxi_flash_ufs0=setenv devnum 0; run sunxi_flash_ufs_boot
“`
`devnum 0` 意味着 U-Boot 去 LUN0(sda,32MB 空盘)找启动分区。当然找不到。
正确应该是 `devnum 3`,指向 LUN3(sdd,238GB 数据盘)。
## 修复过程
### 1. 备份原始 boot_package
“`bash
dd if=/dev/sdd of=/tmp/boot_package_backup.bin bs=512 skip=24576 count=2816
“`
### 2. 二进制 patch
boot_package.fex 是二进制文件,不能直接文本编辑。用 Python 精确定位并替换:
“`python
原始: “setenv devnum 0”
目标: “setenv devnum 3”
只改一个字节: 0x30 → 0x33
data = open(‘/tmp/boot_package_backup.bin’, ‘rb’).read()idx = data.find(b’setenv devnum 0′)
data = data[:idx+14] + b’3′ + data[idx+15:]
open(‘/tmp/boot_package_patched.bin’, ‘wb’).write(data)
“`
### 3. 写回 sdd
“`bash
dd if=/tmp/boot_package_patched.bin of=/dev/sdd bs=512 seek=24576 conv=notrunc,fsync
“`
### 4. 验证
“`bash
读回来比对
dd if=/dev/sdd of=/tmp/verify.bin bs=512 skip=24576 count=2816md5sum /tmp/boot_package_patched.bin /tmp/verify.bin
两者一致 ✅
# 确认内容
strings /tmp/verify.bin | grep devnum
输出: setenv devnum 3 ✅
“`
## GPT 4K 扇区对齐
顺带确认了一下 sdd 的 GPT 分区表,全志 UFS 使用 4096 字节物理扇区:
“`
Device Start End Sectors Size Type
/dev/sdd1 4096 69631 65536 256M Linux extended boot
/dev/sdd2 69632 43945312 43875681 167.4G Linux root (ARM-64)
/dev/sdd3 43945472 50236927 6291456 24G Linux filesystem
/dev/sdd4 50236928 62435071 12198144 46.5G Linux filesystem
“`
GPT 头的 AlternateLBA = 62435327,与磁盘总扇区数 62435328 匹配,说明 GPT 确实按 4K 扇区单位编写,没有对齐问题。
## 安全回滚
修改前已备份原始 boot_package.bin。如果 UFS 启动失败,插回 TF 卡即可恢复,TF 卡启动链完全不受影响。最坏情况用 TF 卡启动后把备份写回去:
“`bash
dd if=/tmp/boot_package_backup.bin of=/dev/sdd bs=512 seek=24576 conv=notrunc,fsync
“`
## 总结
全志 A733 UFS 的 LUN 布局不是常见的单 LUN,而是 4 LUN(3×32MB + 1×238GB)。HWRT 的 boot_package.fex 默认 `devnum=0` 指向了空 LUN,改成 `devnum=3` 就能正确从数据 LUN 启动。
一个字节的差异,让 UFS 启动完全瘫痪。嵌入式设备调试,有时候就是这么离谱。
—
💖 打赏支持
如果这篇文章帮到了你,欢迎打赏支持
微信扫一扫,赞赏支持
发表回复