【问题标题】:Writing character device driver, ioctl() vs normal read/write?编写字符设备驱动程序,ioctl() 与普通读/写?
【发布时间】:2012-11-29 15:47:54
【问题描述】:

我一直在为 linux 内核编写一个字符设备模块,结果有点困惑。

我在网上看到有人谈论使用ioctl() 将命令/数据从用户程序传输到内核空间,反之亦然。但是,用file_operations struct 做已经可以做的事情似乎有些过头了

// structure containing callbacks
static struct file_operations fops = 
{
    .read = dev_read, // address of dev_read
    .open = dev_open,  // address of dev_open
    .write = dev_write, // address of dev_write 
    .release = dev_rls, // address of dev_rls
};

使用ioctl() 而不是使用在dev_read()dev_write() 定义的函数有什么好处,这些函数只需使用copy_to_user()copy_from_user() 将数据块复制到用户空间或从用户空间复制数据块?

【问题讨论】:

    标签: c linux-kernel operating-system driver


    【解决方案1】:

    ioctl 只能用于内核默认未提供的那些操作。

    在使用简单的readwrite 调用时,必须调用ioctl 来读取或写入数据到您的设备会大大降低您的易用性。

    我所说的非标准操作是指在终端设备驱动程序中设置自动 ASCII/EBCDIC 转换,或从 DVD 块设备中弹出磁盘,或修改串行通信参数(波特率、停止位等)串行通信设备。

    务必使用ioctl 将命令传输到设备驱动程序(或从中获取非数据信息,如当前参数或统计信息)(另一种方法是在数据中使用一些复杂的转义方案,如AT调制解调器的命令集或(这显示了我的年龄)Apple ][ 磁盘子系统的 CTRL-D,这很少漂亮。

    将数据传输留给标准调用。

    【讨论】:

    • 为什么不能使用读/写来做非标准操作?您可以通过读/写轻松传输命令/参数。我根本看不到 ioctl 存在的原因?
    • @John,基本上是职责分离。如果您在单个通道上混合数据和控制,则将它们分开是一件苦差事,尤其是对于异步操作。这与用于控制传输的两个 FTP TCP 会话没有什么不同。数据仅在一个会话中传输,在另一个会话中传输,从而可以轻松分离带外信息。想想如果你的命令都以xyzzy 开头并且设备驱动程序拦截了write 调用上的那些会发生什么。现在,当您想将字符串xyzzy 发送到实际的设备(例如终端)本身时会发生什么?
    • 啊,我想这更有意义,为了我的使用,我可以组合数据/控制,因为我有一个非常小的控制集和具有有限(非负)值集的数据,但是如果我的值使用了不起作用的全部范围。
    猜你喜欢
    • 2019-03-10
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    相关资源
    最近更新 更多