一、驱动模块的加载和卸载

Linux驱动有两种运行方式,第一种就是将驱动编译进Linux内核中,这样当Linux内核启动的时候就会自动运行驱动程序。第二种就是将驱动编译成模块(Linux下模块扩展名为.ko),在Linux内核启动以后使用“insmod”命令加载驱动模块。在调试驱动的时候一般都选择将其编译为模块,这样修改驱动以后只需要编译一下驱动代码即可,不需要编译整个Linux代码。而且在调试的时候只需要加载或者卸载驱动模块即可,不需要重启整个系统。总之,将驱动编译为模块最大的好处就是方便开发,当驱动开发完成,确定没有问题以后就可以将驱动编译进Linux内核中,当然也可以不编译进Linux内核中,具体看自己的需求。模块有加载和卸载两种操作,在编写驱动的时候需要注册这两种操作函数,模块的加载和卸载注册函数如下:

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 )
{/*出口函数具体内容*/
}/*将上面两个函数指定为驱动的入口和出口函数*/
module_init(xxx_init);
module_exit(xxx_exit);
  • 第2行,定义了个名为xxx_init的驱动入口函数,并且使用了“_init”来修饰。
  • 第9行,定义了个名为xxx_exit的驱动出口函数,并且使用了“_exit”来修饰。
  • 第15行,调用函数module_init来声明xxx_init为驱动入口函数,当加载驱动的时候xxx_init函数就会被调用。
  • 第16行,调用函数module_exit来声明xxx_exit为驱动出口函数,当卸载驱动的时候xxx_exit函数就会被调用。

二、insmod和rmmod命令

1、insmod命令
驱动编译完成以后扩展名为.ko,有两种命令可以加载驱动模块:insmod和modprobe,insmod是最简单的模块加载命令,此命令用于加载指定的.ko模块,比如加载drv.ko这个驱动模块,命令如下:

insmod drv.ko

insmod命令不能解决模块的依赖关系,比如drv.ko依赖first.ko这个模块,就必须先使用insmod命令加载first.ko这个模块,然后再加载drv.ko这个模块。但是modprobe就不会存在这个问题,modprobe会分析模块的依赖关系,然后会将所有的依赖模块都加载到内核中,因此modprobe命令相比insmod要智能一些。modprobe命令主要智能在提供了模块的依赖性分析、错误检查、错误报告等功能,推荐使用modprobe命令来加载驱动。modprobe命令默认会去/lib/modules/目录中查找模块
因此modprobe命令默认会到/lib/modules/4.1.15这个目录中查找相应的驱动模块,一般自己制作的根文件系统中是不会有这个目录的,所以需要自己手动创建。
2、rmmod命令
驱动模块的卸载使用命令“rmmod”即可,比如要卸载drv.ko,使用如下命令即可:

rmmod drv.ko

也可以使用“modprobe -r”命令卸载驱动,比如要卸载drv.ko,命令如下:

modprobr -r drv.ko

使用modprobe命令可以卸载掉驱动模块所依赖的其他模块,前提是这些依赖模块已经没有被其他模块所使用,否则就不能使用modprobe来卸载驱动模块。所以对于模块的卸载,还是推荐使用rmmod命令。

三、字符设备注册和注销

对于字符设备驱动而言,当驱动模块加载成功以后需要注册字符设备,同样,卸载驱动模块的时候也需要注销掉字符设备。字符设备的注册和注销函数原型如下所示:

static inline int register_chrdev(unsigned int major, const char *name,const struct file_operations*fops)
static inline void unregister_chrdev(unsigned int major, const char *name)

1、register_chrdev函数用于注册字符设备,此函数一共有三个参数,这三个参数的含义如下:

  • major:主设备号,Linux下每个设备都有一个设备号,设备号分为主设备号和次设备号两部分。
  • name:设备名字,指向一串字符串。
  • fops:结构体file_operations类型指针,指向设备的操作函数集合变量。

2、unregister_chrdev函数用户注销字符设备,此函数有两个参数,这两个参数含义如下:

  • major:要注销的设备对应的主设备号。
  • name:要注销的设备对应的设备名。

一般字符设备的注册在驱动模块的入口函数xxx_init中进行,字符设备的注销在驱动模块的出口函数xxx_exit中进行。在示例代码40.2.2.1中字符设备的注册和注销,内容如下所示:

static struct file_operations test_fops;
/*驱动入口函数*/
static int _init xxx_init(void)
{/*入口函数具体内容*/int retvalue = 0;/*注册字符设备驱动*/retvalue = register_chrdev(200,"chrtest", &test_fops);if(retvalue<0){/*字符设备注册失败,自行处理*/}return 0;
}
/*驱动出口函数*/
static void_exit xxx_exit(void)
{/*注销字符设备驱动*/unregister_chrdev(200,"chrtest");
}
/*将上面两个函数指定为驱动的入口和出口函数*/
module_init(xxx_init);
module_exit(xxx_exit);
  • 定义了一个file_operations结构体变量test_fops,test_fops就是设备的操作函数集合,只是此时我们还没有初始化test_fops中的open、release等这些成员变量,所以这个操作函数集合还是空的。
  • 调用函数register_chrdev注册字符设备,主设备号为200,设备名字为“chrtest”,设备操作函数集合就是第1行定义的test_fops。要注意的一点就是,选择没有被使用的主设备号,输入命令“cat/proc/devices”可以查看当前已经被使用掉的设备号。
  • 调用函数unregister_chrdev注销主设备号为200的这个设备。

以上即为Linux驱动模块加载和卸载的介绍!!!

Linux驱动模块加载和卸载以及设备注册与注销相关推荐

  1. Linux如何加载与卸载U盘

    Linux如何加载与卸载U盘   第一:以root用户登陆 先加载USB模块 modprobe usb-storage 用fdisk -l 看看U盘的设备 假如U盘是sda1   第二:确定在 目录 ...

  2. Linux驱动3:驱动模块加载与卸载

    目录 一.环境配置 1.开发板环境 2.uboot环境 ①设置bootargs ②设置bootcmd 二.加载驱动与卸载驱动 1.加载命令选择 2.创建目录环境以及驱动文件复制 3.加载驱动 提示①& ...

  3. linux驱动模块加载错误(insmod: can‘t insert ‘xxx.ko‘: invalid module format)的原因之一:内核或者配置不一致

    问题现象:insmod方式加载某个驱动ko模块,提示insmod: can't insert 'xxx.ko': invalid module format 问题原因之一(也可能是概率较大的一个原因) ...

  4. linux驱动加载流程分析

    linux驱动加载流程分析 内核是如何加载驱动的,有些是编译到内核里面,有些事编译成ko,让系统自动加载.总的说来,在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动 ...

  5. Linux可加载内核模块(LKM)(转载)

    转载: 漏天剑 文章导航: 为校长杯流尽最后一滴血, Lkm注射, 返回首页 Linux可加载内核模块(LKM) Linux可加载内核模块完全版 --黑客.病毒程序编写者和系统管理员的概念性指南 作者 ...

  6. 备份linux分区到usb,将Linux引导加载程序备份到USB的方法

    本文介绍如何将Linux引导加载程序备份到USB以应对紧急情况.大多数Linux操作系统使用的引导加载程序称为Grub,这是一个简单的工具,可以配置为在PC启动时从菜单启动Linux发行版以及其他操作 ...

  7. 正确使用AssetBundle加载和卸载

    在使用Unity开发项目时,AssetBundle是必须使用的,对资源进行打包加载,因为移动端游戏包体的大小对用户体验非常重要,对内存的使用更加重要,下面我们就介绍一下关于AssetBundlle的使 ...

  8. 基于PsSetLoadImageNotifyRoutine实现监控模块加载并卸载已加载模块(卸载DLL、EXE和sys等加载)

    背景 对于内核层实现监控模块的加载,包括加载DLL模块.内核模块等.你也许会想到 HOOK 各种内核函数来实现.确定,在内核层中的 HOOK 已经给人留下太多深刻的印象了,有 SSDT HOOK.In ...

  9. 生成PL设备树及动态加载PL程序和设备树

    实验说明 操作环境: Windows 7/10 64bit Xilinx Vivado 2017.4 Ubuntu 14.04 表 1 开发板型号 是否支持本实验 TLZ7x-EasyEVM 支持 T ...

最新文章

  1. 喧哗的背后:Serverless 的概念及挑战
  2. SAP系统与MES系统的数据协同技术方案
  3. wps重复上一步快捷键_WPS表格怎么快速输入重复内容?快速输入重复内容的详细步骤...
  4. Java enum枚举
  5. 计算机专业英语的理解,计算机专业英语之理解网络地址
  6. android自动生成cardview,学习使用Material Design控件(三)使用CardView实现卡片效果...
  7. 工作3年,可视化毫无进步?小白都能看懂的干货,我真不想告诉你
  8. 字体设计灵感合集|字体决定了设计
  9. jQuery做个TextBox自动完成条
  10. mysql 使用内置函数来进行模糊搜索(locate()等)
  11. GB35114—③、证书和密钥要求、基本功能要求及性能要求
  12. 伍德里奇计量经济学第六章计算机答案,伍德里奇计量经济学导论计算机习题第六章第13题c_6.13...
  13. 用Java弹个Freepiano钢琴《The truth that you leave》
  14. 直播APP源码在ftp服务器搭建教程
  15. J2EE框架(StrutsHibernateSpring)的理解
  16. 学英语尽量不要从背词汇表开始
  17. Unity 透视相机世界和屏幕坐标系转换
  18. 【2022 年第十二届 MathorCup杯数学建模】D 题 移动通信网络站址规划和区域聚类问题 赛后总结、论文及代码
  19. 逻辑电路是计算机学的吗,逻辑电路可以使计算机具备什么能力 计算机具有逻辑判断能力,主要取决于( )。...
  20. 用户画像是怎么生成出来的

热门文章

  1. vue3使用百度地图(详)
  2. arm spi 接口概述
  3. LUT实现简单滤镜效果
  4. 鲜奶品牌从0起步,只一个月就做到日销20万?28天赚600万!
  5. Python移动APP开发之Kivy(二)——第一个APP
  6. Three.js学习一——Three.js学习路线(供参考)
  7. 一文解析,Linux内核——Intel CPU体系结构
  8. Elasticsearch自带分词查询及使用分词器查询
  9. 【模糊理论】模糊矩阵的合成、并交补运算代码
  10. Python简易编写阴阳师刷魂土脚本(上)