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

Android ioctl 第二个参数命令码以及BINDER_FREEZE示例

1. _IOC_NRSHIFT _IOC_TYPESHIFT _IOC_SIZESHIFT _IOC_DIRSHIFT

宏定义了命令码中各字段的二进制偏移量,用于将不同参数定位到命令码的特定位置

#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
#define _IOC_SIZEBITS 14
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS)
​​_IOC_DIRSHIFT​​
​​作用​​:方向(dir)字段的起始位偏移量。
​​值​​:30(大小占 14 位后,方向从第 30 位开始)。
​​计算逻辑​​:_IOC_SIZESHIFT + _IOC_SIZEBITS = 16 + 14 = 30
_IOC_TYPESHIFT​​
​​作用​​:类型(type,即幻数)字段的起始位偏移量。
​​值​​:8(序号占 8 位后,类型从第 8 位开始)。
​​计算逻辑​​:_IOC_NRSHIFT + _IOC_NRBITS = 0 + 8 = 8
_IOC_NRSHIFT​​
​​作用​​:序号(nr)字段的起始位偏移量。
​​值​​:0(序号是命令码的第一个字段,从最低位开始)。
​​计算逻辑​​:序号占 _IOC_NRBITS(8 位),因此其偏移量为 0
_IOC_SIZESHIFT​​
​​作用​​:数据大小(size)字段的起始位偏移量。
​​值​​:16(类型占 8 位后,大小从第 16 位开始)。
​​计算逻辑​​:_IOC_TYPESHIFT + _IOC_TYPEBITS = 8 + 8 = 16

2. _IOC_TYPECHECK

此宏用于验证数据类型的大小是否合法,并生成数据大小字段的值

#define _IOC_TYPECHECK(t) (sizeof(t))

计算数据类型 t 的大小(通过 sizeof)。
确保数据大小不超过 14 位能表示的最大值(即 16383 字节)。

3. _IOC

通过 _IOC 宏将各字段组合为最终的命令码

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

4. BINDER_FREEZE

1. 命令定义分解
#define BINDER_FREEZE      _IOW('b', 14, struct binder_freeze_info)
#define _IOW(type,nr,size)  _IOC(_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
#define _IOC(dir,type,nr,size) \(((dir)  << _IOC_DIRSHIFT) | \((type) << _IOC_TYPESHIFT) | \((nr)   << _IOC_NRSHIFT) | \((size) << _IOC_SIZESHIFT))
2. 命令码的二进制结构

一个 ioctl 命令码是 ​​32位整数​​,按以下分段:
所谓幻数就是类型的意思。

3. 具体计算示例

假设 struct binder_freeze_info 的大小为 ​​12 字节​​:
各字段二进制位置:

// 1. 方向 _IOC_WRITE (写操作)
方向位 = 1 << 30 (0x40000000)
// 2. 幻数 'b' (ASCII码 0x62)
幻数位 = 0x62 << 24 (0x62000000)
// 3. 序号 14
序号位 = 14 << 16 (0x000E0000)
// 4. 数据大小 12
大小位 = 12 << 0 (0x0000000C)
命令码 = 0x40000000 | 0x62000000 | 0x000E0000 | 0x0000000C = 0x62 00 E0 0C → 十六进制表示为 0x62E00C
4. 关键设计思想

为何需要如此复杂的宏?

  1. ​​类型安全​​:
    _IOC_TYPECHECK(size) 确保用户空间传递的结构体大小与内核一致,避免内存越界。
  2. ​​方向明确​​:
    明确数据流向(_IOC_READ/_IOC_WRITE),驱动无需猜测用户意图。
  3. ​​幻数隔离​​:
    不同驱动的幻数不同(如 Binder 用 ‘b’,USB 用 ‘U’),避免命令码冲突。

相关文章:

  • vue3项目中eslint.config.ts配置rules
  • 18.ArkUI Video的介绍和使用
  • ECharts 地图开发入门
  • HD Tune Pro v6.10 简体中文汉化单文件版
  • C++_数据结构_详解红黑树
  • Winform(1.Winform控件学习)
  • 每天学一个 Linux 命令(31):md5sum
  • Linux安全模块:SELinux与AppArmor深度解析
  • ✨ Apifox:这玩意儿是接口界的“瑞士军刀”吧![特殊字符][特殊字符]
  • XYNU2024信安杯-REVERSE(复现)
  • kafka与flume的整合、spark-streaming
  • 量子加密通信技术及其应用:构建无条件安全的通信网络
  • 【合新通信】浸没式液冷光模块与冷媒兼容性测试技术报告
  • 【滑动窗口+哈希表/数组记录】Leetcode 3. 无重复字符的最长子串
  • 搜索二叉树-key的搜索模型
  • nc工具!Netcat:TCP/IP瑞士军刀!全参数详细教程!Kali Linux教程!
  • prometheus通过Endpoints自定义grafana的dashboard模块
  • 时序数据库IoTDB在航空航天领域的解决方案
  • 对Mac文字双击或三击鼠标左键没有任何反应
  • Mac 「brew」快速安装MySQL
  • 人民日报任仲平:为什么中国意味着确定性、未来性、机遇性
  • 合同约定拿850万保底利润?重庆市一中院:约定无效,发回重审
  • 青海西宁市公安局原党委委员、副局长王小华被“双开”
  • 上海开展2025年“人民城市 文明风采”群众性主题活动
  • 魔都眼·上海车展④|奔驰宝马保时捷……全球豪车扎堆首秀
  • 还山记——走进山水、感受山水艺术的魅力