最稳妥的启动加载方式是将模块名写入 /etc/modules-load.d/ 目录下的 .conf 文件,systemd 启动时自动按行加载并处理依赖;其他方式如 rc.local、udev 规则或 SysVinit 脚本均适用特定场景,非通用首选。

模块名写进 /etc/modules-load.d/ 是最稳妥的启动加载方式
系统启动时,systemd 会读取 /etc/modules-load.d/ 下所有 .conf 文件,按行加载模块名(不带 .ko 后缀),且自动处理依赖。这是目前主流发行版(如 Debian、Ubuntu、CentOS 8+、openSUSE)默认启用的方式,兼容性好、无需手动调用 depmod(只要模块已正确安装)。
常见错误现象:modprobe: FATAL: Module xxx not found in directory /lib/modules/$(uname -r) —— 实际是模块文件没放对位置,不是配置问题。
- 把
mydrv.ko拷到/lib/modules/$(uname -r)/目录下(不是子目录,除非你额外建了extra/并更新了depmod) - 执行
sudo depmod -a,确保modules.alias和modules.dep包含该模块信息 - 新建
/etc/modules-load.d/mydrv.conf,内容只有一行:mydrv - 重启或运行
sudo systemctl restart systemd-modules-load立即生效
rc.local 加载只适合调试,别在 systemd 系统里当主力
很多旧文档仍推荐改 /etc/rc.local,但在默认启用 systemd 的系统中,它已被弃用——rc-local.service 默认不启用,且执行时机晚于模块依赖链建立阶段,容易因依赖未就绪导致 insmod 失败。
使用场景:仅限快速验证模块能否加载成功,或临时绕过模块自动发现机制(比如设备 ID 不匹配、需强制加载)。
- 确认
rc-local.service已启用:sudo systemctl enable rc-local - 在
/etc/rc.local的exit 0前插入:/sbin/modprobe mydrv(优先用modprobe,不是insmod) - 必须给文件加可执行权限:
sudo chmod +x /etc/rc.local - 注意:如果模块依赖其他模块(如
usbcore),rc.local执行时这些依赖可能尚未 ready,modprobe会静默失败
用 udev 规则实现“插拔即加载”,不是开机加载
udev 规则触发的是设备热插拔事件(ACTION=="add"),不是系统启动阶段的行为。它适用于 USB 设备、PCIe 设备等有明确总线 ID 的硬件,目标是“设备一接入就加载对应驱动”,而非“开机就加载”。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
容易踩的坑:规则写错路径或匹配条件,导致规则完全不触发;或误以为它能替代开机加载逻辑。
- 规则文件放在
/etc/udev/rules.d/99-mydrv.rules,内容示例:ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", RUN+="/sbin/modprobe mydrv" - 规则中不能用
insmod,必须用modprobe(udev进程无权直接操作内核模块) - 写完后执行
sudo udevadm control --reload-rules,再插拔设备测试 - 调试用:
udevadm monitor --subsystem-match=usb查看是否捕获到事件
嵌入式 SysVinit 系统请用 /etc/init.d/ 脚本 + Sxx 符号链接
ARM 嵌入式 Linux(如 Yocto、Buildroot 默认配置)若用 sysvinit 而非 systemd,/etc/modules-load.d/ 不起作用。此时必须靠 init 脚本控制加载顺序和时机。
关键点在于脚本执行顺序:模块必须在相关总线(如 usb、platform)初始化完成后再加载,否则 modprobe 会找不到总线子系统。
- 脚本命名为
/etc/init.d/S10mydrv(数字越小越早执行,S10通常足够靠前) - 脚本内用
case "$1" in start) modprobe mydrv ;;结构,确保支持start参数 - 确保脚本有可执行权限:
chmod +x /etc/init.d/S10mydrv - 不需要手动创建
/etc/rcX.d/下的软链接——SysVinit 会按文件名排序自动执行Sxx*脚本
真正麻烦的不是怎么写脚本,而是模块依赖关系没理清:比如你的驱动依赖 usbserial,但后者没被提前加载,modprobe mydrv 就会失败,且错误信息往往只显示“no such device”而不是“missing dependency”。建议先手动跑一遍 modprobe -D mydrv 看依赖树,再决定加载时机。

















