You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux系统中如何获取_IOWR宏定义的IOCTL_NAME对应的IOCTL编号

IOCTL编号计算方法

Linux系统下ioctl编号是32位整数,由_IOWR这类宏按固定规则拼接生成,计算逻辑如下:

1. 先明确ioctl编号的4个组成字段(主流x86/ARM架构规则)

  • 方向位(2位,最高2位):标识数据传输方向,_IOWR对应读写双向,取值为_IOC_READ | _IOC_WRITE = 2 | 1 = 3
  • 大小位(14位,方向位之后的14位):标识传输参数的字节大小,等于sizeof(ioctl_param)的结果
  • 魔数位(8位,大小位之后的8位):你定义的IOCTL_MAGIC为字符'A',对应ASCII码十进制65、十六进制0x41
  • 序号位(8位,最低8位):你传入的功能序号2,对应值为0x2

2. 宏拼接逻辑

内核中_IOWR的底层展开规则为:

// 内核标准宏定义
#define _IOC(dir, type, nr, size) \
    (((dir)  << _IOC_DIRSHIFT) | \
     ((type) << _IOC_TYPESHIFT) | \
     ((nr)   << _IOC_NRSHIFT) | \
     ((size) << _IOC_SIZESHIFT))
#define _IOWR(type, nr, size) _IOC(_IOC_READ|_IOC_WRITE, (type), (nr), sizeof(size))

其中默认移位偏移值为:_IOC_DIRSHIFT=30、_IOC_SIZESHIFT=16、_IOC_TYPESHIFT=8、_IOC_NRSHIFT=0

3. 实际计算示例

假设你定义的ioctl_param类型大小为16字节,计算过程为:

  • 方向位部分:3 << 30 = 0xC0000000
  • 大小位部分:16 << 16 = 0x00100000
  • 魔数位部分:65 << 8 = 0x00004100
  • 序号位部分:2 << 0 = 0x00000002
    将四个部分按位或得到最终值:0xC0000000 | 0x00100000 | 0x00004100 | 0x00000002 = 0xC0104102

快速获取准确值的方法

如果不想手动计算避免出错,可以直接在C代码中添加打印语句编译运行即可得到真实值:

#include <stdio.h>
// 此处引入你定义IOCTL_NAME的头文件
int main() {
    printf("IOCTL_NAME 对应编号为:0x%x\n", IOCTL_NAME);
    return 0;
}

内容的提问来源于stack exchange,提问作者MicrosoctCprog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 04:45:10