Linux内置驱动无法打开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节点已创建,只是驱动无法打开它,不符合命名空间导致设备不可见的特征。
解决方法
改用异步触发机制
不要在驱动初始化阶段主动打开MMC设备,而是注册设备通知回调,当/dev/mmcblk0节点创建并就绪后再执行打开操作,比如利用udev事件或内核的设备热插拔机制。优化块设备就绪检查逻辑
替换现有重试逻辑,直接通过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); } }调整驱动初始化时机
在代码中用subsys_initcall()替代module_init(),让驱动在MMC子系统之后初始化;或者在Kconfig中添加depends on MMC_BLOCK,确保编译顺序上依赖MMC块设备驱动。直接通过MMC子系统获取设备
绕过块设备路径,直接遍历MMC设备列表找到目标设备,再获取对应的块设备,避免依赖/dev/mmcblk0节点的创建时机。
内容的提问来源于stack exchange,提问作者Loic44000

