1、Linux驱动开发:模块_加载卸载

这篇具有很好参考价值的文章主要介绍了1、Linux驱动开发:模块_加载卸载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

🍅点击这里查看所有博文

  随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有一点用处的技巧,用的不多的技巧可能一个星期就忘了。

  想了很久想通过一些手段把这些事情记录下来。也尝试过在书上记笔记,这也只是一时的,书不在手边的时候那些笔记就和没记一样,不是很方便。

  很多时候我们遇到了问题,一般情况下都是选择在搜索引擎检索相关内容,这样来的也更快一点,除非真的找不到才会去选择翻书。后来就想到了写博客,博客作为自己的一个笔记平台倒是挺合适的。随时可以查阅,不用随身携带。

  同时由于写博客是对外的,既然是对外的就不能随便写,任何人都可以看到。经验对于我来说那就只是经验而已,公布出来说不一定我的一些经验可以帮助到其他的人。遇到和我相同问题时可以少走一些弯路。

  既然决定了要写博客,那就只能认真去写。不管写的好不好,尽力就行。千里之行始于足下,一步一个脚印,慢慢来 ,写的多了慢慢也会变好的。权当是记录自己的成长的一个过程,等到以后再往回看时,就会发现自己以前原来这么菜😂。

  本系列博客所述资料均来自互联网资料,并不是本人原创(只有博客是自己写的)。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。

前言

  一个基础模块的源代码,应有c文件,h文件(可选)和makefile文件构成

C文件

  c文件中除了必要的函数申明以及头文件导入外,还要分别为模块声明载入函数和销毁函数。载入函数使用module_init声明,当模块被加载进入内核的时候该函数会被调用。销毁函数使用module_exit声明,当从内核中移除模块时该函数会被调用。

  宏MODULE_LICENSE宏用于声明此模块的许可证,宏MODULE_AUTHOR的用于声明内核模块的作者。

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("PD");
static int hello_init(void)
{
	printk(KERN_SOH"hello_init \n");
	return 0;
}
static void hello_exit(void)
{
	printk("hello_exit \n");
	return;
}
module_init(hello_init); //insmod
module_exit(hello_exit);//rmmod

  从2.4.10版本内核开始,模块必须通过MODULE_LICENSE宏声明此模块的许可证,否则在加载此模块时,会收到内核被污染 “kernel tainted” 的警告。从linux/module.h文件中可以看到,被内核接受的有意义的许可证有 “GPL”,“GPL v2”,“GPL and additional rights”,“Dual BSD/GPL”,“Dual MPL/GPL”,“Proprietary”。

/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *	"GPL"				[GNU Public License v2 or later]
 *	"GPL v2"			[GNU Public License v2]
 *	"GPL and additional rights"	[GNU Public License v2 rights and more]
 *	"Dual BSD/GPL"			[GNU Public License v2
 *					 or BSD license choice]
 *	"Dual MIT/GPL"			[GNU Public License v2
 *					 or MIT license choice]
 *	"Dual MPL/GPL"			[GNU Public License v2
 *					 or Mozilla license choice]
 *
 * The following other idents are available
 *
 *	"Proprietary"			[Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.	So modinfo can show license info for users wanting to vet their setup
 *	is free
 * 2.	So the community can ignore bug reports including proprietary modules
 * 3.	So vendors can do likewise based on their own policies
 */
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)

makefile文件

  此makefile可作为一个通用示例。

ifneq ($(KERNELRELEASE),)
$(info "makebuild2")
obj-m:=hello.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD  :=$(shell pwd)
all:
	$(info "makebuild1")
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order
	rm -rf .*.cmd .*.mk .*/
endif

  在编译模块运行make命令时。首先由于KERNELRELEASE变量不存在,会直接进入else分支,执行内核modules的make流程。

root@ubuntu:# make
"makebuild1"
make -C /lib/modules/4.15.0-142-generic/build M=/home/peng/Desktop/driver/example/1_module modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic'

  第二步再次从头开始重新执行该makefile,由于第一步中已经指定了内核模块编译,此时KERNELRELEASE不为空,会进入到ifneq分支,完成*.o的生成。

"makebuild2"
  CC [M]  /home/peng/Desktop/driver/example/1_module/hello.o
  Building modules, stage 2.

  完成hello.o的编译后,最后一步会执行一个转化和链接的操作。该makefile被再次调用。将*.o转化为*.mod.o,最后完成内核模块的链接生成*.ko

"makebuild2"
  MODPOST 1 modules
  CC      /home/peng/Desktop/driver/example/1_module/hello.mod.o
  LD [M]  /home/peng/Desktop/driver/example/1_module/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cYaB26gb-1690343130822)(https://raw.githubusercontent.com/chenxiahuaxu/stackedit-app-data-img/master/2023/07/22/1.%E6%A8%A1%E5%9D%97_%E5%8A%A0%E8%BD%BD%E5%8D%B8%E8%BD%BD/13qSi7ijnkTc7f2S.png)]

加载卸载

  加载模块前建议先清除dmesg的日志信息。否则影响调试

root@ubuntu:$ dmesg -c

  使用insmod加载模块,加载完成可通过dmesg查看载入函数的日志打印,也可以通过lsmod查看模块是否被正常加载。

root@ubuntu:# insmod ./hello.ko
root@ubuntu:# dmesg
[ 6891.682070] hello_init 
root@ubuntu:# lsmod | grep hello
hello                  16384  0

  使用rmmod卸载模块,卸载完成可通过dmesg查看卸载函数的日志打印,也可以通过lsmod查看模块是否被正常卸载。

root@ubuntu:# rmmod ./hello.ko
root@ubuntu:# dmesg
[ 6891.682070] hello_init 
[ 7087.613847] hello_exit 
root@ubuntu:# lsmod | grep hello

常用操作

  • lsmod:显示模块
  • insmod/rmmod:安装/卸载模块
  • dmesg -c:清除log信息
  • dmesg:打印log信息

  那么本篇博客就到此结束了,这里只是记录了一些我个人的学习笔记,其中存在大量我自己的理解。文中所述不一定是完全正确的,可能有的地方我自己也理解错了。如果有些错的地方,欢迎大家批评指正。如有问题直接在对应的博客评论区指出即可,不需要私聊我。我们交流的内容留下来也有助于其他人查看,说不一定也有其他人遇到了同样的问题呢😂。文章来源地址https://www.toymoban.com/news/detail-604143.html

到了这里,关于1、Linux驱动开发:模块_加载卸载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Linux内核显示、加载、卸载等超实用命令

    内核模块是 Linux 系统中一种特殊的可执行文件,它可以在运行时动态地加载到内核中或卸载出内核,从而实现内核的扩展和优化。内核模块操作相关的命令主要有以下几种: 列出当前已加载的内核模块及其依赖关系和使用情况。 将指定的内核模块加载到内核中,需要提供完

    2024年02月08日
    浏览(47)
  • 如何将模块加载到linux内核

    如何将模块加载到linux内核

    假设存在一个文件叫mymq.c,下该文件相同目录下的makefile如下语句: obj-y += mymq.o 然后编译:编译完成了以后,mymq.c文件中,有个函数叫mymq_open,搜索这个函数在不在System.map文件中,如果在,就说明这个模块被内置到内核中了。 执行grep -rn mymq_open System.map,在文件System.map中搜索

    2023年04月24日
    浏览(46)
  • Linux 内核模块加载过程之重定位

    1.1.1 struct load_info info 加载模块只需要读入模块的二进制代码即可,然后执行init_module系统调用。 我们先介绍下struct load_info info结构体。 struct load_info 是一个用于加载模块时存储相关信息的数据结构。 该结构体包含以下成员: name:模块的名称,以字符串形式存储。 mod:指向

    2024年02月10日
    浏览(320)
  • 【嵌入式Linux内核驱动】内核模块三要素与验证测试

    内核模块 Linux内核模块是一种可以动态加载和卸载的软件组件,用于扩展Linux操作系统的功能。Linux内核本身只包含了必要的核心功能,而内核模块则允许开发者在运行时向内核添加新的功能、驱动程序或文件系统支持,而无需重新编译整个内核或重新启动系统。 内核模块是

    2024年02月06日
    浏览(66)
  • 【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)

    编译驱动一般采用的是将驱动编译成模块(.ko 文件),然后加载到内核,这其中就用到了 make modules 命令。 目录 一、单模块编译 1、一个 c 文件编译成一个 ko 文件 2、多个文件编译成一个 ko 文件 二、多模块编译(多文件多模块) 下面是最简易的单文件单模块编译,假设我们

    2024年02月10日
    浏览(47)
  • Linux中驱动模块加载方法分析

    如何管理驱动模块 由于Linux驱动模块众多,系统对模块加载顺序有要求,一些基础模块在系统启动时需要很早就被加载;开发者加入自己的模块时,需要维护一个模块初始化列表,上面两方面的做起来很困难,为了科学地管理这些模块,首先要解决两个问题: 如何方便开发者

    2024年02月12日
    浏览(9)
  • linux内核网络驱动框架(linux驱动开发篇)

    linux内核网络驱动框架(linux驱动开发篇)

    网络驱动的核心: 1、就是初始化 net_device 结构体中的各个成员变量, 2、然后将初始化完成以后的 net_device 注册到 Linux 内核中 1、网络设备(用net_device结构体) 2、网络设备的操作集( net_device_ops结构体 ) 3、sk_buff结构体 网络是分层的,对于应用层而言不用关系具体的底层是

    2023年04月08日
    浏览(14)
  • 【linux驱动】用户空间程序与内核模块交互-- IOCTL和Netlink

    【linux驱动】用户空间程序与内核模块交互-- IOCTL和Netlink

    创建自定义的IOCTL(输入/输出控制)或Netlink命令以便用户空间程序与内核模块交互涉及几个步骤。这里将分别介绍这两种方法。 1. 定义IOCTL命令 在内核模块中,需要使用宏定义你的IOCTL命令。通常情况下,IOCTL命令包括了一个命令编号、请求类型的方向(读/写/两者)以及数

    2024年01月20日
    浏览(14)
  • linux驱动开发:Linux 内核的一些函数

    1 、 MKDEV ( ma, mi ) 构造设备号,将主设备号和次设备号转换为设备号类型(dev_t)。 MKDEV 宏将主设备号( ma )左移 20 位,然后与次设备号( mi )相与,得到设备号。 dev_t 结构 主设备号 12 位

    2024年02月17日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包