当前位置:首页 > 青鸟知识 > 网络技术

Linux IO节制号令天生

来源:长沙it培训学院 发布日期:2016-05-21
摘要:在驱动法式里, ioctl() 函数上传送的变量 cmd 是应用法式用于辨别配备驱动法式请求处置内容的值。cmd除可辨别数字外,还包括有助于处置的几种响应信息。

在驱动法式里, ioctl() 函数上传送的变量 cmd 是应用法式用于辨别配备驱动法式请求处置内容的值。cmd除可辨别数字外,还包括有助于处置的几种响应信息。 cmd的年夜小为 32位,共分 4 个域:

bit31~bit30 2位为 “辨别读写” 区,感化是区分是读取号令仍是写进号令。
bit29~bit16 14位为 数据年夜小 区,暗示 ioctl() 中的 arg 变量传送的内存年夜小。

bit15~bit08  8位为 “魔数 (也称为 幻数 )区,这个值用以与其它配备驱动法式的 ioctl 号令中止辨别。

bit07~bit00   8位为 辨别序号 区,是区分号令的号令挨次序号。

内审定义了 _IO() , _IOR() , IOW() 和 _IOWR() 这 4 个宏来辅佐天生下面的 cmd

[cpp]view plaincopyprint?

#define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)  

#define _IOR(type,nr,size)  _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))  

#define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))  

#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))  

#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
号令码中的 “区分读写区” 里的值多是 _IOC_NONE (0值)暗示有数据传输,_IOC_READ (读), _IOC_WRITE (写) , _IOC_READ|_IOC_WRITE (双向)。
[cpp]view plaincopyprint?

#define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)  

#define _IOC(dir,type,nr,size)  

   (((dir)   _IOC_DIRSHIFT) |  

    ((type) _IOC_TYPESHIFT) |  

    ((nr)   _IOC_NRSHIFT) |  

    ((size) _IOC_SIZESHIFT))  

 

#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)  

 

#define _IOC_NRBITS 8  

#define _IOC_TYPEBITS   8  

# define _IOC_SIZEBITS  14  

#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)#define _IOC(dir,type,nr,size)  (((dir)   _IOC_DIRSHIFT) |  ((type) _IOC_TYPESHIFT) |  ((nr)   _IOC_NRSHIFT) |  ((size) _IOC_SIZESHIFT))#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)#define _IOC_NRBITS 8#define _IOC_TYPEBITS 8# define _IOC_SIZEBITS 14
宏睁开后[cpp]view plaincopyprint?

#define _IO(type,nr)            (((_IOC_NONE)   30) | ((0) 16)) | ((type) 8) | ((nr)   0)  

#define _IO(type,nr) (((_IOC_NONE)   30) | ((0) 16)) | ((type) 8) | ((nr)   0)
(dir)   _IOC_DIRSHIFT)    dir 往左移 30 位,即移到 bit31~bit30 两位上,取得标的目的(读写)的属性;
(size) _IOC_SIZESHIFT)   size左移 16 位取得“数据年夜小”区;
(type) _IOC_TYPESHIFT)   type左移 8位取得 魔数区 ;
(nr)   _IOC_NRSHIFT)     nr左移 0 位( bit7~bit0) 取得基数区

这几个宏的应用格局为:
_IO (魔数, 基数);
_IOR (魔数, 基数, 变量型)
_IOW  (魔数, 基数, 变量型)
_IOWR (魔数, 基数,变量型 )

魔数 (magic number)魔数范围为 0~255 。但凡,用英文字符 A ~ Z 或 a ~ z 来暗示。配备驱动法式从传送进来的号令取得魔数,然后与自身处置的魔数想比力,若是不异则处置,分歧则不处置。魔数是谢绝误应用的初步辅佐情况。分歧的配备驱动法式最好设置分歧的魔数,但其实不是请求尽对,也是可运用其他配备驱动法式已用过的魔数。配备驱动法式取得魔数:
_IOC_TYPE (cmd) 基(序列号)数 基数用于辨别各类号令。但凡,从 0起头递增,不异配备驱动法式上能够重复应用该值。例如,读取和写进号令中应用了不异的基数,配备驱动法式也能分辩出来,缘由在于配备驱动法式区分号令时 应用 switch ,且直接应用号令变量 cmd值。树立号令的宏天生的值由多个域搭配而成,所以即使是不异的基数,也会断定为分歧的号令。配备驱动法式取得该基数:
_IOC_NR (cmd) 变量型 变量型应用 arg 变量指定传送的数据年夜小,可是不直接代进输出,而是代进变量或是变量的类型,缘由是在应用宏树立号令,已包括了 sizeof() 编译号令。好比 _IOR() 宏的界说是:
#define _IOR(type,nr,size)    _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))而_IOC_TYPECHECK() 的界说恰是:
#define _IOC_TYPECHECK(t) (sizeof(t))配备驱动法式想要从传送的号令取得响应的值,就要应用以下宏函数:
_IOC_SIZE(cmd)
_IO 宏 该宏函数没有可传送的变量,只是用于传送死令。例如以下商定:
#define TEST_DRV_RESET _IO ( Q , 0)
此时,省略由应用法式传送的 arg 变量或代进 0 。在应用法式中应用该宏时,好比:
ioctl (dev, TEST_DEV_RESET, 0) 或  ioctl (dev, TEST_DRV_RESET) 。
这是由于变量的有用身分是可变身分。只作为号令应用时,没有需求判 断出配备上数据的输入或输出。是以,配备驱动法式没有需求实行配备文件年夜开选项的相干处置。
_IOR 宏 该函数用 于树立从配备读取数据的号令,例如能够下商定:
#define TEST_DEV_READ  _IRQ( Q , 1, int)
这声明应用法式从配备读取数据的年夜小为 int 。上面宏用于断定传送到配备驱动法式的 cmd 号令的读写情况:
_IOC_DIR (cmd)
运转该宏时,前往值的类型 以下:
_IOC_NONE                             :  无属性
_IOC_READ                             :  可读属性
_IOC_WRITE                            : 可写属性
_IOC_READ | _IOC_WRITE : 可读,可写属性
应用该号令时,应用法式的 ioctl() 的 arg 变量值指定配备驱动法式上读取数据时的缓存(规划体)地址。
_IOW 宏 用于树立设 备上写进数据的号令,其他内容与 _IOR 不异。但凡,应用该号令时,ioctl() 的 arg 变量值指定配备驱动法式上写进数据时的缓存(规划体)地址。
_IOWR 宏 用于树立配备上读写数据的号令。其他内 容与 _IOR 不异。但凡,应用该号令时,ioctl() 的 arg 变量值指定配备驱动法式上写进或读取数据时的缓存 (规划体) 地址。

拒绝套路 试听有礼

数据已加密保证您的信息安全