树莓派initramfs阶段发送原始MMC命令超时问题排查
排查树莓派4B initramfs阶段MMC命令超时(errno 110)问题
核心原因分析
initramfs阶段的MMC子系统状态与正常系统存在差异,超时问题通常源于设备未完成初始化、命令参数错误或总线休眠三类场景。
分步排查与修复
1. 验证MMC设备是否完成初始化
initramfs中MMC驱动可能未完全加载或设备未probe成功,这是最常见的触发原因:
- 在initramfs Shell中执行以下命令验证状态:
# 查看MMC控制器初始化日志 dmesg | grep -E "mmc0|SDHC" # 检查SD卡设备节点是否存在 ls -l /dev/mmcblk0 # 查看SD卡RCA(相对地址,初始化成功才会生成) cat /sys/class/mmc_host/mmc0/mmc0:* 2>/dev/null | grep rca - 若未输出
mmc0: new high speed SDHC card at address xxxx类日志,说明initramfs未包含必要驱动:- 确认交叉编译的initramfs包含
mmc_core.ko、mmc_block.ko、sdhci.ko、sdhci_brcmstb.ko(树莓派4B专属SD控制器驱动); - 修改initramfs生成脚本,在
init阶段提前加载驱动:modprobe sdhci_brcmstb && modprobe mmc_block。
- 确认交叉编译的initramfs包含
2. 修正MMC命令参数(针对ioctl调用)
CMD13(MMC_CMD_SEND_STATUS)要求传入SD卡的RCA作为参数,参数错误会直接导致超时:
- 从sysfs获取RCA值(例如读取
/sys/class/mmc_host/mmc0/mmc0:xxxx/rca得到0x1234); - 在
test_mmc.c的MMC_IOC_CMD结构体中,将cmd.arg设置为RCA << 16(MMC规范要求RCA左移16位):struct mmc_ioc_cmd cmd = {0}; cmd.opcode = MMC_CMD_SEND_STATUS; cmd.arg = 0x1234 << 16; // 替换为实际读取到的RCA值 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
3. 唤醒休眠的MMC总线
树莓派4B的MMC控制器在initramfs阶段可能自动进入休眠状态:
- 检查总线状态:
cat /sys/class/mmc_host/mmc0/power/state - 若输出为
suspend,执行唤醒命令:echo on > /sys/class/mmc_host/mmc0/power/state - 可将此命令加入initramfs初始化脚本,确保总线在发送命令前处于激活状态。
4. 规范mmc-utils的使用方式
在initramfs中执行mmc extcsd read时需注意:
- 使用根设备节点
/dev/mmcblk0(而非分区节点/dev/mmcblk0p1); - 确保执行前已加载所有MMC驱动模块;
- 确认总线处于激活状态(参考步骤3)。
底层SD卡访问的标准实现流程
- 提前加载驱动:在initramfs初始化脚本中优先加载MMC核心、块设备及树莓派SD控制器驱动;
- 等待设备就绪:通过轮询
/sys/class/mmc_host/mmc0/mmc0:*目录的存在或dmesg日志,确认SD卡初始化完成; - 获取设备参数:读取RCA、CSD、CID等参数,作为后续MMC命令的输入;
- 合规发送命令:使用
MMC_IOC_CMDioctl时,严格遵循MMC规范设置opcode、arg、flags字段; - 精准错误处理:捕获ioctl返回的错误码,结合
dmesg日志定位问题(如-110对应超时,-22对应参数非法)。
内容的提问来源于stack exchange,提问作者Preeti
相关产品推荐
相关产品推荐

