嵌入式驱动学习第五周——驱动模块

news2024/11/24 8:59:42

前言

   Linux驱动有两种运行方式,第一种是将驱动编译进Linux内核中,另一种是编译成模块,本篇博客来介绍一下驱动模块。

   嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程,未来预计四个月将高强度更新本专栏,喜欢的可以关注本博主并订阅本专栏,一起讨论一起学习。现在关注就是老粉啦!

目录

  • 前言
  • 1. 驱动模块介绍
  • 2. 模块加载与卸载
  • 3. 用户空间和内核空间
  • 参考资料

1. 驱动模块介绍

   Linux 驱动有两种运行方式,第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启动的时候就会自动运行驱动程序。第二种就是将驱动编译成模块(Linux 下模块扩展名为.ko),在Linux 内核启动以后使用“insmod”命令加载驱动模块。在调试驱动的时候一般都选择将其编译为模块,这样我们修改驱动以后只需要编译一下驱动代码即可,不需要编译整个 Linux 代码。而且在调试的时候只需要加载或者卸载驱动模块即可,不需要重启整个系统。

   将驱动编译成模块最大的好处就是方便开发,当驱动开发完成,确定没有问题后就可以选择性的将驱动编译进Linux内核中。

   整体驱动如下所示,应用软件根据主次设备号查看设备节点,调用相应的底层驱动。

在这里插入图片描述

2. 模块加载与卸载

   模块有加载和卸载两种操作,在编写驱动时需要注册这两种操作函数,即入口和出口:

module_init(xxx_init);		// 注册模块加载函数
module_exit(xxx_exit);		// 注册模块卸载函数

   module_init是用来向Linux内核注册一个模块加载函数,参数xxx_init就是需要注册的具体函数,当在终端使用insmod命令加载驱动时,xxx_init函数就会被调用。同样的道理,module_exit是用来向Linux内核注册一个模块卸载函数,参数xxx_exit是需要注册的具体函数,当在终端使用rmmod时,xxx_exit函数就会被调用。驱动模块加载和卸载模板如下:

// 驱动入口函数
static int __init xxx_init(void) {
	// 入口函数的具体内容
	return 0;
}

// 驱动出口函数
static void __exit xxx_exit(void) {
	// 入口函数的具体内容
	return 0;
}

module_init(xxx_init);		// 注册模块加载函数
module_exit(xxx_exit);		// 注册模块卸载函数

   __init 标记的函数会在模块被加载时执行,用于初始化驱动所需的数据结构、注册设备、申请资源等操作。这些函数只会在模块加载时执行一次,之后就不再需要,因此被标记为 __init,以表示它们只在初始化时执行。__exit同理。

   驱动编译完成后生成一个扩展名为.ko的模块驱动文件,ko文件在数据组织形式上是ELF(Excutable And Linking Format)格式,是一种普通的可重定位目标文件。 这类文件包含了代码和数据,可以被用来链接成可执行文件或共享目标文件,静态链接库也可以归为这一类。

在这里插入图片描述

   加载模块驱动有两种命令:insmodmodprobe,区别是insmod不能解决模块依赖关系,比如led.ko依赖于gpioled.ko,就必须先试用insmod加载gpioled.ko,再加载led.ko。但是modprobe就会分析模块依赖关系,然后将所有依赖模块加载到内核中。推荐使用modprobe

   modprobe查找模块的目录为:/lib/modules/<kernel-version>,如果没有该目录,需要像我上面一样新建一个目录。

   整体模块驱动结构如下:

在这里插入图片描述

3. 用户空间和内核空间

   为了彻底解决一个应用程序出错不影响系统和其它app的运行,操作系统给每个app一个独立的假想的地址空间,这个假想的地址空间被称为虚拟地址空间(也叫逻辑地址),操作系统也占用其中固定的一部分,32位Linux的虚拟地址空间大小为4G,并将其划分两部分:

0~3G 用户空间 :每个应用程序只能使用自己的这份虚拟地址空间
3G~4G 内核空间:内核使用的虚拟地址空间,应用程序不能直接使用这份地址空间,但可以通过一些系统调用函数与其中的某些空间进行数据通信

在这里插入图片描述

   所有系统资源的管理都是在内存空间进行的,也就是在内核态去做的,那我们应用程序需要访问磁盘,读取网卡的数据,新建一个线程都需要通过系统调用接口,完成从用户态到内存态的切换。

   但是内核态和用户态不能相互访问,因此需要使用copy_from_usercopy_to_user将数据拷贝到所需要的地方。

 /*
  * @description: 将数据从用户空间复制到内核空间
  * @param-to   : 指向内核空间的指针
  * @param-from : 用户空间的指针
  * @param-n	: 复制的字节数
  * @return     : 该函数返回未能复制的字节数,如果返回值为0,则表示全部复制成功
  */
unsigned long copy_from_user(void *to, const void __user *from, unsigned long n);
 /*
  * @description: 将数据从内核空间复制到用户空间
  * @param-to   : 指向用户空间
  * @param-from : 内核空间的指针
  * @param-n	: 复制的字节数
  * @return     : 该函数返回未能复制的字节数,如果返回值为0,则表示全部复制成功
  */
unsigned long copy_to_user(void __user *to, const void *from, unsigned long n);

   需要注意的是,由于用户空间和内核空间是分离的,因此在进行数据传输时需要进行安全检查,以防止非法访问。在使用copy_from_usercopy_to_user函数时,需要使用access_ok函数进行检查,以确保指针指向的内存区域是合法的。例如:

if (access_ok(VERIFY_READ, from, cnt)) {
    if (copy_from_user(to, from, cnt)) {
        printk("kernel write failed!\r\n");
        return -EFAULT;
    }
} else {
    printk("Illegal memory");
}

参考资料

[1] 【正点原子】I.MX6U嵌入式Linux驱区动开发指南 第四十章
[2] 内核空间与用户空间
[3] 用户空间和内核空间的区别

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

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

相关文章

机器学习实战17-高斯朴素贝叶斯(GaussianNB)模型的实际应用,结合生活中的生动例子帮助大家理解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战17-高斯朴素贝叶斯(GaussianNB)模型的实际应用&#xff0c;结合生活中的生动例子帮助大家理解。GaussianNB&#xff0c;即高斯朴素贝叶斯模型&#xff0c;是一种基于概率论的分类算法&#xff0c;广泛应…

open Gauss 数据库-04 openGauss数据库日志管理指导手册

发文章是为了证明自己真的掌握了一个知识&#xff0c;同时给他人带来帮助&#xff0c;如有问题&#xff0c;欢迎指正&#xff0c;祝大家万事胜意&#xff01; 目录 前言 openGauss 数据库日志管理 1 实验介绍 2 实验目的 3 系统日志 3.1 运行时日志 3.2 安装卸载时日志…

高效批量剪辑视频,一键设置区间随机抽取画面,批量剪辑视频不再是梦!

在数字世界的浩瀚海洋中&#xff0c;视频内容日益丰富&#xff0c;如何从冗长的视频中快速抓取关键瞬间&#xff0c;将精彩定格为永恒&#xff1f;今天&#xff0c;我们为你带来一款强大的视频剪辑工具&#xff0c;它拥有批量从视频中指定区间随机抽帧并导出保存的功能&#xf…

9.动态规划——3.最大上升子序和

例题——最大上升子序和 分析 需要定义状态 d p [ i ] dp[i] dp[i]&#xff0c;表示前i个元素中&#xff0c;包含第i个元素 a [ i ] a[i] a[i]的最大子序和&#xff0c;则&#xff1a; 若有 j ∈ [ 0 , i − 1 ] j∈[0,i-1] j∈[0,i−1] 当 a [ j ] < a [ i ] a[j]<a[i]…

maven构建项目报错:Failure to find com.microsoft.sqlserver:sqljdbc4:jar:4.0 in

背景 今天在项目里面查询sqlserver的数据库的时候&#xff0c;本地maven中引入依赖&#xff1a; <dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>sqljdbc4</artifactId><version>4.0</version></dependenc…

苍穹外卖05(Redis入门,下载于安装,服务启动和停止,Redis数据类型面试题,常用命令,Java中操作Redis,店铺营业状态设置)

目录 一、Redis入门 1. Redis简介 1 NoSQL介绍 2 Redis简介 2. Redis下载与安装 1 Redis下载 2 Redis安装 3. Redis服务启动与停止 1 服务启动命令 2 客户端连接命令 3 修改Redis配置文件 3 修改Redis配置文件 4 Redis客户端图形工具 二、Redis数据类型【面试题】…

【Leetcode】top 100 图论

基础知识补充 1.图分为有向图和无向图&#xff0c;有权图和无权图&#xff1b; 2.图的表示方法&#xff1a;邻接矩阵适合表示稠密图&#xff0c;邻接表适合表示稀疏图&#xff1b; 邻接矩阵&#xff1a; 邻接表&#xff1a; 基础操作补充 1.邻接矩阵&#xff1a; class GraphAd…

轻松设置Facebook自动隐藏评论和删除评论功能

Facebook作为海外营销的最大流量平台之一&#xff0c;是很多跨境卖家争夺的市场&#xff0c;希望可以通过Facebook这个全球性的平台来推广自己的产品或服务。身处这个竞争激烈的市场&#xff0c;任何一条负面评论或不当言论出现在你的品牌页面上都可能影响到品牌形象&#xff0…

基于PSO优化的CNN-LSTM-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络&#xff08;CNN&#xff09;在时间序列中的应用 4.2 长短时记忆网络&#xff08;LSTM&#xff09;处理序列依赖关系 4.3 注意力机制&#xff08;Attention&#xff09; 5…

【虚幻引擎】C++ slate全流程开发教程

本套课程介绍了使用我们的虚幻C去开发我们的编辑器&#xff0c;扩展我们的编辑器&#xff0c;设置我们自定义样式&#xff0c;Slate架构设计&#xff0c;自定义我们的编辑器样式&#xff0c;从基础的Slate控件到我们的布局&#xff0c;一步步的讲解我们的的Slate基础知识&#…

Unity UGUI之Text组件基础认识

Text组件用于在游戏中显示文本。 下面来细看下它的基本信息。 一、基本属性&#xff1a; 如上图所示&#xff0c;即为Text组件的一些基本属性&#xff0c;其中&#xff0c; Text&#xff1a;要显示的文本内容。Font&#xff1a;文本所使用的字体。Font Style&#xff08;字体…

iPhone设备中查看应用程序崩溃日志的最佳实践与经验分享

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

【工具-MATLAB】

MATLAB ■ MATLAB-简介■ MATLAB-应用领域■ MATLAB■ MATLAB■ MATLAB■ MATLAB ■ MATLAB-简介 MATLAB是matrix&laboratory两个词的组合&#xff0c;意为矩阵工厂&#xff08;矩阵实验室&#xff09; 美国MathWorks公司出品的商业数学软件, MATLAB和Mathematica、Maple并…

数据结构与算法 顺序串的基本运算

一、实验内容 编写一个程序sqstring.cpp&#xff0c;实现顺序串的各种基本运算&#xff0c;并在此基础上实现一个程序exp7.cpp&#xff0c;完成以下功能&#xff1a; &#xff08;1&#xff09;建立串s“abcdefghefghijklmn”和串s1“xyz” &#xff08;2&#xff09;输出串…

计算机视觉新巅峰,微软牛津联合提出MVSplat登顶3D重建

开篇&#xff1a;探索稀疏多视图图像的3D场景重建与新视角合成的挑战 3D场景重建和新视角合成是计算机视觉领域的一项基础挑战&#xff0c;尤其是当输入图像非常稀疏&#xff08;例如&#xff0c;只有两张&#xff09;时。尽管利用神经场景表示&#xff0c;例如场景表示网络&a…

AR和VR如何改变客户体验?

How AR and VR are transforming customer experiences&#xff1f; How AR and VR are transforming customer experiences AR和VR如何改变客户体验 AR and VR technology was largely expedited by the past pandemic with at least 93.3 million and 58.9 million users r…

类的函数成员(三):拷贝构造函数

一.什么是拷贝构造函数&#xff1f; 1.1 概念 同一个类的对象在内存中有完全相同的结构&#xff0c;如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员&#xff0c;而函数成员是共用的&#xff08;只有一份拷贝&#xff09;。 在建立对象…

String Encryptor custom Bean not found with name ‘jasyptStringEncryptor‘...

项目采用 spring boot 2.6.13 jasypt-spring-boot-starter 3.0.5 apollo-client 1.6.0 自定义jasyptStringEncryptor&#xff0c;服务器上启动死活报找不到bean jasyptStringEncryptor&#xff0c;采用默认的&#xff0c;密文配置项自然解密失败导致服务无法启动。 经过一…

EXCEL VBA与CSV的结合使用,提高多个CSV的处

EXCEL VBA与CSV的结合使用&#xff0c;提高多CSV的处理 1、首先创建一个文本文件&#xff0c;然后将copy *.csv 合并.csv粘贴&#xff0c;并重命名后缀未bat 2、将bat和多个CSV放一个路径下 3、双击运行合并.bat&#xff0c;运行完成会后生成合并.csv 4、将csv用Excel打开&…

蓝桥杯第十五届抱佛脚(九)动态规划

蓝桥杯第十五届抱佛脚&#xff08;九&#xff09;动态规划 基本概念 动态规划(Dynamic Programming, DP)是一种用于解决复杂问题的优化算法设计技术。它将原问题分解为若干相互重叠的子问题,通过记录子问题的解,避免重复计算,从而大大减少了计算量。 动态规划典型的应用场景…