添加驱动模块到内核的两种方法

news2024/11/13 14:42:04

添加驱动模块到内核的两种方法

1. 放在内核源代码树中

步骤总结:

  1. 新建文件夹
  2. 编写Makefile、编写Kconfig
  3. 修改上层Kconfig
  4. 执行make menuconfig
  5. 执行make zImage 或 make modules
1.1 源码放入文件夹

例如:添加一个按键字符设备模块

  • 在内核目录下的 drivers/char 目录下新建文件夹 mykey

  • 在 drivers/char/ 下的 Makefile 中添加一行

    obj-m += mykey/
    这行指令告诉模块构建系统,在编译模块时需要进入 mykey/ 子目录中
        
    有可能的选择是,驱动程序的编译取决于一个特殊的配置选项,例如 CONFIG_MYKEY ,则指令要替换成
    obj-$(CONFIG_MYKEY) += mykey/
    
  • 最后,在 drivers/char/mykey/ 目录下添加一个 Makefile,其中需要有下面这行指令

    obj-m += mykey.o
    表示进入 mykey/ 子目录后,要将 mykey.c 编译成 mykey.o,但最终会生成 mykey.ko 文件
    
    如果加了编译选项,则指令如下
    obj-$(CONFIG_MYKEY) += mykey.o
    
  • 另外,如果后续你的按键程序需要使用到其他的源文件,可以将 mykey/ 目录下的 Makefile 做如下修改

    obj-$(CONFIG_MYKEY) += mykey.o
    mykey-objs := mykey_main.o other.o
    表示 mykey_main.c 和 other.c 会一起被编译和链接进 mykey.ko 文件
    
1.2 源码放入设备总目录下

如果只有一两个源文件,则可以选择不新建文件夹,直接将 mykey.c 放入到 drivers/char/ 目录下,在 drivers/char/ 目录下的 Makefile 中添加如下指令即可

obj-m += mykey.o
    
如果配置了编译选项,则指令为
obj-$(CONFIG_MYKEY) += mykey.o
    
如果有多个源文件,则指令为
obj-$(CONFIG_MYKEY) += mykey.o
mykey-objs := mykey_main.o other.o

即将原本 drivers/char/mykey/Makefile 的内容全部写到 drivers/char/Makefile 中。

1.3 管理配置选项
  • 在 drivers/char/mykey/ 目录下新建一个 Kconfig 文件(如果没有独立目录,则直接在 drivers/char/Kconfig 中添加)

  • 添加如下内容(实例)

    config MYKEY
    	tristate "This is config of mykey"
    	default n
    	help 
    	  If you chose Y, support this key function, 
    	  this key will be compiledinto the kernel.
    	  you can also chose M, then this driver will 
    	  be built as a module named mykey.ko.
    
  1. 第一行定义了该选项所代表的配置目标(注意 CONFIG_ 前缀不必写上)

  2. 第二行声明选项类型为 “tristate” ,它有三个选项N Y M,Y表示可以编译进内核,M表示作为模块编译,N表示不操作。

  3. 第三行是默认的选项类型

  4. help 表示为该选项提供帮助文档

  5. 除了上述选项外,还有其他选项,比如 depends 指令,规定了该选项的依赖选项,表示必须将依赖选项设置,才可以选择本选项

    depends on MENU_KEY

  6. 在 drivers/char/Kconfig 文件中添加

    source “drivers/char/mykey/Kconfig”

执行 make menuconfig 后结果如下
在这里插入图片描述

如果 Kconfig 的内容改成这样(带菜单)

menu "Config my key"

config MYKEY    
	tristate "This is config of mykey"    
	default n    
	help       
		If you chose Y, support this key function,       
		this key will be compiledinto the kernel.      
		you can also chose M, then this driver will       
		be built as a module named mykey.ko.

endmenu

make menuconfig 找到 MYKEY(可以看到多出一个菜单来)
在这里插入图片描述

按 “h” 进入 help
在这里插入图片描述
make menuconfig 之前看一眼内核根目录下的 .config 文件, CONFIG_MYKEY 还未定义

在这里插入图片描述
我们使用 make menuconfig 将 CONFIG_MYKEY 选项选择为 M 后,看一下内核目录下的 .config 文件
在这里插入图片描述

别忘了在 drivers/char/mykey/Makefile 中添加内容

obj-$(CONFIG_MYKEY) += mykey.o

make modules 后观察 drivers/char/mykey/ 目录下的文件,多出了许多文件,其中包括 key.ko
在这里插入图片描述

如果要编译进内核中, CONFIG_MYKEY 选项选择为 Y ,然后执行 make zImage,会发现生成的zImage镜像大小增加了一些,但是不会在 drivers/char/mykey/ 下生成 key.ko ,不过会生成 key.o

PS:obj-y(对应 make zImage))是指将模块编译进内核(zImage)

obj-m(对应 make modules)是指编译模块生成 ko 文件


2. 放在内核代码外

如果我们希望编写的模块可以被动态的加载到内核中,即使用 insmod、modprobe 命令,则不能将模块代码直接放入内核源码树中了。

只需在自己编写的模块目录中新建一个 Makefile 文件,由于是在内核源码外围,所以我们需要告诉 make 工具如何找到内核源代码文件和基础的 Makefile 文件

为什么需要找到内核源码和基础 Makefile 文件?

答:因为驱动代码中使用到了内核提供的函数、头文件等等,编译成最终的 ko 文件也是要遵循内核的编译方法

Makefile 中一定要包含以下指令

make -C 内核所在路径 M=$PWD modules
    
obj-m += mykey.o

一般的 Makefile 的写法如下:

KERN_DIR = /home/内核路径

all:
	make -C $(KERN_DIR) M=`pwd` modules

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean

obj-m += mykey.o

执行make后,生成mykey.ko文件,使用动态加载命令插入进内核

insmod mykey.ko

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1061222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码:对鱼眼相机图像进行去畸变处理

图像投影模型:针孔[fx, fy, cx, cy] 图像畸变模型:切向径向畸变[k1, k2, p1, p2] 说明:用于备忘 第一部分是常规的去畸变操作,在已知内参的情况下对鱼眼相机进行去畸变,这里使用的是remap映射在对图像去畸变后&#x…

毛玻璃 has 选择器卡片悬停效果

效果展示 页面结构 从上述的效果展示可以看到&#xff0c;页面是由多个卡片组成&#xff0c;并且鼠标悬停在卡片上时&#xff0c;会旋转用户图片并且韩式对应的用户信息框。 CSS3 知识点 :has 属性的运用 实现页面整体结构 <div class"container"><div…

复原akshare的股票代码缺失前面000代码

原始的akshare保存成文件&#xff0c;再读取时&#xff0c;代码会被自动转换为如下形式&#xff1a; 我们需要对每一个元素&#xff0c;补齐前面的0&#xff0c;将代码补充为6位 示例程序 import pandas as pdmy_df pd.read_csv("akshare下载文件.csv") my_df[代码…

【Linux基础】Linux发展史

&#x1f449;系列专栏&#xff1a;【Linux基础】 &#x1f648;个人主页&#xff1a;sunny-ll 一、前言 本篇主要介绍Linux的发展历史&#xff0c;这里并不需要我们掌握&#xff0c;但是作为一个合格的Linux学习者与操作者&#xff0c;这些东西是需要了解的&#xff0c;而且…

线程的概述

#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 功能&#xff1a;创建一个子线程 参数&#xff1a; -thread:传出参数&#xff0c;线程创建成功后&#xff0c;子线程的ID被写到…

SSRF+redis未授权漏洞复现

1.SSRF漏洞简介 SSRF&#xff08;Server-Side Request Forgery&#xff09;即服务器端请求伪造&#xff0c;是一种由攻击者构造攻击链传给服务器&#xff0c;服务器执行并发起请求造成安全问题的漏洞&#xff0c;一般用来在外网探测或攻击内网服务。当网站需要调用指定URL地址…

Inno Setup新手使用教程

1.编写脚本.iss文件 2.使用Inno Setup打开脚本 3.点击运行 4.打包好的文件在output文件夹下 注&#xff1a;运行不通过可能是文件不存在或者路径错误 推荐一个零声学院项目课&#xff0c;个人觉得老师讲得不错&#xff0c;分享给大家&#xff1a; 零声白金学习卡&#xff08;含…

重生奇迹MU刷装备注意事项

在打斗游戏里面装备的作用非常巨大&#xff0c;较好的武器装备可以为玩家带来不错的体验&#xff0c;很多玩家甚至不惜花重金打造属于好装备。那么游戏中刷装备需要注意什么。 一、对武器装备的认识 对于玩家来说需要对武器装备有一定的认识&#xff0c;连基本的武器装备分类都…

# Flink的状态

1.什么是时状态(state)&#xff1f; 有状态的计算是流处理框架要实现的重要功能&#xff0c;因为稍复杂的流处理场景都需要记录状态&#xff0c;然后在新流入数据的基础上不断更新状态。 例如以下状态都需要使用流处理的状态功能&#xff1a; 数据流中的数据有重复&#xff0c…

1.springcloudalibaba nacos2.2.3部署

前言 nacos是springcloudalibaba体系的注册中心&#xff0c;演示如何搭建最新稳定版本的linux搭建。 前置条件&#xff0c;安装好jdk1.8 一、二进制压缩包下载 1.1 下载压缩包 nacos下载 点击下载下载后得到二进制包如下 nacos-2.2.3.tar.gz二、安装步骤 2.1.解压二进制…

十、2023.10.4.计算机网络(one).10

文章目录 1、简述静态路由和动态路由&#xff1f;2、说说有哪些路由协议&#xff0c;都是如何更新的&#xff1f;3、简述域名解析过程&#xff0c;本机如何干预域名解析&#xff1f;4、简述 DNS 查询服务器的基本流程是什么&#xff1f;DNS 劫持是什么&#xff1f;5、简述网关的…

Lwip的接收邮箱大小的影响

LwIP&#xff08;Lightweight IP&#xff09;是一个用于嵌入式系统的轻量级的TCP/IP协议栈&#xff0c;它支持UDP和其他网络协议。 接收邮箱大小 在LwIP中&#xff0c;UDP接收邮箱的大小对系统性能和可靠性有一定影响。 首先&#xff0c;UDP接收邮箱的大小决定了可以同时接收…

如何去占用windows端口

一、问题: 测试的服务使用的端口号范围为6881~6888&#xff0c;一般使用6881&#xff0c;如果该端口被占用&#xff0c;应该去使用其他端口&#xff0c;验证是不是真的这样 二、占用windows端口号方法 1、修改注册表 修改window现有远程连接服务的端口号&#xff08;可能有其他…

计算机中的进制转换

在计算机软件中&#xff0c;经常需要进行进制转换&#xff0c;这包括二进制、八进制、十进制和十六进制之间的转换。以下是一些常见的转换方法&#xff1a; 二进制转十进制&#xff1a;这是最直接的转换&#xff0c;基本上不需要什么特别的算法。你只需要按照二进制的权值进行…

MacBook 录制电脑内部声音

MacBook 录制电脑内部声音 老妈喜欢跳广场舞&#xff0c;现在广场舞音频下载都收费了&#xff01;没办法&#xff0c;只能自己录歌了&#xff0c;外录有杂音大家也都知道&#xff0c;所以就只能采用内录的方式然后再用 Audition 调整一下音量大小。 一、&#xff08;前置条件&a…

【计算机网络】高级IO——select

文章目录 1. select函数介绍为什么要有select&#xff1f;select 接口第一个参数 nfds的理解什么是 输入 输出型参数最后一个参数 timeout 的理解readfds writefds exceptfds 参数的理解select的返回值 2. select的使用SelectServer_v1start 最初版本start 最终版本HandlerEven…

【成像光敏描记图提取和处理】成像-光电容积描记-提取-脉搏率-估计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Apollo Planning2.0决策规划算法代码详细解析 (2): vscode gdb单步调试环境搭建

前言: apollo planning2.0 在新版本中在降低学习和二次开发成本上进行了一些重要的优化,重要的优化有接口优化、task插件化、配置参数改造等。 GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端…

C/C++进程超详细详解【下部分】(系统性学习day8)

目录 前言 一&#xff0c;有名管道通信 1 .概念 2 .创建有名管道 实例代码如下&#xff1a; 二、信号通信 1 .概念 2 .用户进程对信号的响应方式 3. 用户进程对常用信号的缺省操作 4. 信号处理流程 5. 信号相关函数(系统调用) 5.1 kill - 给指定进程发送信号 实例代…

使用云服务器部署SpringBoot+Vue项目

一、购买云服务器并配置安全组 二、准备好前后端项目并先打包好 对于前端文件。新建文件 .env.development VUE_APP_BASEURLhttp://localhost:9090 还有新建文件 .env.production VUE_APP_BASEURLhttp://:9090 main.js 设置全局变量 $baseUrl Vue.prototype.$baseUrlproc…