[Turn] IOCTL's command cmd construction detailed

Source: Internet
Author: User
turn from: http://blog.csdn.net/helloanthea/article/details/25330809. 0 Preface

Prior to the IOCTL of the CMD knowledge is: As long as the application to ensure that the introduction of the driver-defined cmd consistent. But this was not the case recently found in the development of a driver. When an attempt to pass in the command word is 0x0000_0002, a bad address error occurs, and there is no IOCTL method to enter the driver definition (the first statement (print) is not executed), and the other commands are entered normally. Debugging for a long time, think back to the university teaching assistants and the teacher debate whether the need to call the kernel API to construct the command, was always firmly believe that is not, those APIs are only used for understanding, so the last attempt to change the 0x0000_0006 unexpectedly normal execution, suddenly, then decided to standardize the later CMD. (In fact, the reason for refusing to accept is because the application layer did not find the corresponding API, hateful at that time did not quiet down to delve into).

Finally, it is stated that the IOCTL cannot be 2 because the Vfs_ioctl or File_ioctl will be experienced in the process of calling IOCTL from the application layer to the drive xxx_drv_ioctl, which is considered an illegal value in the middle for 2, as described in "http:// Stackoverflow.com/questions/10071296/ioctl-is-not-called-if-cmd-2 "or" http://www.cnblogs.com/kevinhwang/p/ 5665485.html ". 1 Composition of IOCTL

CMD is 32 bits in size and is divided into 4 fields:

The Bit31~bit30 2-bit is a "read-write" area that distinguishes between reading commands and writing commands.

The bit29~bit15 14-bit is the data size area, representing the amount of memory transferred by the ARG variable in IOCTL ().

The bit20~bit08 8-bit is the "magic number" (also known as the "magic number") area, which distinguishes it from the IOCTL commands of other device drivers.

The bit07~bit00 8-bit is the "difference ordinal" area, which is a command sequence ordinal number that distinguishes a command. 2 API padding

The value in the "distinguish read-write area" in the command code may be _ioc_none (0 value) indicating no data transfer, _ioc_read (read), _ioc_write (write), _ioc_read|_ioc_write (bidirectional).

The kernel defines the _io (), _ior (), IOW (), and _IOWR () 4 macros to assist in generating cmd above. The following is an analysis of the implementation of _io (), others similar.

You can see the definition of _io () in asm-generic/ioctl.h:

#define _IO (TYPE,NR) _ioc (_ioc_none, (Type), (NR), 0)

Then look at the definition of _IOC ():

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

((dir) << _ioc_dirshift| \

((type) << _ioc_typeshift) | \

((nr) << _ioc_nrshift) | \

(size) << _ioc_sizeshift)

It is visible that the final result of the _io () is a combination of 4 parameter shifts in the _IOC (). Then look at the definition of _ioc_dirshit:

#define _IOC_DIRSHIFT (_ioc_sizeshift+_ioc_sizebits)

Definition of _ioc_sizeshift:

#define _IOC_SIZESHIFT (_ioc_typeshift+_ioc_typebits)

Definition of _ioc_typeshif:

#define _IOC_TYPESHIFT (_ioc_nrshift+_ioc_nrbits)

Definition of _ioc_nrshift:

#define _IOC_NRSHIFT 0

Definition of _ioc_nrbits:

#define _IOC_NRBITS 8

Definition of _ioc_typebits:

#define _IOC_TYPEBITS 8

From the above definition, push up:

_ioc_typeshift =8

_ioc_sizeshift =16

_ioc_dirshift =30

So, (dir) << _ioc_dirshift) indicates that dir moves 30 bits to the left, that is, to the Bit31~bit30 two bit, to get the direction (read and write) attributes, (size) << _ioc_sizeshift) bit to the left 16 bit To the data size area (type) << _ioc_typeshift) to the left 8 digits to get the "Magic Area" (NR) << _ioc_nrshift), 0-bit left (bit7~bit0). In this way, you get the macro value of _io ().

So calling IOCTL () in an application is generally like this:

#define I2c_ioctl_cmd_make (CMD) (_io (I2c_drv_magicnum, cmd))

CMD = i2c_ioctl_cmd_make(i2c_cmd_write);

Status = ioctl(hndl->fd, cmd,&prm);

This call is made in the corresponding driver when the switch makes a classification of CMD:

#define I2c_ioctl_cmd_get (CMD) (_ioc_nr (cmd))

#define I2C_IOCTL_CMD_IS_VALID (CMD) (_ioc_type (cmd) = = i2c_drv_magicnum)? 1:0)

if (! I2c_ioctl_cmd_is_valid(CMD))

return-1;

CMD = i2c_ioctl_cmd_get(cmd);

switch (cmd)

{}

So what is _ioc_nr () and _ioc_type () is the reverse operation of _io () from a formal perspective

The following macros are used in the following formats:

_io (magic number, base);

_ior (magic number, cardinality, variable type)

_iow (magic number, cardinality, variable type)

_IOWR (magic number, cardinality, variable type)
magic Number (MagicNumber)

The magic number range is 0~255. Usually, the English character "a" ~ "Z" or "a" ~ "Z" is expressed. The device driver obtains the magic number from the command passed in, and then compares it to the number of demons it handles, if the same is handled, and the difference is not processed. The magic number is a preliminary auxiliary state for refusing to use misuse. The device driver can get the magic number by _ioc_type (cmd) . Different device drivers have the best set of different magic numbers, but not absolute, but also the number of magic that other device drivers can use.

number of base (serial number)

Cardinality is used to distinguish between various commands. Typically, the value is incremented from 0 and can be reused on the same device driver. For example, the same cardinality is used in the read and write commands, and device drivers can be distinguished because the device driver uses the switch when differentiating commands and uses the command variable cmd value directly. A macro that creates a command generates a value that is composed of multiple domains, so even the same cardinality is judged to be a different command. If the device driver wants to get the cardinality from the command, use the following macro:

_IOC_NR (CMD)

Variable Type

The variant uses the ARG variable to specify the data size of the transfer, but not directly into the input, but instead to the variable or the type of the variable, because the sizeof () compilation command is already included in the use of the macro creation command.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.