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

前言

   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.mzph.cn/news/785229.shtml

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

相关文章

Oladance、南卡、韶音开放式耳机值得买吗?爆款实测拒绝踩坑!

​在寻找最佳开放式耳机的过程中&#xff0c;我亲自试用并评估了市场上三个备受欢迎的品牌&#xff1a;Oladance、南卡和韶音。通过全面的多维度性能测试&#xff0c;我旨在为大家提供准确的购买指南&#xff0c;避免因选择不当而遭遇音质失真或佩戴不适的问题。 选择正确的耳…

window7 SP2

网上很多window7 SP1的更新教程&#xff0c;很少有sp2的教程 参考博客Windows 7 Service Pack 2 Download and Install (64-bit/32-bit) 即 转到 Microsoft 网站上的 Windows 7 Service Pack 2下载页面 。 选择与 Windows 7 版本相对应的 “下载 ”链接。 也可以 登录官网…

【LeetCode周赛】第 391 场周赛

目录 100263. 哈沙德数 简单100235. 换水问题 II 中等100266. 交替子数组计数 中等 100263. 哈沙德数 简单 100263. 哈沙德数 分析&#xff1a; 按题意将数的各个数位进行求和&#xff0c;计算即可。 代码&#xff1a; class Solution { public:int sumOfTheDigitsOfHarsha…

https安全性 带给im 消息加密的启发

大家好&#xff0c;我是蓝胖子&#xff0c;在之前# MYSQL 是如何保证binlog 和redo log同时提交的&#xff1f;这篇文章里&#xff0c;我们可以从mysql的设计中学会如何让两个服务的调用逻辑达到最终一致性&#xff0c;这也是分布式事务实现方式之一。今天来看看我们能够从http…

get和post的区别!

1.get请求一般是去取获取数据&#xff08;其实也可以提交&#xff0c;但常见的是获取数据&#xff09;&#xff1b; post请求一般是去提交数据。 2.get因为参数会放在url中&#xff0c;所以隐私性&#xff0c;安全性较差&#xff0c;请求的数据长度是有限制的&#xff0c; 不同…

【Qt 学习笔记】Day3 | 使用两种方式实现helloworld

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Day3 | 使用两种方式实现helloworld 文章编号&#xff1a;Qt 学习笔记…

【CTSDB数据集转换成YOLO格式】

CSTDB数据集介绍 CTSDB数据集 Dataset consists of 5998 traffic sign images of 58 categories. Each image is a zoomed view of single traffic sign. Annotations provide image properties (file_name, width, height) as well as traffic sign coordinates within imag…

移动硬盘怎么加密?移动硬盘加密软件有哪些?

移动硬盘是我们在工作中最常用的移动存储设备&#xff0c;为了保护数据安全&#xff0c;需要使用专业的移动硬盘加密软件加密保护。那么&#xff0c;移动硬盘加密软件有哪些&#xff1f; ​BitLocker BitLocker是Windows的磁盘加锁功能&#xff0c;可以用于加密保护移动硬盘中…

火焰烟雾AI识别检测算法---豌豆云

烟雾火焰AI识别算法是一项重要的火灾预防工具。近年来&#xff0c;火灾的发生频率和范围不断扩大&#xff0c;给人们和社会经济造成了巨大的损失&#xff0c;已成为一种普遍而破坏性极大的自然灾害。 火灾一旦爆发&#xff0c;火势迅速蔓延&#xff0c;烟雾浓度高&#xff0c;…

MySQL(常用函数、多表查询)

文章目录 1.数据库函数1.count函数案例答案count&#xff08;*&#xff09;与count&#xff08;列&#xff09;的区别 2.sum函数案例答案 3.avg函数案例答案 4.max/min函数案例答案 5.group by 分组统计案例答案 6.字符串相关函数演示练习 7.数学相关函数演示 8.日期相关函数演…

Linux系统使用Docker部署个人IT工具箱IT-Tools结合内网穿透实现公网访问

作为程序员&#xff0c;在日常工作中&#xff0c;需要借助一些工具来提高我们工作效率&#xff0c;IT-Tools是为开发人员度身打造的一套便捷在线工具。它提供全面功能&#xff0c;使开发者能以更高效方式完成任务。经由IT-Tools&#xff0c;开发人员能轻松应对各类技术挑战&…

算法刷题记录 Day28

算法刷题记录 Day28 Date: 2024.03.23 lc 45. 跳跃游戏II // 使用范围计算 class Solution { public:int jump(vector<int>& nums) {if(nums.size() 1)return 0;int pre_range 0;int range 0; // 当前覆盖范围int cur_steps 0; // 当前步数// 每次遍历当…

鸿蒙OS开发实例:【通知消息】

背景 HarmonyOS 论坛中有研发人员求助&#xff0c;反馈通知没有没有声音&#xff0c;因此在真机上验证了一下&#xff0c;果不其然&#xff0c;没有通知的提示音&#xff0c;后来解决办法也非常简单&#xff0c;在手机设置应用中&#xff0c;将可以打开的通知提示统统改为铃声…

告别繁琐代码,只需简单拖拽,便可从0到1开发!

告别繁琐代码&#xff0c;拥抱科技未来&#xff01;只需简单拖拽&#xff0c;便可从0到1开发&#xff01;代码即刻生成&#xff0c;一键下载&#xff0c;轻松上手。我们的低代码平台&#xff0c;不仅高效便捷&#xff0c;更完全开源&#xff0c;让你自由探索编程的无限可能&…

利用DNDC模型分析温室气体排放的建模方法与实践

碳循环的精确模拟是实现“双碳”行动的关键。DNDC&#xff08;Denitrification-Decomposition&#xff0c;反硝化-分解模型&#xff09;是目前国际上最为成功的模拟生物地球化学循环的模型之一&#xff0c;自开发以来&#xff0c;经过不断完善和改进&#xff0c;从模拟简单的农…

算法—递归逆序栈、排序栈

递归和栈 1. 递归逆序栈2. 递归排序栈 1. 递归逆序栈 只用递归逆序一个栈&#xff0c;时间复杂度O(n^2) // 栈底元素移除掉&#xff0c;上面的元素盖下来 // 返回移除掉的栈底元素 public static int bottomOut(Stack<Integer> stack) {int ans stack.pop();if (stack…

MySQL TDE 透明数据加密 知识总结

目录 一、存储加密说明 二、TDE概述 三、MySQL对TDE支持情况 四、注意事项 一、存储加密说明 MySQL数据库存储加密有多种方式可供选择&#xff0c;主要分为两大类&#xff1a; 利用字段加密&#xff0c;在对数据库存储/读取时进行加密/解密操作&#xff0c;需要用户修改应…

设计模式-装饰者模式在Java中使用实例-打印发票装饰抬头和脚注

场景 设计模式-装饰者模式在Java中的使用示例&#xff1a; 设计模式-装饰者模式在Java中的使用示例_java装饰者模式例子-CSDN博客 上面装饰器的调用示例如下 AbstarctComputer computer;//要买1台电脑computer new BaseComputer();//加一个内存条computer new MemoryDecor…

【面试专题】Spring高频面试题

1.Spring应该很熟悉吧&#xff1f;来介绍下你的Spring的理解 有些同学可能会抢答&#xff0c;不熟悉!!! 好了&#xff0c;不开玩笑&#xff0c;面对这个问题我们应该怎么来回答呢&#xff1f;我们给大家梳理这个几个维度来回答 1.1 Spring的发展历程 先介绍Spring是怎么来的…

密码学 总结

群 环 域 群 group G是一个集合&#xff0c;在此集合上定义代数运算*&#xff0c;若满足下列公理&#xff0c;则称G为群。 1.封闭性 a ∈ G , b ∈ G a\in G,b\in G a∈G,b∈G> a ∗ b ∈ G a*b\in G a∗b∈G 2.G中有恒等元素e&#xff0c;使得任何元素与e运算均为元素本…