将 ioctl 代码从内核模块传递到用户空间程序

Posted

技术标签:

【中文标题】将 ioctl 代码从内核模块传递到用户空间程序【英文标题】:Passing ioctl codes from Kernel module to Userspace program 【发布时间】:2013-01-31 13:34:42 【问题描述】: 内核模块中的

ioctl 代码通常定义为 .c.h 文件中的宏,即:

#define DRV_CTL_RESET          _IO(DRV_MAGIC, 0x01)
#define DRV_CTL_DSP_TO         _IO(DRV_MAGIC, 0x02)

在用户空间程序中的用法是:

ioctl(drv_fd, DRV_CTL_DSP_TO, (unsigned long)tmo);

一切都很好,但是..

问题是:在内核和用户空间之间同步ioctl代码有哪些好的做法?

我目前的解决方案是从内核模块的源代码自动生成一个 API 头文件,并将其包含在用户空间程序中。但我希望,也许有更方便的方法。

【问题讨论】:

【参考方案1】:

只需将 ioctl 代码放在 .h 文件中,并使用内核空间和用户空间中的相同 .h。还有什么比这更方便的呢? ;)

【讨论】:

这就是我现在正在做的事情。但是要定义 _IO 宏,必须包含很少的其他内核头文件。当只需要几个数字时,这看起来有点过分了。 _IO 宏在 中定义,它应该存在于任何安装了开发头文件的 linux 系统上。这些头文件 - 在 /usr/include/asm-generic,linux - 总是被导出到用户空间。 我知道并且它有效。但是我正在为嵌入式系统编写一个库,并且希望尽可能少地依赖内核。所以我的目标是在用户空间中有原始数字,就像 #define DRV_CTL_RESET 0x150 (为了清楚起见只是一个随机数)。 @KBart 最初设计 ioctl 时,数字应该嵌入一定量的魔法,而宏的存在是因为这种魔法可能会不时改变。实际上,这都是古老的历史,但遗留问题是您确实应该使用宏定义它们,这意味着您需要依赖内核头文件。即使您正在为嵌入式平台开发,您也只需要在您正在编译的机器上标头,而不是您要部署到的嵌入式平台。 所以我认为答案是否定的,没有更好的方法。谢谢你们的回答。

以上是关于将 ioctl 代码从内核模块传递到用户空间程序的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ioctl 调用没有传递给 sys_ioctl?

在内核中访问用户空间结构的成员会给出错误的值

Linux用户与内核空间交互—ioctl

Linux用户与内核空间交互—ioctl

将变量从linux内核传递给进程

分析 Linux 内核模块