linux ioctl编程基础

本文详细介绍了ioctl命令的工作原理,包括命令的组成元素如幻数、序数等,以及如何在用户态和内核态之间传递数据。同时,还介绍了在内核空间中处理ioctl命令的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在用户态中,很多时候除了要读写内核设备外,还要进行一些其他的控制。ioctl可以实现用户态和内核态的通信,即通过用户态向内核态发送命令,在内核态的switch  case中做出相应的处理,即可在用户态实现对内核态的控制。那么ioctl是怎么实现的呢?

       1. 首先用户态要向内核态发送命令,看看命令是怎么构成的。一个ioctl命令被分为多个字段,包括:类型(幻数)、序数、传送方向以及参数的大小。

        type:幻数。选择一个号码(记住先仔细阅读ioctl-number.txt),并在整个驱动程序中使用这个号码,8位宽(_IOC_TYPEBITS).

        number:序数(顺序编号、在我们的驱动中可以用命令的枚举序数)。也是8为宽

        direction:数据传送的方向。

        size:所涉及ioctl函数中所传送参数的大小。

       linux中有一些构造构造命令编号的宏:

       _IO(type, nr)用于构造无参数命令的编号

      _IOR(type, nr, datatype)用于构造从设备中读取数据的命令的编号。

      _IOW(type, nr, datatype)用于构造向设备中写数据的命令的编号。

     _IOWR(type, nr, datatype)用于构造双向传输数据的命令的编号。

    2.在用户空间中。ioctl系统调用的原型:

    ioctl(int fd, unsigned long cmd, void *arg);

    fd:  为打开的设备的文件描述符

    cmd:为上面生成的命令码编号

    arg:用户需要传入的参数(在用户空间和内核空间要通过copy_from_user和copy_to_user交换数据)

  3.在内核空间ioctl的原型如下:

     int (*ioctl) (struct  inode  *inode, struct  file  *filp, unsigned  int cmd, unsigned  long  arg)

     inode  和 filp两个指针的值对应于应用程序传送的文件描述符fd。

    在内核中可以用_IO_TYPE(cmd)来获取命令的幻数,可以用来判断是不是我们要出来的命令

     _IO_NR(cmd)可以用来获取命令的命令码,用于在switch  case中处理。

     4.当用一个指针在用户空间时,必须确保指向的用户空间时合法的。为此,我们可以通过access_ok验证地址(而不用传输数据)。

     int   access_ok(int type, const void  *addr, unsigned int size)

     第一个参数应该是VERIFY_READ和VERIFY_WRITE,取决于是要写入还是读取数据。addr是一个用户空间地址,size是字节数。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值