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

Linux驱动加载后如何等待probe执行完成及设备文件生效?

首先澄清核心认知误区

init_module系统调用返回不代表probe()一定执行完成:
对于总线型驱动(PCI/USB/平台设备等绝大多数现代驱动),模块初始化函数(module_init修饰的函数)仅负责把驱动注册到总线框架,注册完成就会返回init_module,probe()是总线后续匹配到对应设备时异步调度执行的。就算probe()执行完device_create,/dev下的设备文件还需要用户空间udev/systemd-udevd处理内核uevent、执行规则后才会生成,这一步也存在异步延迟,这就是你遇到设备文件不立即出现的核心原因。


正确的等待方案

方案1:用户空间通用轮询(无依赖,兼容性最好)

直接轮询检查目标设备路径是否存在,超时时间按硬件初始化最坏情况设置即可,示例shell代码:

DEVICE_PATH="/dev/你的设备名"
TIMEOUT=10
COUNT=0
while [ ! -e "$DEVICE_PATH" ] && [ $COUNT -lt $TIMEOUT ]; do
    sleep 0.5
    COUNT=$((COUNT+1))
done
if [ ! -e "$DEVICE_PATH" ]; then
    echo "等待设备文件超时"
    exit 1
fi

C语言实现可替换为stat()系统调用轮询,逻辑完全一致。

方案2:监听uevent事件(效率更高)

device_create执行完成后内核会发送add类型的uevent,可直接用udev自带工具等待udev处理完所有规则,设备文件生成后再返回:

udevadm wait --timeout=10 /dev/你的设备名

有二次开发需求也可以自己监听netlink套接字捕获对应设备的add uevent,匹配成功即可确认内核侧设备创建完成。

方案3:内核侧同步改造(可修改驱动源码时使用)

如果能控制驱动代码,可直接在模块初始化逻辑中加同步机制,保证init_module返回前probe()已经执行完成:

  • 自定义平台设备驱动可在module_init中先注册设备,再注册驱动,总线匹配后会同步执行probe(),probe返回后module_init才会结束。
  • 也可以用内核完成量struct completion实现同步:probe结束时调用complete(),module_init中调用wait_for_completion()阻塞等待,按需设置超时时间即可。
    注意:不要在probe中执行耗时过长的操作,否则会阻塞模块加载,甚至触发内核软锁告警。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:15:05