IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> scull设计和如何动态分配主设备号(linux驱动开发程序) -> 正文阅读

[系统运维]scull设计和如何动态分配主设备号(linux驱动开发程序)

scull设计和如何动态分配主设备



一、scull设计解析

1.什么是scull

一个操作内存区域的字符设备驱动程序,这片内存区域相当于一个设备。

2.scull优点

1.在于它不和硬件相关
2.只是操作从内核中分配的一些内存。任何人都可以编译和运行scull
3.还可以将scull移植到Linux支持的计算机平台上,
4.展示内核和字符驱动之间的接口并且让用户运行某些测试。scull设备做不了任何事

3.scull设计

编写驱动程序的第一步就是定义驱动程序未用户程序提供的功能(机制)
scull的源代码实现了下列的设备,模块实现每一种设备称作一种 “类型”:

  1. scull0~scull3
    这四个设备分别由一个全局且持久的内存区域组成,全局指的是:如果设备被多次打开,则打开她的所有文件描述符可共享该设备所包含的数据。“持久”是指 设备关闭在打开数据不丢失。
  2. scullpipe0~scullpipe3
    一个进程读取由另一个进程写入的数据。如果多进程读取同一个设备。他们会产生竞争关系。scullpipe的内部实现将说明不借助与中断的情况下如何实现阻塞时和非阻塞式的读/写
  3. scullsingle
    一次只允许一个进程使用该驱动程序
  4. scullpriv
    而scullpriv对每个虚拟控制台式私有的。这是因为每个控制台/终端上的进程将获取不同的内存区域
  5. sculluid、scullwuid
    sculluid和scullwuid可被多次打开,但每次只能由一个用户打开;如果另一个用户锁定该设备。sculluid将返回 “Device Busy”的错误,而scullwuid则实现了阻塞时open.这些scull设备的变种混淆了机制和策略,

如何动态分配主设备号

一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各设备
注:区分字符驱动设备和块驱动设备
字符设备驱动程序的设备文件可通过ls -l 命令输出的第一行的“c”来识别。块设备也出现在/dev ,标识用"b"标识

案例解析

如果执行ls -l命令,则可在设备文件项的最后修改日期前两个数(用逗号分隔),这个位置通常现实的时文件的长度; 而对设备文件,这两个数就是相应设备的主设备号和次设备号。主设备号是1,4,7,10和次设备号是1、3、5、64、65和129
在这里插入图片描述
通常而言、主设备号标识设备对应的驱动程序。例如,/dev/null和/dev/zero由驱动程序1管理。而虚拟控制台和串口终端由驱动程序4管理,类似地,vcsl和vcsal设备都有驱动程序7管理。,一个主设备号对应一个驱动程序的原则

次设备号

在内核中 dev_t 用来保持设备编号, 包括主从设备号,dev_t是一个32位的数,其中的12位用来标识主设备数而其余20位用来标识次设备号。应该始终使用<linux/kdev_t.h>中定义的宏。比如获得dev_t的主从设备号应使用:

MAJOR(dev_t dev); //主
MINOR(dev_t dev); //从

如果需要把主从设备号换称dev_t类型则使用

MKDEV(int major, int minor);

分配和释放设备编号

在建立一个字符设备之前,我们的驱动程序首先要做的事情就是获得一个或多个设备编号。完成该工作的必要函数是register_chrdev_region,该函数在<linux/fs.h>中声明

int register_chrdev_region(dev_t first,unsigned int count, char *name);

其中,first是要分配的设备编号范围的起始值。first的次设备号经常被设置位0,
count是锁清秋的联系设备编号的个数,如果count非常大,则所请求的返回可能和
下一个主设备号重叠。 name是该编号范围关联的设备名称,它将出现在/proc/devices和sysfs中
int alloc_chrdev_region(dev_t *dev,unsigned int firstminor, unsigned int count, char * name);
dev是仅用于输出的参数,在调用完成后将保持已分配防范围的第一个编号。
firstminor应该是要使用的被生气的第一个次设备号,
它通常是0.count和name参数与register_chrdev_region函数一样的
void unregister_chrdev_region(dev_t first,unsigned int count);
我们在模块的清除函数中调用unregister_chrdev_region函数

动态分配主设备号

由于分配的主设备号不能保证始终一致,所以驱动预先创建设备节点
下面这个名scull_load的脚本是scull发布的一部分。使用以模块形式发布的驱动程序的用户可以在系统的rc.local文件中调用这个脚本。或是在需要模块是手工调用。

#!/bin/sh
module="scull"
device="scull"
modu="664"
# 使用传入到该脚本得所有参数调用insmod,同时使用路径名来指定模块地址,
# 这是应为新得modutils默认不会再当前目录中查找模块
/sbin/insmod ./$module.ko $* || exit 1
# 删除原有节点
rm -f /dev/${device}[0-3]
major=${awk "\$2= =\"$module\" {print \$1}" /proc/devices}
mknod /dev/${device}0 c $major 0
mknod /dev/${device}1 c $major 1
mknod /dev/${device}2 c $major 2
mknod /dev/${device}3 c $major 3
# 给定适当得组属性及许可,并修改属组
# 并非所有得发行版独具偶staff组,有些有wheel组
qroup="staff"
grep -q '^staff:' /etc/group || group="wheel"
chgrp $group /dev/${device}[0-3]
chmod $mode /dev/${device}[0-3]

这个脚本同样可以适用其他驱动程序,只要重新定义变量并调整mknod那几行语句就可以了,该脚本创建了四个设备,应为scull得源码默认创建四个设备。

为什么要改变设备得组和访问模式呢,原因在于这个脚本必须有超级用户允许,所以新创建得设备文件自然属于root,默认得权限只允许root对其有写访问前线。我们得脚本默认地把访问权赋予给一个用户组。

处理适用这一对装载和卸载模块脚本外,我们还可以把编写一个init脚本,并将其保持再发行版适用得init脚本目录中,最为scull源码一部分,我们提供了相当详尽和可配置得init脚本范例。

分配主设备号得最佳方式:默认采用动态分配,同时保留在加载甚至时编译时指定主设备号得余地。scull的实现采用这种方式;它适用了一个全局变量scull_major,迎来保留选择的设备号,该变量的初始化只时SCULL_MAJOR,这个宏定义在scull.h中。SCULL__MAJOR默认取0,即选择动态分配。用户可以适用这个默认值或选择某个特定的主设备号, 也可用insmod命令行指定scull_major的值。

scull.c中用来获取主设备号的代码


if(scull_major){

?	dev = MKDEV(scull_major,scull_minor);

result = register_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");	

}else{

?	result = alloc_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");

?	scull_major = MAJOR(dev);

}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 12:01:58  更:2022-05-05 12:02:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 17:45:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码