linux驱动之ioctl详解

2023-11-02

何为ioctl?

在linux对文件IO, 有打开,读写,关闭,定位等命令, 如果需要一些自定义的命令来操作我们写的驱动, ioctl便是传入这些自定义命令的函数, 先看看在应用层的函数原型:

int ioctl(int fd, unsigned long request, ...);

fd: 文件描述符
request: 请求, 即自定义命令
可变参数: 一般是一个, 此参数的存在与否却决于request的命令.

对文件调用ioctl, 在驱动层对应的便是
file_operations结构体中的:


  long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 
  long (*compat_ioctl) (struct file *, unsigned int, unsigned long);

区别在于在 64位系统上,32位的应用程序调用将会使用compat_ioctl函数。在 32位的系统上运行 32位的应用程序调用的是unlocked_ioctl。
应用层的命令会传值到第二个参数. 至于第三个参数就是应用层的可变参数, 如果arg是一个整数,可以直接使用;
如果是指针,我们必须确保这个用户地址是有效的,因此,使用之前需要进行正确检查。
内部有检查的,不需要检测的:
使用以下函数

copy_from_user
copy_to_user
get_user
put_user

自定义命令cmd参数

虽然是自定义命令, 以前需要遵守定义命令的规则.
如何定义有效的ioctl命令
从函数参数类型来看 命令类型是int型, 如何用int的整数,来表示命令?
linux中,将 32 位 int 型数据划分为四个位段, 代表不同的涵义:

设备类型 序列号 方向 数据尺寸
8 bit 8 bit 2 bit 8~14 bit

设备类型, 有时候会用一个字母来表示, 数据长度也是8, 这和用一个数字是一样的,只是更加利于记忆和理解
内核中提供了宏用来定义命令:

// include/uapi/asm-generic/ioctl.h

#define _IOC(dir,type,nr,size) \
    (((dir)  << _IOC_DIRSHIFT) | \
     ((type) << _IOC_TYPESHIFT) | \
     ((nr)   << _IOC_NRSHIFT) | \
     ((size) << _IOC_SIZESHIFT))

dir: ioctl数据传输方向, 占2bit, 取值可以: _IOC_NONE、_IOC_READ、_IOC_WRITE、_IOC_READ | _IOC_WRITE,分别指示了四种访问模式:无数据、读数据、写数据、读写数据;
type : 设备类型,占据 8 bit,在一些文献中翻译为 “幻数” 或者 “魔数”,可以为任意 char 型字符,例如 ‘a’ , ‘b’, ‘c’.
内核文档Documentation/ioctl/ioctl-number.txt中记录了内核驱动用到的type
nr : 命令编号/序数,占据 8 bit,可以为任意 unsigned char 型数据,取值范围 0~255,如果定义了多个 ioctl 命令,通常从 0 开始编号递增;
size: 涉及到 ioctl 函数 第三个参数 arg ,占据 13bit 或者 14bit(体系相关,arm 架构一般为 14 位),指定了 arg 的数据类型及长度,如果在驱动的 ioctl 实现中不检查,通常可以忽略该参数;
为了方便会使用宏 _IOC() 衍生的接口来直接定义 ioctl 命令:

// include/uapi/asm-generic/ioctl.h

/* used to create numbers */
#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)))

在使用时直接使用:

_IO:       定义不带参数的 ioctl 命令
_IOW:      定义带写参数的 ioctl 命令(copy_from_user)
_IOR:      定义带读参数的ioctl命令(copy_to_user)
_IOWR:     定义带读写参数的 ioctl 命令

看个实例:

struct data{
	int x;
	char y;
};
#define IOCTL_BASE 		 		 'S'
#define GET_MODEL_NAME	 		 _IOR(iOCTL_BASE, 0, char*)  //读命令, 带参char*, 自定义0为命令编号不可重复
#define GET_GET_POWER_STATUS	 _IOR(iOCTL_BASE, 2, int) 
#define SET_DELAY_TIME 			 _IOW(IOCTL_BASE, 3, int) //向驱动写数据
#define SET_DATA				 _IOW(IOCTL_BASE, 4, struct data)

编写驱动:
实现file_operations中的unlocked_ioctl compat_ioctl 函数指针

static long my_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct data tmp;
	int status = 1;
	switch(cmd){
	case GET_MODEL_NAME:
	...
	break;
	case GET_GET_POWER_STATUS:
	//数据传给应用层
	copy_to_user((unsigned char *)&arg,(unsigned char *)&status ,sizeof(int));
	break;
	case SET_DELAY_TIME:
	...
	break;
	case SET_DATA:
				//这里需要强制转换的类型为unsigned char * 保证数据按最小进行分割
	copy_from_user((unsigned char *)&tmp,(unsigned char *)args,sizeof(struct data));//拿到应用层传来的结构体
	
	break;
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux驱动之ioctl详解 的相关文章

  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • SSH,运行进程然后忽略输出

    我有一个命令可以使用 SSH 并在 SSH 后运行脚本 该脚本运行一个二进制文件 脚本完成后 我可以输入任意键 本地终端将恢复到正常状态 但是 由于该进程仍在我通过 SSH 连接的计算机中运行 因此任何时候它都会登录到stdout我在本地终
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 通过 Visual Studio 2017 使用远程调试时 Linux 控制台输出在哪里?

    我的Visual Studio 2017 VS2017 成功连接Linux系统 代码如下 include
  • tcpdump 是否受 iptables 过滤影响?

    如果我的开发机器有iptables规则到FORWARD一些数据包 这些数据包是否被 tcpdump 捕获 我有这个问题 因为我知道存在其他链称为INPUT如果数据包路由到 它会过滤发往应用程序的数据包FORWARD链 它会到达吗tcpdum
  • 执行“minikube start”命令时出现问题

    malik malik minikube start minikube v1 12 0 on Ubuntu 18 04 Using the docker driver based on existing profile Starting c
  • Linux 上的 Pervasive ODBC 错误 [01000][unixODBC][驱动程序管理器]无法打开 lib '/usr/local/psql/lib/odbcci.so':找不到文件

    我正在尝试让 Pervasive v10 客户端 ODBC 在 Centos 6 上运行 据我所知 没有 64 位 ODBC 客户端 因此我必须使用 32 位客户端 我终于成功安装了它 但尝试使用时出现以下错误 isql v mydsn 0
  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 并行运行 shell 脚本

    我有一个 shell 脚本 打乱大型文本文件 600 万行和 6 列 根据第一列对文件进行排序 输出 1000 个文件 所以伪代码看起来像这样 file1 sh bin bash for i in seq 1 1000 do Generat
  • 使用 shell 脚本将行附加到 /etc/hosts 文件

    我有一个新的 Ubuntu 12 04 VPS 我正在尝试编写一个安装脚本来完成整个 LAMP 安装 我遇到问题的地方是在 etc hosts文件 我当前的主机文件如下所示 127 0 0 1 localhost Venus The fol
  • 在 Mono 上运行 .Net MVC5 应用程序

    我正在 Windows 上的 Visual Studio 2013 中开发 Net 4 5 1 MVC5 应用程序 现在我想知道 是否可以在Linux Ubuntu 12 04 上运行这个应用程序 可以使用OWIN吗 Owin 可以自托管运
  • .net-core:ILDASM / ILASM 的等效项

    net core 是否有相当于 ILDASM ILASM 的功能 具体来说 我正在寻找在 Linux 上运行的东西 因此为什么是 net core ildasm 和 ilasm 工具都是使用此存储库中的 CoreCLR 构建的 https
  • 如何使用waf构建共享库?

    我想使用构建一个共享库waf http code google com p waf 因为它看起来比 GNU 自动工具更容易 更简洁 到目前为止 我实际上有几个与我开始编写的 wscript 有关的问题 VERSION 0 0 1 APPNA
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • 绕过 dev/urandom|random 进行测试

    我想编写一个功能测试用例 用已知的随机数值来测试程序 我已经在单元测试期间用模拟对其进行了测试 但我也希望用于功能测试 当然不是全部 最简单的方法是什么 dev urandom仅覆盖一个进程 有没有办法做类似的事情chroot对于单个文件并
  • 为什么同一个curl命令在windows和linux下输出不同的东西?

    为什么同样的curl o file https www link com 命令输出不同的东西 例如 如果我运行命令curl o source txt https www youtube com playlist list PLIx6Fwnp
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序

随机推荐

  • 【记录11】前端项目上传至gitee仓库及相关命令

    本篇文章适用于初次使用git base来上传项目至gitee仓库的初学者 使用git base来上传项目至国内gitee 判断当前项目是否连接仓库 2022 3 29 查看当前的用户 git config user name 查看当前用户地
  • Android Genemotion模拟器一直卡在黑屏界面

    Android Genemotion模拟器一直卡在黑屏界面 解决办法 调大对应的模拟器的内存 第一步 右键你要修改的模拟器 弹出的菜单中选择 Settings 第二步 增大或者减小内存
  • MySQL必知必会 学习笔记 第九章 用正则表达式进行搜索

    正则表达式是用来匹配文本的特殊的串 它用正则表达式语言来建立 MySQL支持的正则表达式仅为正则表达式的一个很小的子集 可通过WHERE子句使用正则表达式过滤SELECT检索出的数据 检索条件列包含字符100的所有行 SELECT colu
  • 如何搭建websocket及使用

    保持一个长连接 当服务端有新的消息 能够实时的推送到使用方 像知乎的点赞通知 评论等 都可以使用WebSocket通信 那该如何搭建呢 首先在utils文件夹下创建一个websocket ts文件 import onUnmounted fr
  • java手动抛出异常、用户自定义异常类、异常处理5个关键字、throw和throws的区别

    文章目录 1 6手动抛出异常 1 6 1代码 1 6 2结果 1 6 3throw和throws的区别 1 7用户自定义异常类 1 8异常处理5个关键字 1 9综合练习 1 9 1主函数 1 9 2自定义异常类 1 10一首小悟结束异常处理
  • 【牛客KY45】——skew数(取余法int类型溢出 改用char字符串数组)

    include
  • vue js 语音播报 语音读文字 window.speechSynthesis new SpeechSynthesisUtterance (补充无声音 问题解决办法)

    存在问题1 在google chrome 89版本之后 默认使用的线上服务来合成语音 所以在国内可能会没有声音 解决办法 通过getVoices 获取 localService为true 的字段 localService true 表示 使
  • git在linux bash下显示分支信息

    linux bash平台下查看linux分支 bash profile 在 bash profile加上以下两句 function git branch name git symbolic ref short q HEAD 2 gt dev
  • Hook原理--逆向开发

    今天我们将继续讲解逆向开发工程另一个重要内容 Hook原理讲解 Hook 可以中文译为 挂钩 或者 钩子 逆向开发中改变程序运行的一种技术 按照如下过程进行讲解 Hook概述 Hook技术方式 fishhook原理及实例 符号表查看函数名称
  • XSL中template的match属性匹配模式

    出处 http www cnblogs com ygcao archive 2010 05 23 1742247 html 匹配模式 1 匹配根节点
  • 使用sqlserver镜像时的JDBC连接字符串

    使用sqlserver数据库镜像时 有两个数据库 主库和镜像库 两个IP地址 以前的连接串只有一个地址 连接串该怎么写 查了网上的一些资料 新的JDBC支持此功能 在以前的每个连接串里面加上一个Failover partner 的参数就可以
  • 运放震荡自激原因及解决办法

    运放震荡自激的原因 1 环路增益大于1 2 反馈前后信号的相位差在360度以上 也就是能够形成正反馈 参考 自控原理 和 基于运算放大器和模拟集成电路的电路设计 自激振荡的引起 主要是因为集成运算放大器内部是由多级直流放大器所组成 由于每级
  • 怎么重写equals()方法

    equals 方式是顶级父类Object中的方法 自定义类若想重新写equals 方法 则需要考虑以下几个特性 自反性 对于任何非null的引用值 x equals x 必须返回true 对称性 对于任何非null的引用值x和y 当且仅当y
  • [机器学习与scikit-learn-40]:算法-分类-支持向量机-通过3D图像可视化线性不可分数据升维后的线性可分的效果图。

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 123838687 目录 前言 第1步
  • 中文核心期刊有哪些?

    身为中国大学生 可能我们平时接触最多的就是中文期刊啦 尤其是老师留下有关论文的作业的时候 就可能是我们大学四年和论文接触最早也是最多的时候啦 然而无论是完成老师留下的论文作业还是我们完成毕业论文的写作 要想顺利 那我们浏览的文章质量必须要好
  • 程序调试

    我高中接触过VB语言 当时主要是用笔抄写书中代码 写过一个计算器 大学主要写 C 程序 工作后需要一些脚本 写过一段时间Python 下面主要是针对C 程序 问题分类 在编程中很容易就会出现各种各样的问题 我觉得初步可以分为下面几种类型 1
  • 在无序数组中,经过排序后,找相邻元素的最大差值(O(N))

    一个无序数组 如何求出该数组排序后的任意相邻元素的最大差值 要求时间和空间复杂度尽可能低 常规操作 利用快排或堆排堆数组进行排序 时间复杂度为O NlogN 比较排序后的数组 两个相邻元素的最大差值 优化的方法 利用计数排序 当最大值和最小
  • IAR报错处理

    问题1 Error Li005 no definition for xxxxx 解决方法 1 可能是对应的h文件没有引用 2 可能是对应的c文件没有包含进工程里 3 当工程用到c 时候 c语言的内容需要做条件编译 如下 ifdef cplu
  • JVM——StringTable

    JVM StringTable string 字符串k使用一对 引起来表示 string声明为final的 不可被继承 string实现了serializable接口 表示字符串是支持序列化的 实现了Comparable接口 表示strin
  • linux驱动之ioctl详解

    何为ioctl 在linux对文件IO 有打开 读写 关闭 定位等命令 如果需要一些自定义的命令来操作我们写的驱动 ioctl便是传入这些自定义命令的函数 先看看在应用层的函数原型 int ioctl int fd unsigned lon