当前位置: 首页 > news >正文

28.驱动程序,生成ko文件,需要放到特定文件夹去编译吗?

编写Linux内核驱动生成.ko(内核模块)文件,不一定需要把代码放到内核源码目录编译,但核心取决于你的编译方式——有两种主流方式,对应不同的文件存放逻辑,推荐第二种(更灵活):

一、两种编译方式的文件存放规则

方式1:内核源码树内编译(传统方式,需放特定目录)
  • 要求:必须把驱动代码放到Linux内核源码的指定目录(如drivers/i2c/devices/drivers/misc/);
  • 原因依赖内核源码的Makefile体系,需要修改目录下的KconfigMakefile,让内核编译系统识别你的驱动
  • 步骤示例(以AHT20驱动为例):
  • aht20.c放到linux-src/drivers/i2c/devices/
  • 修改该目录下的Makefile,添加:obj-$(CONFIG_AHT20) += aht20.o
  • 修改该目录下的Kconfig,添加驱动配置项;
  • 回到内核根目录,执行make modules编译出.ko
  • 缺点:侵入内核源码,不灵活,多驱动开发时易混乱;
  • 适用场景:驱动需要合入内核主线、或依赖内核深层接口。
方式2:内核源码树外编译(推荐,无需放特定目录)
  • 核心:通过自定义Makefile指定内核源码路径,驱动代码可放在任意目录(如/home/yourname/drivers/aht20/);
  • 原理:自定义Makefile通过KERNELDIR指向内核源码目录,借助内核的scripts/Makefile.modpost工具完成编译,无需修改内核源码;
  • 优势:驱动代码独立,编译不影响内核源码,灵活易管理;
  • 新手必用:99%的嵌入式驱动开发场景(如AHT20/PCF8574驱动)都用这种方式。

二、独立目录编译.ko(无需内核源码目录)

以编译AHT20驱动为例,全程无需把代码放进内核目录:

步骤1:任意目录创建驱动代码和Makefile

比如在/home/root/drivers/aht20/下创建两个文件:

  • aht20.c(驱动源码,略);
  • Makefile(核心,指定内核路径和编译规则):
# 1. 指定你的内核源码目录(开发板对应的内核源码,不是系统内核) KERNELDIR ?= /home/root/linux-4.19.35-imx6ul # 替换为你的内核源码路径 # 2. 指定编译后的模块存放目录(可选,默认当前目录) PWD ?= $(shell pwd) # 3. 内核模块编译规则 obj-m += aht20.o # 要编译的驱动文件:aht20.c → aht20.ko # 4. 编译目标 all: make -C $(KERNELDIR) M=$(PWD) modules # -C进入内核目录,M指定驱动目录 clean: make -C $(KERNELDIR) M=$(PWD) clean
步骤2:编译生成.ko

在驱动目录执行编译命令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- # 交叉编译(根据你的编译器调整)
  • ARCH=arm:指定CPU架构(ARM);
  • CROSS_COMPILE:指定交叉编译器前缀(和你的开发板匹配);
  • 编译完成后,当前目录会生成aht20.ko(还有.o/.mod.c等中间文件)。
关键注意事项
  • 内核源码必须匹配
    • 编译.ko的内核源码,必须和开发板运行的内核“版本+配置+编译选项”完全一致(否则insmod时会报version magic mismatch);
    • 比如开发板内核是4.19.35,就必须用同版本的内核源码编译,不能用Ubuntu系统的内核源码。
  • 无需修改内核源码
    • 这种方式完全独立,不用动内核目录的任何文件,驱动代码放在任意目录都能编译;
    • 若驱动依赖内核头文件(如linux/i2c-dev.h),内核源码会自动提供,无需额外拷贝。
  • 编译工具链匹配
    • 必须用和内核编译相同的交叉编译器(比如内核用arm-linux-gnueabihf-gcc 7.5,驱动也得用这个版本)。

三、常见误区澄清

  1. “必须放内核目录”是错的:只有要把驱动合入内核主线时才需要,普通开发完全不用;
  2. “任意目录编译”的前提:内核源码必须提前配置(make defconfig/make menuconfig)并编译过(至少编译出vmlinux),否则会缺少头文件和编译依赖;
  3. .ko的安装:编译好的.ko无需放到内核目录,直接拷贝到开发板任意目录(如/lib/modules/$(uname -r)/extra/),执行insmod aht20.ko即可加载。

总结

  • 无需把驱动代码放到内核特定目录编译,独立目录+自定义Makefile是嵌入式驱动开发的标准做法;
  • 核心是Makefile中指定正确的内核源码路径,保证内核版本、工具链和开发板匹配;
  • 对你的AHT20/PCF8574驱动开发,直接在自己的工作目录(如~/drivers/)创建代码和Makefile,编译即可,完全不用动内核源码目录。
http://www.cnnetsun.cn/news/69932.html

相关文章:

  • 嵌入式系统时序图完全指南:从原理到实战
  • 小团队与大团队的管理差异
  • [CISCN2019 华东南赛区]Web4
  • AI编程革命!Claude Skills大揭秘:小白也能快速上手的Agent开发神器,大模型开发者必看!
  • 内点法求最优潮流附matlab代码
  • 三相PWM整流器有限集模型预测电流控制附Simulink仿真模型
  • 光伏四可“可观”功能:光伏电站全景数字化的底层支撑技术
  • 如何用FLUX.1-dev镜像在本地部署下一代AI绘画模型?
  • 基于 Comsol 移动网格方法的激光熔池流动数值模拟
  • BLDC无刷直流电机Matlab仿真:转速电流双闭环控制及有感无感换相方式研究
  • [光学原理与应用-491]:水冷机、零气模块CDA、功率计等影响266皮秒紫外激光器的种子源1064nm功率稳定性结果的主要因素有哪些?
  • 昆仑通态MCGS与欧姆龙E5CC温控器通讯实战:PID模式及输出启停控制
  • 通达信〖逆势突破强牛〗指标公式 逆市环境中率先突破前期重要压力位 较强内在上涨动力
  • 基于扰动观测器的永磁同步电机(PMSM)模型预测控制(MPC)仿真探索
  • AEB联合仿真算法设计:Carsim2019.0+Matlab/Simulink2021a实现...
  • Java毕设选题推荐:基于springboot个人博客系统的设计与实现基于SpringBoot+Vue个人博客系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设选题推荐:基于springboot停车场车位预约系统基于Java springboot停车场管理系统停车位预约【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设选题推荐:基于springboot的无人化、线上化、数据化海洋馆预约系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Ascend C高级API应用:InitGlobalMemory与Pad操作的底层原理
  • Java毕设选题推荐:基于Java Web的新能源汽车信息咨询服务基于SpringBoot+Vue的新能源汽车信息咨询服务的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:OPA 集成指南:从原理到实践
  • Object.defineProperty和Proxy实现拦截的区别
  • 若依物联网
  • PSEN1抗体:如何揭示阿尔茨海默病致病机制与治疗新靶点?
  • Docker Engine 升级指南:保障容器安全的关键步骤
  • 基于zigbee灯光控制照明及色温调节系统的设计与实现(有完整资料)
  • 7、Python高级语法:描述器、属性与元编程实战
  • 【开题答辩全过程】以 基于java技术的校园一卡通系统的设计与实现为例,包含答辩的问题和答案
  • 11、Python 包与应用开发全解析
  • django基于智能推荐算法的全屋定制平台网站设计