ioctl函数详解(参数详解,驱动unlocked_ioctl使用、命令码如何封装)

article/2025/11/8 7:28:15

@ioctl函数详解

一、ioctl函数的原型

在用户空间的函数原型

#include <sys/ioctl.h>
int ioctl(int d, int request, ...);    //io的控制,设备的控制/***第一个参数d是打开的文件描述符***//***The  second  argument is a device-dependent request code,An ioctl() request has encoded in it whether the argument is an in parameter or out paramter, and the size of the argument argp in bytes.  Macros and defines used in specifying an ioctl() request are located in the file <sys/ioctl.h>就是说第二个参数已经被编码,这个int(32位)的数编码中有一部分说明了输入输出,还有部分说明了第三个参数的大小字节,这个封装成了一个宏在<sys/ioctl.h>定义了。***/
/***The third argument is an untyped pointer to memory,第三个参数可变参数,可写可不写,要写就是一块地址***/

在内核空间的函数原型,定义在了struct file_operations这个操作方法结构中。

struct file_operations {ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);//这个才是ioctl的接口long (*compat_ioctl) (struct file *, unsigned int, unsigned long);  //为了兼容性保留的老的接口int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*release) (struct inode *, struct file *);                                       int (*fsync) (struct file *, loff_t, loff_t, int datasync);……};

二、ioctl函数的第二个参数详解,如何编码

1、asm-generic/ioctl.h中命令码的分析

我们可以根据man手册确认到在内核中有一个定义的文件,可以在linux内核找到这个文件就是include/asm-generic/ioctl.h:
打开这个文件以后我们可以根据注释找到这么一段话:

* ioctl command encoding: 32 bits total, command in lower 16 bits,
* size of the parameter structure in the lower 14 bits of the
* upper 16 bits./*意思就是这个32位命令码,低16位(0bit——15bit)包含了命令,从16位开始(16bit——29bit)的14位描述了参数的大小*/
* Encoding the size of the parameter structure in the ioctl request
* is useful for catching programs compiled with old versions
* and to avoid overwriting user space outside the user buffer area.
* The highest 2 bits are reserved for indicating the ``access mode''.  /*意思是最高的两位为传输位表明了(读/写)*/

2、内核提供帮助手册Documentation底下有各种使用说明,有一个编码的说明文档Documentation/ioctl/ioctl-decoding.txt

bits    meaning31-30  00 - no parameters: uses _IO macro10 - read: _IOR01 - write: _IOW11 - read/write: _IOWR//方向,输出模式,读写位29-16  size of arguments//传递数据的大小15-8   ascii character supposedlyunique to each driver//类型,驱动的标识位,一个特殊字符(ASCII)代表不同的一个驱动7-0    function #//功能
/*************总结:本质上是为了组成一个不同的32位的数************/
So for example 0x82187201 is a read with arg length of 0x218,
character 'r' function 1. Grepping the source reveals this is: 
//举例说明,如果读一个这个数据长度为多少地址多少通过_IOR这个宏合成如下的例子
#define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct dirent [2])

3、命令码的编码详解

通过例子可以确认到_IOR这个宏是其中一个封装命令码的宏,找到其原型在文件asm-generic/ioctl.h中:

#define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size)  _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))

可以看到这些封装命令码的宏又都调用了一个宏_IOC,那继续看这个宏是怎么定义的。

#define _IOC(dir,type,nr,size) \(((dir)  << _IOC_DIRSHIFT) | \     //dir(读写)方向左移30位((type) << _IOC_TYPESHIFT) | \    //type类型左移8位((nr)   << _IOC_NRSHIFT) | \      //nr功能左移0位((size) << _IOC_SIZESHIFT))      // size传递数据大小左移16位/**通过分析是dir、type、nr、size几个数都左移了一个不知道的宏的位数,通过查找发现这些宏如下,所以得到上边每行注释左移位数**/
#define _IOC_NRBITS 8                                                                                   
#define _IOC_TYPEBITS   8
# define _IOC_SIZEBITS  14
#define _IOC_NRSHIFT    0
#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)  // 0+8 = 8                                                     
#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS) //8+8 = 16
#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS) //16+14 = 30

总结:我们通过分析_IOC这个宏可以发现他做了这么一件事,将一个32位的数拆成了四个部分,分别是dir、type、nr、size,分别如下解释和图示:
bit31~bit30:“区别读写” 区,作用是区分是读取命令还是写入命令;
bit29~bit16:“数据大小” 区,表示 ioctl() 中的 arg 变量传送的内存大小。
bit15~bit8 : “ 魔数” (也称为"幻数")区,这个值用以与其它设备驱动程序的 ioctl 命令进行区别。
bit7~bit0 :“区别序号”区,是区分命令的命令顺序序号。
在这里插入图片描述

4、eg:来封装一个命令码

1、直接封装一个IO命令码,无需读写数据(不需要用户和内核数据传输):

    #define  LED_ON  _IO(‘a’,0)#define  LED_OFF _IO(‘a’,1)

2、直接封装一个读结构体的命令码(用户读取内核的数据):

   struct  aa{};#define READ_STRUCT_aa _IOR(‘z’,0,struct aa)/***这里第三个参数大小,size不是说直接sizeof(struct aa),有一个宏_IOC_TYPECHECK,查看原型得到用了宏定义_IOC_TYPECHECK(t), ***/#define _IOC_TYPECHECK(t) \                                                                             ((sizeof(t) == sizeof(t[1]) && \sizeof(t) < (1 << _IOC_SIZEBITS)) ? \sizeof(t) : __invalid_size_argument_for_IOC)

个人总结:命令码封装之后每一个32的数值代表了一种确定的功能,在一个系统里每一个功能是互不干扰的,比如相机设置的参数(拍照的大小宽高、亮度、分辨率),将这个参数分装成一个命令码给内核,下次拍照就用这个命令码设置的参数。再有所有的开发更过面向用户的,以用户为中心,所以,一个优秀的驱动,不是说全部都将寄存器的设置和用户隔离开,比如你要循环读一个外设的数据,这个读取的周期可能是在4个、5个、6个时钟周期之后,这些都可以通过用户实际需求来更改,而不是在驱动中已经写死一个周期。一个优秀的驱动工程师应该将硬件的功能最大化保留的提供给用户选择,而不是直接屏蔽掉硬件的一部分功能。相当于开了一个和用户360度无死角接触的API。


http://chatgpt.dhexx.cn/article/e4C1J0Ai.shtml

相关文章

IOCTL函数用法

.ioctl 的实现 一、ioctl的简介&#xff1a; 虽然在文件操作结构体"struct file_operations"中有很多对应的设备操作函数&#xff0c;但是有些命令是实在找不到对应的操作函数。如CD-ROM的驱动&#xff0c;想要一个弹出光驱的操作&#xff0c;这种操作并不是所有的…

IOCTL函数用法详解

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数 。所谓对I/O通道进行管理&#xff0c;就是对设备的一些特性进行控制&#xff0c;例如串口的传输波特率、马达的转速等等。它的调用个数如下&#xff1a; int ioctl(int fd, ind cmd, …)&#xff1b; 其中fd是用户程序打…

linux ioctl()详解

一、ioctl的简介&#xff1a; 虽然在文件操作结构体"struct file_operations"中有很多对应的设备操作函数&#xff0c;但是有些命令是实在找不到对应的操作函数。如CD-ROM的驱动&#xff0c;想要一个弹出光驱的操作&#xff0c;这种操作并不是所有的字符设备都需要的…

ioctl 详细介绍

ioctl 详细介绍 (一)ioctl 的作用: 通过设备驱动程序执行各种类型的硬件控制。除了简单数据传输外,大部分设备可以执行其他的一些操作,比如,用户空间经常请求设备锁门、弹出介质、报告错误信息、改变波特率或者执行自破坏等等。 Ioctl的操作通过流程图简言之: 从图…

ioctl函数

一、什么是ioctl   ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理&#xff0c;就是对设备的一些特性进行控制&#xff0c;例如串口的传输波特率、马达的转速等等。   ioctl函数是文件结构中的一个属性分量&#xff0c;就是说如果你的驱动程序…

linux驱动开发(四):ioctl()函数

前文中我们介绍了应用程序通过使用虚拟文件系统VFS提供的接口&#xff0c;来控制字符驱动程序&#xff0c;完成字符驱动设备的open、close、read、write操作。但是如果我们想进行除此以外的其他操作&#xff0c;拓展一些file_operations给出的接口中没有的自定义功能&#xff0…

linux 内核 - ioctl 函数详解

1. 概念 ioctl 是设备驱动程序中设备控制接口函数&#xff0c;一个字符设备驱动通常会实现设备打开、关闭、读、写等功能&#xff0c;在一些需要细分的情境下&#xff0c;如果需要扩展新的功能&#xff0c;通常以增设 ioctl() 命令的方式实现。 在文件 I/O 中&#xff0c;ioc…

第10章综合案例1广电大数据分析

第10章综合案例1广电大数据分析 实验目的及要求 &#xff08;1&#xff09;现有用户观看历史和用户信息两个广电大数据文件&#xff0c;将对用户数据进行大数据分析。 实验系统环境及版本 Linux Ubuntu 20.04 JDK1.8 Hadoop3.1.0 MySQL8.0.28 Hive3.1.2 实验任务 基本…

图解大数据 | 综合案例-使用Spark分析挖掘零售交易数据

作者&#xff1a;韩信子ShowMeAI 教程地址&#xff1a;http://www.showmeai.tech/tutorials/84 本文地址&#xff1a;http://www.showmeai.tech/article-detail/177 声明&#xff1a;版权所有&#xff0c;转载请联系平台与作者并注明出处 收藏ShowMeAI查看更多精彩内容 引言 …

大数据之实践案例分析

前言 公司由页游转手游&#xff0c;公司的数据分析需要针对手游进行设计&#xff0c;所以原来的那一套针对页游的数据分析框架就显得不是很合适了&#xff0c;一方面在于手游和页游一些业务逻辑上的不同&#xff0c;另外一方面是数据量级上的改变&#xff0c;以及渠道、区服之间…

大数据分析案例-基于朴素贝叶斯算法构建电信客户流失分析预警模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Python+大数据-数据分析与处理(六)-综合案例

Python大数据-数据分析与处理(六)-综合案例 案例一&#xff1a;Appstore数据分析 学习目标 掌握描述性数据分析流程 能够使用pandas、seaborn进行数据分析和可视化 1.案例介绍 案例背景&#xff1a; 对 App 下载和评分数据分析&#xff0c;帮助 App 开发者获取和留存用户…

大数据挖掘分析的经典案例,主要有哪几种?

大数据挖掘分析经典案例有以下几种&#xff1a; 1.预测产品未来一段时间用户是否会流失&#xff0c;流失情况怎么样&#xff1b; 2.公司做了某个促销活动&#xff0c;预估活动效果怎么样&#xff0c;用户接受度如何&#xff1b; 3.评估用户信用度好坏&#xff1b; 4.对现有…

第11章综合案例2影评大数据分析

第11章综合案例2影评大数据分析 实验目的及要求 &#xff08;1&#xff09;现有电影、影评和用户信息3个数据文件&#xff0c;将对其进行大数据分析。 实验系统环境及版本 Linux Ubuntu 20.04 JDK1.8 Hadoop3.1.0 MySQL8.0.28 Hive3.1.2 实验任务 评分次数最多的10部电…

淘宝大数据分析案例

项目介绍 本次结合的是一份淘宝大数据数据&#xff0c;数据集的大小共177MB&#xff0c;数据一共有3182261份&#xff08;三百多万份数据集&#xff09;&#xff0c;一般的软件是无法计算和分析的&#xff0c;比如Excel&#xff0c;MySQL&#xff0c;Python这些都无法较好的完…

数据分析综合案例

数据分析综合案例&#xff1a; 数据分析流程 什么是数据清洗&#xff1f; 简单来说&#xff0c;数据清洗就是把“脏数据”变为“干净的数据”。数据清洗虽然很繁琐&#xff0c;但也很重要。数据清洗流程&#xff1a; 数据的读写、数据的探索与描述、数据简单处理、重复值的处…

磁力搜索网站+下载神器放送2019-03-05

先介绍下背景,因为喜欢看的电影因为版权问题,不能用迅雷及百度云离线下载.今天找了好久,终于发现了一个好用的解决方案. 先介绍常用的磁力搜索网站: 搜索网 https://btsow.pw/tags https://cn.torrentkitty.tv https://www.ciliurl.com/ http://www.zhizhuc.com/ https://www.a…

几款磁力搜索引擎,找资料更方便

Bt177.info 一款强大的磁力搜索引擎网站&#xff0c;这款网站包含有7万多个磁力链接&#xff0c;提供提供网盘形式和磁力形式的储存&#xff0c;有很多你想要的东西。如果是音频和视频的话支持在线观看。 Bt977 磁力搜索引擎&#xff0c;支持网盘播放&#xff0c;磁力下载。 To…

搜索下载神器

前言 新闪存云app是一款功能非常强大的云盘软件&#xff0c;为用户提供了非常给力资源搜索功能&#xff0c;支持多种下载方式&#xff0c;让你在这里体验全网最快速的资源下载&#xff0c;多种格式的文件以及视频也都可以在这里进行下载并进行解析&#xff0c;操作十分的简单&a…

基于python的种子搜索网站,你懂得!

该项目是基于python的web类库django开发的一套web网站&#xff0c;给师弟做的毕业设计。本人的研究方向是一项关于搜索的研究项目。在该项目中&#xff0c;笔者开发了一个简单版的搜索网站&#xff0c;实现了对数据库数据的检索和更新。通过开发该项目&#xff0c;笔者学习和巩…