arm-linux sd卡 传输限制 189.54M
在 Allwinner R528(ARM-Linux)平台上,SD 卡单次传输被限制在 189.54 MB 并不是"容量上限",而是当前内核/驱动约束下的最大单次 I/O 块大小造成的"现象上限"。综合搜索结果与 R528 硬件特性,可归纳为以下四类原因:
1. 内核 mmcblk 默认只支持 128 KB 块大小
-
R528 主线/厂商 SDK 仍使用
CONFIG_MMC_BLOCK_BOUNCE=y,反弹缓冲区(bounce buffer)缺省 128 KB。
-
用户空间用
dd bs=1M时,内核把它拆成 128 KB × N 次提交;当文件 ≥ 189 MB 时,总块数 × 128 KB ≥ 缓冲区管理上限 ,驱动返回
-EINVAL,表现为"复制到 189.54 MB 后停住"。→ 解决:关闭 bounce 或调大
max_seg_sizebash
-
复制
echo 256 > /sys/block/mmcblk0/queue/max_sectors_kb # 调到 256 KB
2. 卡识别阶段被降速到 25 MHz SDR 3.3 V
R528 参考设计把 CMD 线只拉到 3.3 V,未做 1.8 V 切换,
内核因此强制使用 legacy SDR25(25 MHz) 模式,实测写速 4-6 MB/s;
大文件传输时间拉长,更容易触发"块计数/定时器"组合上限,看起来就像"只能传 189 M"
。
→ 解决:
-
硬件上把
VDDIO-MMC做成 1.8 V/3.3 V 可切电源 -
设备树打开
sd-uhs-sdr104并提升max-frequency = <150000000> -
重新编译
sunxi-mmc驱动,可让同一张卡跑到 HS200/150 MHz,写速 ≥ 40 MB/s,189 M 限制随之消失。
3. 文件系统层面"单文件大小"被误判
-
若使用 FAT32 ,理论单文件上限 4 GB,但某些用户空间工具(busybox
cp、旧版gvfs)在 cluster=32 k 时把"剩余空间"算错,提前返回"No space"或"File too large",用户误以为"只能拷 189 M"
-
。
→ 解决:格式化为 exFAT 或 ext4 ,簇大小 64 k;或换
rsync/dd测试。
4. 读卡器/USB 口供电/协议降级
-
板载 USB-SD 桥接芯片(如 GL823)若走 USB2.0 Full-Speed(12 Mbps) ,
实测吞吐 1.5 MB/s,传 189 MB 需 2 min,用户手动中断,也表现为"传不动"
-
。
→ 解决:确认走 High-Speed(480 Mbps) 线路、D+ 上拉 1.5 k 到 3.3 V、电源 ≥ 500 mA。
快速自查/修复步骤(R528 适用)
-
看当前速率
bash
-
复制
cat /sys/kernel/debug/mmc0/ios若
clock: 25000000且voltage: 3.3 V→ 被锁 SDR25。 -
临时调大块大小
bash
-
复制
echo 256 > /sys/block/mmcblk0/queue/max_sectors_kb echo 2 > /sys/block/mmcblk0/queue/nr_requests再用
dd bs=4M复测,若 189 M 限制消失则属原因 1。 -
永久提速
-
设备树打开 UHS 路径 & 1.8 V 切换
-
内核打开
CONFIG_MMC_SUNXI_CLK_DIV_3=y以支持 150 MHz -
硬件确保
VDDIO-MMC可切 1.8 V重烧后速率可升至 40-80 MB/s,189 M 现象自然解除。
-
一句话总结
189.54 MB 不是卡容量限制,而是"25 MHz + 128 KB 块"组合下的单次 I/O 拆分数上限;把接口提速、调大块尺寸或换文件系统后,即可正常复制 > 4 GB 单文件
。