Linux内核学习(十三)—— 设备与模块(基于Linux 2.6内核)

这篇具有很好参考价值的文章主要介绍了Linux内核学习(十三)—— 设备与模块(基于Linux 2.6内核)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、设备类型

二、模块

构建模块

安装模块

载入模块


一、设备类型

在 Linux 以及 Unix 系统中,设备被分为以下三种类型:

  • 块设备(blkdev):以块为寻址单位,块的大小随设备的不同而变化;块设备通常支持重定位(seeking)操作,也就是对数据的随机访问。如硬盘、蓝光光碟和 Flash 这样的存储设备都是块设备。块设备是通过称为 ”块设备节点“ 的特殊文件来访问的,并且通常被挂载为文件系统。
  • 字符设备(cdev):不可寻址,只提供数据的流式访问,即一个一个字符或字节地访问。如键盘、鼠标和打印机等都是字符设备。字符设备是通过称为 ”字符设备节点“ 的特殊文件来访问的,与块设备不同,应用程序通过直接访问设备节点与字符设备交互。
  • 网络设备:有时也被称为以太网设备(ethernet devices),提供了对网络的访问,这是通过一个物理适配器和一种特定的协议进行的。它不是通过设备节点来访问,而是通过套接字 API 这样的特殊接口来访问。

并不是所有设备驱动都表示物理设备。有些设备驱动是虚拟的,仅仅提供访问内核功能而已。这种设备被称为 ”伪设备“ (pseudo device),如内核随机数发生器(/dev/random)、空设备(/dev/null)等。

二、模块

尽管 Linux 是 ”单块内核“(monolithic)的操作系统,但 Linux 内核时模块化组成的,它允许内核在运行时动态地向其中安装或卸载一个模块。

下面编写一个 Hello,World!的模块程序:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

/* 初始化函数,当模块装载时被调用 */
static int hello_init(void)
{
    printk(KERN_ALERT "Module installed!\n");
    return 0;
}

/* 退出函数,当模块卸载时调用 */
static void hello_exit(void)
{
    printk(KERN_ALERT "Module removed!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

这是一个非常非常简单的内核模块程序,hello_init() 是模块的入口点,它通过 module_init() 例程注册到系统中,在内核装载时调用。这个 init 函数仅仅打印了一行简单的信息,但在实际的模块中,该函数还会注册资源、初始化硬件、分配数据结构等。而 hello_exit() 函数负责对 init 函数以及在模块生命周期过程中所作的一切事情进行撤销与清理工作。

构建模块

下面开始构建模块。有两种方法来构建模块:

第一种是放在内核源代码树中。这样构建的模块会正式成为 Linux 内核中的一部分,设备驱动程序存放在内核源码树根目录下的 /drivers 的子目录下,根据不同的设备类型,字符设备存放于 /drivers/char,块设备存放于 /drivers/block 等。

假如我们编写的模块类型是字符设备,那就把模块文件移动到 /drivers/char 目录下,然后往 /drivers/char 目录下的 Makefile 文件中添加一行:

obj-m += hello.o

然后编译内核,重新装载内核即可。

第二种是放在内核代码外。将 hello.c 放到 /drivers/char 目录下后,在内核代码外创建一个 Makefile 文件,内容如下:

# -C 后为你的内核源码树所在位置
#  make -C /root/linux_kernel_learning/linux-2.6 modules

obj-m += hello.o

然后执行如下指令来构建模块: 

make -C /root/linux_kernel_learning/linux-2.6 SUBDIRS=$PWD modules

安装模块

编译后模块将被装入到目录 /lib/modules/<version>/kernel/drivers/char 下:

下面的构建命令用来安装编译的模块(在内核源码树目录下执行):

make modules_install

载入模块

载入一个模块:

insmod hello.ko

卸载一个模块:文章来源地址https://www.toymoban.com/news/detail-681870.html

rmmod hello.ko

到了这里,关于Linux内核学习(十三)—— 设备与模块(基于Linux 2.6内核)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Linux--2.6内核调度和环境变量

    📘北尘_ :个人主页 🌎个人专栏 :《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 上图是Linux2.6内核中进程队列的数据结构,之间关系也已经给大家画出来,方便大家理解 如果有多个CPU就要考虑进程个数的负载均衡问题 普通

    2024年02月05日
    浏览(61)
  • LSM零知识学习二、Linux内核中的安全模块

    接前一篇文章:LSM零知识学习一、概念与框架机制 本文内容参考: 《Linux内核安全模块深入剖析》 李志 机械工业出版社 Linux LSM(Linux Security Modules) Hook Technology_weixin_30929011的博客-CSDN博客 Linux Security Module Usage — The Linux Kernel documentation 前文已提到,LSM的全称为Linux Security Mod

    2024年02月10日
    浏览(40)
  • 【PostgreSQL内核学习(十三)—— (PortalRun)】

    声明 :本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。 本文主要参考了《PostgresSQL数据库内核分析》一书,OpenGauss1.1.0 的开源代码和《OpenGauss数据库源码解析》一书以及Op

    2024年02月07日
    浏览(43)
  • 【PostgreSQL内核学习(二十三)—— 执行器(ExecEndPlan)】

    声明 :本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。 本文主要参考了 postgresql-10.1 的开源代码和《OpenGauss数据库源码解析》和《PostgresSQL数据库内核分析》一书   在这三

    2024年01月17日
    浏览(52)
  • 《由浅入深学习SAP财务》:第2章 总账模块 - 2.6 定期处理 - 2.6.4 月末操作:货币折算

             如果一个公司代码启用了多个本位币,如下表所示,则在平时记账时,系统会在凭证行项目中同时体现出多个本位币的金额 。 图2.6.4-1          两个本位币的金额都会实时更新到科目余额中 。因此,在月末可以直接提取两种本位币下的报表结果。       

    2024年04月15日
    浏览(54)
  • 【linux驱动开发】在linux内核中注册一个杂项设备与字符设备以及内核传参的详细教程

    开发环境: windows + ubuntu18.04 + 迅为rk3568开发板 相较于字符设备,杂项设备有以下两个优点: 节省主设备号:杂项设备的主设备号固定为 10,在系统中注册多个 misc 设备驱动时,只需使用子设备号进行区分即可。 使用简单:相比如普通的字符设备驱动, misc驱动只需要将基本信

    2024年01月21日
    浏览(51)
  • Linux 内核设备树时钟绑定

    这种绑定依然处于开发中,并且基于 benh[1] 的一些实验性工作。 时钟信号源可以由设备树中的任何节点表示。这些节点被指定为时钟提供者。时钟消费者节点使用 phandle 和时钟指示符对将时钟提供者输出连接到时钟输入。与 gpio 指示符类似,时钟指示符是 0 个、1 个或多个标

    2024年02月17日
    浏览(48)
  • Linux 内核定时器(高级字符设备五)

      在 Linux 内核中很多函数是基于定时器进行驱动的,但是内核定时器的精度并不高,所以不能作为高精度定时器使用。并且内核定时器的运行没有周期性,到达计时终点后会自动关闭。如果要实现周期性定时,就要在定时处理函数中重新开启定时器。   Linux 内核中使用

    2024年02月08日
    浏览(42)
  • linux用户态与内核态通过字符设备交互

    Linux设备分为三类,字符设备、块设备、网络接口设备。字符设备只能一个字节一个字节读取,常见外设基本都是字符设备。块设备一般用于存储设备,一块一块的读取。网络设备,Linux将对网络通信抽象成一个设备,通过套接字对其进行操作。 对于字符设备的用户态与内核

    2024年02月03日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包