当前位置: 首页 > news >正文

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 modulesobj-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

卸载一个模块:

rmmod hello.ko

http://www.lryc.cn/news/145613.html

相关文章:

  • 计算机视觉工程师学习路线
  • c#多线程—基础概念到“双色球”项目实现(附知识点目录、代码、视频)
  • 【OpenCV入门】第一部分——图像处理基础
  • vue3+ts+tinynce富文本编辑器+htmlDocx+file-saver 配合实现word下载
  • 论文阅读 The Power of Tiling for Small Object Detection
  • 【FreeRTOS】【应用篇】消息队列【下篇】
  • 芯片技术的崭新时代:探索未来的可能性
  • 博流RISC-V芯片Eclipse环境搭建
  • 智慧水产养殖方案,守护养殖水产品安全!
  • 前端vue引入高德地图入门教程
  • 【LeetCode题目详解】第八章 贪心算法 part05 435. 无重叠区间 763.划分字母区间 56. 合并区间 (day36补)
  • 数据的语言:学习数据可视化的实际应用
  • 【Flutter】Flutter简介
  • 做区块链卡牌游戏有什么好处?
  • C语言每日一练------Day(5)
  • (Windows )本地连接远程服务器(Linux),免密码登录设置
  • Python 面试:异常处理机制
  • Matlab图像处理-水平镜像
  • Ansys Zemax | 手机镜头设计 - 第 2 部分:使用 OpticsBuilder 实现光机械封装
  • 【GPT,Flask】用Python Flask结合OpenAI的GPT API构建一个可自主搭建的内容生成应用网站
  • vue + electron
  • spring中LocalDateTime 转成字符串的时候注意事项
  • vue数组对象中按某一字段排序
  • yolov5和yolov7部署的研究
  • 【JavaEE进阶】拦截器与统一功能处理
  • 2023年智慧政务一网通办云平台顶层设计与建设方案PPT
  • 安防监控/视频汇聚平台EasyCVR调用rtsp地址返回的IP不正确是什么原因?
  • 媒体服务器与视频服务器有什么区别
  • 菜鸟教程《Python 3 教程》笔记(11):循环语句
  • 【DevOps视频笔记】8. Jenkins 配置