You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内置驱动无法打开MMC块设备问题求助

内置驱动无法打开MMC块设备问题排查

我基于Linux 5.1的block2mtd.c驱动编写了一个用于打开MMC块设备的模块。当驱动作为模块、系统启动后用modprobe加载时可正常工作;但将驱动设为内置时,无法打开MMC块设备。MMC已以正确名称完成挂载,且挂载日志出现在驱动超时之前。

请问为何无法识别eMMC?是否与命名空间有关?

部分代码

int i;
int timeout = 10;
const fmode_t mode = FMODE_READ | FMODE_WRITE;

struct block_device *bdev;
bdev = blkdev_get_by_path("/dev/mmcblk0", mode, NULL);


for (i = 0; IS_ERR(bdev) && i <= timeout; i++) {
    dev_t devt;

    printk("Try...\n");
    if (i)
        msleep(1000);
    wait_for_device_probe();

    devt = name_to_dev_t("/dev/mmcblk0");
    if (!devt)
        continue;
    bdev = blkdev_get_by_dev(devt, mode, NULL);
}

if (IS_ERR(bdev)) {
    pr_err("error: cannot open device %s\n", "/dev/mmcblk0");
    return -1;
}
else
{
   printk("Open MMC OK !\n");
}

抱歉无法提供完整启动日志(工作原因)。


情况1:CONFIG_MODULES=y且CONFIG_MYDRIVER=m时

..
..
mmc1: new high speed SDHC card at address b368

mmcblk0: mmc1:b368 3.73 GiB
..
modprobe mydriver
..
Open MMC OK !
..
..

情况2:未设置CONFIG_MODULES且CONFIG_MYDRIVER=y时

Try...
Try...
Try...
Try...
mmc1: new high speed SDHC card at address b368
Try...
mmcblk0: mmc1:b368 3.73 GiB
Try...
Try...
Try...
Try...
Try...
Try...
Try...
Try...
error: cannot open device /dev/mmcblk0

问题原因分析与解决建议

核心原因:启动阶段初始化顺序不匹配

内置驱动会在系统启动早期执行,而MMC设备的初始化(包括块设备节点/dev/mmcblk0的就绪)是异步流程。你的代码里的wait_for_device_probe()只能等待硬件探测完成,无法保证上层的块设备逻辑(如devtmpfs创建设备节点、块设备状态同步)全部就绪。

另外,name_to_dev_t()依赖sysfs或devtmpfs的设备节点信息,内置驱动执行时这些文件系统可能还未完全初始化,导致即使MMC硬件被识别,也无法通过路径获取有效dev_t。

与命名空间无关

当前现象和命名空间没有关系——日志已显示mmcblk0节点已创建,只是驱动无法打开它,不符合命名空间导致设备不可见的特征。

解决方法

  1. 改用异步触发机制
    不要在驱动初始化阶段主动打开MMC设备,而是注册设备通知回调,当/dev/mmcblk0节点创建并就绪后再执行打开操作,比如利用udev事件或内核的设备热插拔机制。

  2. 优化块设备就绪检查逻辑
    替换现有重试逻辑,直接通过blkdev_get_by_path()重试并检查设备状态:

    for (i = 0; i <= timeout; i++) {
        if (i)
            msleep(1000);
        bdev = blkdev_get_by_path("/dev/mmcblk0", mode, NULL);
        if (!IS_ERR(bdev)) {
            // 验证块设备是否真正就绪
            if (bdev->bd_inode && bdev->bd_inode->i_size > 0)
                break;
            blkdev_put(bdev, mode);
            bdev = ERR_PTR(-ENODEV);
        }
    }
    
  3. 调整驱动初始化时机
    在代码中用subsys_initcall()替代module_init(),让驱动在MMC子系统之后初始化;或者在Kconfig中添加depends on MMC_BLOCK,确保编译顺序上依赖MMC块设备驱动。

  4. 直接通过MMC子系统获取设备
    绕过块设备路径,直接遍历MMC设备列表找到目标设备,再获取对应的块设备,避免依赖/dev/mmcblk0节点的创建时机。

内容的提问来源于stack exchange,提问作者Loic44000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:19:53