【Linux 驱动小白教程】二、驱动Makefile编写 + 模块操作全套命令实操

发布时间:2026/10/4 8:14:59

【Linux 驱动小白教程】二、驱动Makefile编写 + 模块操作全套命令实操 接上一篇从零看懂驱动框架 设备分类 最简模板上一篇我们拿到了最简内核驱动.c源码但是内核驱动不能用gcc直接编译必须借助内核源码树进行编译。本篇讲解驱动专用Makefile语法、编译步骤、insmod/rmmod/lsmod/modinfo/modprobe全套命令新手照着敲即可跑通实验。一、为什么驱动不能直接 gcc xxx.c普通应用程序链接glibc用户态库gcc直接编译。内核驱动运行在内核空间要调用内核导出的函数、头文件必须使用内核本身的编译体系不能链接用户态C库。重点编译驱动必须要有对应版本的内核源码/内核头文件内核版本必须和运行开发板/虚拟机的内核版本严格匹配否则会出现版本魔数校验失败模块加载报错。二、驱动专用Makefile完整模板新建文件名字就叫Makefile注意大小写M大写不要后缀和驱动c文件放在同一个目录。假设驱动源码文件名叫mydrv.c# 判断是否传入KERNELDIR没有就使用本机内核路径 KERNELDIR ? /lib/modules/$(shell uname -r)/build # 当前源码所在目录 PWD : $(shell pwd) # 要编译生成的模块名对应 mydrv.c → mydrv.ko obj-m mydrv.o # make的默认目标 all: make -C $(KERNELDIR) M$(PWD) modules # make clean 清理编译产物 clean: make -C $(KERNELDIR) M$(PWD) cleanMakefile逐行小白讲解KERNELDIR ? /lib/modules/$(shell uname -r)/build?如果变量没有被外部赋值才赋值交叉编译的时候可以外部传入指定内核路径覆盖。$(shell uname -r)shell命令获取当前正在运行的内核版本号。/lib/modules/xxx/buildUbuntu虚拟机本地编译指向内核头文件软链接做开发板交叉编译时这里改成开发板内核源码绝对路径。PWD : $(shell pwd):立即赋值获取当前源码文件夹路径。obj-m mydrv.o核心驱动Makefile最关键一行obj‑m表示把这个文件编译成可动态加载的内核模块.koobj‑y编译进内核镜像zImage开机就内置不能rmmod卸载。mydrv.o对应源码mydrv.c会自动生成mydrv.ko不要写komake -C $(KERNELDIR) M$(PWD) modules-C $(KERNELDIR)切换工作目录到内核源码目录执行内核顶层MakefileM$(PWD)告诉内核编译系统外部模块源码在当前PWD目录modules内核Makefile目标专门编译外部内核模块clean清理编译出来的.ko、.o、.mod.c等中间文件。✅编译操作终端进入源码目录执行make编译成功后目录生成mydrv.ko就是我们的内核模块文件。⚠️交叉编译小提示开发板场景# 示例传入交叉编译器开发板内核路径makeKERNELDIR/home/xxx/linux-5.4ARCHarmCROSS_COMPILEarm-linux-gnueabihf-编译产物说明*.ko真正内核模块拷贝到开发板使用*.mod.c内核自动生成中间文件*.o编译目标文件modules.order、Module.symvers模块符号表多个模块依赖时需要三、内核模块全套操作命令必考实操注意大部分模块加载卸载操作需要root权限Ubuntu加sudo开发板一般默认root。1. lsmod 列出当前已经加载的内核模块lsmod作用查看系统哪些ko已经载入内核第一列模块名第二列占用内存第三列被哪些其他模块依赖。2. insmod 手动加载模块sudoinsmod mydrv.ko直接指定ko文件路径加载。缺点不会自动解决模块依赖如果本模块依赖别的模块insmod会报错。查看打印输出驱动里面printk打印用dmesg看dmesg# 实时追踪打印dmesg-wprintk不会直接输出终端存在内核环形缓冲区要用dmesg查看日志。3. modprobe 智能加载模块sudomodprobe mydrv不需要写.ko后缀只写模块名字会自动查找模块路径自动加载依赖的其他模块前提条件ko需要拷贝到系统模块目录/lib/modules/$(uname -r)/执行depmod更新模块依赖数据库modprobe才能识别。简单理解insmod简单粗暴modprobe智能处理依赖。4. rmmod 卸载模块sudormmod mydrv只写模块名字不要加.ko后缀执行驱动的__exit退出函数。注意模块正在被程序占用的时候rmmod会失败。5. modinfo 查看模块信息modinfo mydrv.ko读取ko内部信息作者、协议、描述、模块参数、版本就是我们代码里MODULE_LICENSE、MODULE_AUTHOR这些宏生成的信息。6. depmod 更新模块依赖数据库配合modprobe使用sudodepmod把新拷贝的ko注册进系统模块列表modprobe才能找到这个模块。完整实操流程示例虚拟机#1 编译make#2 加载模块sudoinsmod mydrv.ko#3 看内核打印dmesg#4 查看已加载模块lsmod#5 查看模块信息modinfo mydrv.ko#6 卸载模块sudormmod mydrv#7 清理编译产物makeclean四、常见踩坑点小白高频报错版本魔数不匹配version magic does not match原因编译用的内核头文件版本 和 运行内核版本不一致。虚拟机不要随便升级内核开发板编译驱动必须使用和烧录内核一模一样的源码。MODULE_LICENSE(GPL)忘记写dmesg里面出现tainted kernel内核污染警告部分内核函数调用直接失败。必须写GPL。make报错找不到内核头文件Ubuntu安装内核头文件sudoaptinstalllinux-headers-$(uname-r)rmmod提示module is in use模块正在被使用有应用程序打开设备要先关闭应用再卸载。modprobe找不到模块ko没有放到系统模块目录没有执行depmod改用insmod指定ko完整路径临时测试。五、本篇知识点总结驱动不能gcc直接编译依靠内核Makefile编译体系obj‑m xxx.o编译生成ko模块。Makefile关键参数‑C切换内核目录M指定外部模块源码目录。命令速记|命令|功能|| ---- | ---- ||lsmod|列出已加载内核模块||insmod xxx.ko|直接加载ko不处理依赖||modprobe xxx|智能加载自动处理依赖||rmmod xxx|卸载模块不加ko后缀||modinfo xxx.ko|查看模块元信息||dmesg|查看printk内核打印||make clean|清理驱动编译产物|本篇为专栏入门免费章节完整专栏包含三大基础驱动设备面向入门、内核机制原理讲解面向面试、多套驱动框架配套源码面向工作等内容后续进阶内容仅专栏订阅用户可见点击专栏主页订阅解锁全部教程。
延伸阅读

更多相关文章

2026/9/27 12:08:27

郑州flash网站建设怎么做企业数字化升级的必修课

在这个信息爆炸的时代,咱们郑州的企业老板们可能每天都在琢磨同一个问题:怎么让我的客户在茫茫 internet 大海中一眼就能看到我的产品?以前咱们做网站,好像就是把电话号码放上去,把产品介绍放上去,觉得这就是万事大吉了。但随着移动互联网的普及,用户的浏览习惯早就变了…

2026/10/4 8:11:24

Qt中轻量HTTP服务器实战:QtWebApp零依赖搭建指南

1. 项目概述:为什么在Qt里自己搭HTTP服务器?不是有现成的Web框架吗?“QtWebApp的使用【在Qt中搭建HTTP服务器】(一)”——这个标题乍看有点反直觉。毕竟Qt是做GUI的,搞HTTP服务器?很多人第一反应…

2026/10/4 8:11:24

Windows 上配置 Codex 全攻略:Node.js、npm 与 VSCode 集成

1. 为什么要在 Windows 上折腾 Codex如果你最近在关注 AI 辅助编程这块,大概率已经听说过 Codex 这个名字。它本质上是一个跑在终端里的智能编程助手,能理解你当前项目的上下文,帮你补全代码、解释逻辑、重构函数,甚至直接根据自然…

2026/10/4 8:11:24

VASP自旋轨道耦合计算全指南:参数设置、三步流程与排错经验

做第一性原理计算的同行,估计都遇到过这种场景:文献里一个重元素材料的能带,费米面附近忽然劈开几条带,或者一个本应显示金属行为的体系,算完却出现了一个微小的带隙。问作者怎么处理的,对方轻描淡写地回一…

2026/10/4 8:11:24

Matlab2018a启动黑屏报错No sandbox解决方案

1. 这个报错不是Matlab本身的问题,而是Qt框架在Windows上的沙箱机制失效了你刚点开Matlab2018a,还没输入一行代码,界面刚弹出来就“啪”一下黑屏退出,控制台里只留下一行冷冰冰的提示:No sandbox or build area path。…

2026/10/4 8:11:24

Codex半年实战盘点:安装配置避坑与省Token技巧

过去这半年,Codex 的变化比我预想的大很多。它从一个在终端里敲命令的编程代理,慢慢长成了带桌面客户端、支持自定义模型、能接 MCP 工具的完整开发助手。但更新越频繁,社区里的报错就越热闹:sign-in could not be completed、tok…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑