linux开发板 之 手动加载.ko驱动

发布时间:2026/9/12 20:45:07
linux开发板 之 手动加载.ko驱动 一、什么是 .ko 内核模块为什么要手动加载Linux内核有两种编译驱动方式内置编译(y)驱动直接编译进内核镜像Image内核启动过程直接初始化不能卸载增大内核体积修改驱动必须完整重编内核。模块编译(m)驱动编译为独立后缀.ko的内核模块文件可在内核运行时动态加载、卸载不需要重启内核。为什么要手动加载 .ko驱动调试阶段修改驱动源码只编译生成.ko不用完整重编整个系统镜像、不用重新烧TF卡。在PC交叉编译把ko传到开发板insmod/rmmod反复测试极大缩短调试周期。部分外设不是必选硬件如OLED显示屏、传感器不是每块板子都外接不需要开机强制内置进内核按需加载。headless无桌面系统的加载链条失效AvaotaOS CLI无桌面版本udev自动匹配加载模块经常失效设备树已经定义设备节点但驱动不会自动probe需要手动加载ko才会触发设备匹配。排查故障定位问题设备树写好但设备没有生成比如没有/dev/fb1、没有wlan0手动加载ko观察dmesg日志快速区分是设备树问题还是驱动本身问题。⚠️ 注意.ko模块有严格版本校验模块编译时的内核版本、vermagic必须和开发板当前运行内核完全一致。版本不匹配insmod直接报Exec format error。二、开发板上手动加载 .ko板子已经烧好镜像运行状态场景调试驱动不重新烧录镜像把编译出来的.ko传到开发板内存/rootfs动态操作。1、获取ko文件两种得到ko的途径完整内核编译产物执行mklinux.sh编译内核后ko会打包进deb包部署后放在开发板/lib/modules/$(uname -r)/目录。板上就地编译ko推荐调试开发板安装内核头文件包linux-headers直接在板子上编译模块生成匹配本机内核的ko不需要交叉编译。# 在开发板上进入驱动源码目录执行 make -C /lib/modules/$(uname -r)/build M$PWD modules # 当前目录就生成xxx.ko把ko传到板子scp工具从编译主机传到开发板scp xxx.ko avaota192.168.x.x:/home/avaota2、核心命令加载、查看、卸载模块# 加载驱动模块insmod原始加载必须写完整ko路径不会自动解决依赖 sudo insmod ssd1307fb.ko # 更推荐 modprobe自动解析模块依赖不需要写ko完整路径 # modprobe会去 /lib/modules/$(uname -r) 搜索模块 sudo modprobe ssd1307fb # 查看已经加载的内核模块 lsmod # 过滤看目标模块 lsmod | grep ssd1307 # 查看模块加载日志重点看probe是否执行成功报错信息 dmesg | grep -i ssd1307 # 卸载模块 sudo rmmod ssd1307fb3、手动加载后probe不触发常见排查即便成功insmod也不代表设备会正常工作很多时候模块加载成功但设备树匹配失败probe函数不会执行dts设备节点的compatible字符串和驱动of_device_id匹配表逐字完全一致大小写、空格不能有差异dts节点状态属性必须设置status okay;不能是disableddtb设备树二进制已经更新板子上/proc/device-tree确认节点生效查看dmesg看是否报i2c/spi总线错误、地址错误。调试流程加载ko → lsmod确认模块驻留 → dmesg查看probe打印信息 → 检查是否生成/dev设备节点。手动加载缺点临时生效重启开发板模块就丢失需要重新手动敲命令加载。只适合调试不适合正式产品。如果驱动有依赖其他模块insmod不会自动加载依赖会报错优先用modprobe。三、方案A板子镜像内开机自动加载系统已经烧录完成事后修改rootfs场景镜像已经烧写到TF卡不想重新编译整套镜像修改板子本地文件实现开机自动加载ko。systemd的systemd‑modules‑load.service服务会读取/etc/modules‑load.d/*.conf开机自动加载列表内模块。在开发板创建conf配置文件一行写一个模块名不带.ko后缀sudo tee /etc/modules-load.d/oled.conf EOF ssd1307fb EOF示例WiFi驱动AIC8800模块有先后加载顺序bsp必须先于fdrvsudo tee /etc/modules-load.d/aic.conf EOF aic8800_bsp aic8800_fdrv EOF可选模块参数、黑名单创建/etc/modprobe.d/xxx.conf# aic-options.conf示例 options aic8800_fdrv firmware_pathaic8800d80 softdep aic8800_fdrv pre: aic8800_bsp重启板子验证sudo reboot # 重启后校验 systemctl status systemd-modules-load.service journalctl -u systemd-modules-load.service lsmod | grep ssd1307fb缺点这是烧卡之后的“修复手段”如果重新烧录全新镜像修改全部丢失需要再次手动操作。适合调试验证量产不推荐。四、方案B镜像编译前固化模块自动加载量产推荐rootfs‑overlay机制场景编译AvaotaOS镜像阶段直接把配置打进镜像烧录完TF卡第一次上电就自动加载模块开箱即用。利用框架的rootfs‑overlay机制在打包rootfs时把文件注入最终镜像。操作步骤在编译主机PC编译环境创建overlay目录cd ~/AvaotaOS mkdir -p rootfs-overlay/etc/modules-load.d创建模块加载配置文件内容和板子上完全一样# OLED模块配置 echo ssd1307fb rootfs-overlay/etc/modules-load.d/oled.conf # WiFi模块配置 printf aic8800_bsp\naic8800_fdrv\n rootfs-overlay/etc/modules-load.d/aic.conf修改打包脚本scripts/pack.sh在解压rootfs之后增加复制overlay全部文件到rootfs_dir 找到脚本中tar -zxvf ... -C rootfs_dir这一行在后面追加cp -a ${workspace}/../rootfs-overlay/* ${workspace}/rootfs_dir/后续完整流程如果修改内核/驱动删除.done标记强制重编内核sudo rm build_dir/avaota-a1-kernel-pkgs/.done sudo bash scripts/mklinux.sh -b avaota-a1 -k no -g bsp -e no执行pack.sh重新打包sdcard.img镜像sudo setsid bash scripts/pack.sh -b avaota-a1 -t cli -v jammy \ -u avaota -p avaota -s avaota pack.log 21 /dev/null tail -f pack.log打包完成后不要忘记补写bootloader引导头AvaotaOS框架bugsudo dd ifbuild_dir/bootloader-syterkit.bin ofbuild_dir/sdcard.img bs1024 seek8 convnotrunc sync烧录前校验镜像loop挂载镜像确认配置文件已经写入镜像内sudo mount -o loop,offset$((524288*512)) build_dir/sdcard.img /mnt ls /mnt/etc/modules-load.d/ sudo umount /mnt烧录镜像到TF卡上电开机系统会自动加载ko模块。扩展搭配systemd服务模块加载完成后执行应用脚本OLED显示logo等也把.service服务文件放入rootfs‑overlay/etc/systemd/system/在pack.sh的chroot段执行systemctl enable xxx.service开启开机自启。overlay适合注入普通文件软链接、apt安装软件包需要在pack.sh的chroot脚本段执行。五、三种加载方式对比总结加载方式操作时机生效范围适用场景重启后insmod / modprobe手动加载板子运行时命令行执行内存临时加载驱动调试快速验证ko不改动镜像重启失效修改/etc/modules‑load.d板上本地修改镜像烧录后板子内修改当前这张TF卡验证自动加载逻辑临时修复镜像缺陷换全新镜像丢失配置rootfs‑overlay编译前固化编译主机打包镜像阶段所有由该脚本生成的sdcard.img镜像量产、发布固件出厂即自动加载永久保存在镜像六、重要踩坑总结.kovermagic必须和板子内核版本完全匹配否则insmod报错Exec format error。mklinux.sh编译内核如果defconfig没有变更框架会读取.done标记跳过编译修改驱动源码必须删除.done文件强制重编。模块CONFIG_XXXm内核配置必须设置为模块编译y代表内置不会生成ko。模块加载成功 ≠ probe执行成功必须核对dts的compatible、status状态查看dmesg日志。