Linux Kernel Driver (6): 1. Device Control-IOCTL

Source: Internet
Author: User

I. Functions of IOCTL

1. In addition to the ability to read and write devices, most drivers also need the ability to control hardware. For example, to change the baud rate of a device, the device must report an error message. These operations are often implemented through the ioctl method.

Ii. IOCTL usage

1. In the user space, the ioctl system call is used to control the device. The function prototype is as follows:

Int IOCTL (int fd, unsigned long cmd ,【...]);

Note: The ellipsis "..." in the parameter list indicates an optional parameter. The existence of these parameters depends on the Control Command (2nd parameter cmd ).

2. IOCTL in the driver method (the ioctl driver method has a prototype different from the user space version ):

INT (* IOCTL) (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long Arg );

Parameters:

= Inode: records some device numbers and other information.

= Filp: corresponding to an opened file, which records information such as the file's read/write location.

= Cmd: this parameter is passed down from the user space,

= Arg: an optional parameter, whether it is an integer or a pointer, Arg is passed in the form of an unsigned long. If the 3rd parameter cmd command does not involve data transmission, the value of the 3rd parameter Arg is meaningless.

Iii. IOCTL implementation method: (STEP)

1. Define commands

(1) In essence, a command is a 32-bit integer. To prevent incorrect devices from using the correct command, the command number should be unique within the system.

(2) The IOCTL command code is divided into four bit segments (these bit fields are defined in include/ASM/IOCTL. h). They are:

A, type (magic number) B, serial number C, direction D, parameter size

(3) the correct way to define commands is to use four bit segments. The symbols described in this list are defined in <Linux/IOCTL. h>

= Type (PHANTOM: type)

The device command is selected after ioctl-number.txt is referenced. The value is 8 bits.

Eg:

We specify a type (magic number) for each device. If we specify 3 for a device, all the commands with the value of 3 for the Type segment serve the device.

= Number (serial number)

A device has multiple control commands. The value of this field indicates that the current command is the first command in all Device Control commands, with an 8-bit width.

= Direction (data transmission direction)

Commands involving data transmission need to specify the direction of data transmission (for example, setting the baud rate). The direction of data transmission is viewed from the application's point of view. Possible values include:

--- _ Ioc_none: No Data Transmission

--- _ Ioc_read: read from the device

--- _ Ioc_write: Write to Device

= Size (user data size)

13/14-Bit Width, depending on the processor

(4) The Kernel provides the following macros to help define commands:

= _ IO (type, NR), used to construct commands without Parameters

Because there is no parameter, the direction (equal to _ ioc_none) and size (equal to 0) of this command are clear and do not need to be set.

Therefore, if you use this macro and input the type field and NR field value of the command, it will help you construct and return a command without parameters.

= _ Ior (type, NR, datatype), read data from the driver

You do not need to provide the size directly here. This macro will automatically calculate the size of the data according to the parameter type datatype you provide.

==_ Iow (type, NR, datatype), write data to the driver

==_ IOWR (type, NR, datatype), bidirectional transfer, type and number members are passed as parameters

Eg:

# Define mem_ioc_magic 'M' // defines the magic number. Because the magic number is an 8-Bit Width, it is actually a char variable, of course, we can assign a value to it with a single character # define mem_iocset _ Iow (mem_ioc_magic, 0, INT); // define a command mem_iocset, used to write data to the device # define mem_iocgqset _ ior (mem_ioc_magic, 1, INT) // read data to the device

2. Implementation commands (ioctl function implementation includes the following three technical links: A, return value B, Parameter Setting C, and command operation)

(1) The implementation body of the ioctl function is a switch statement, and the switch parameter is cmd. If the command number does not match any command, return the-einval (error invalid is invalid parameter. Note that there is a negative number before)

(2) How to Use the 4th parameter ARG in the ioctl function (transmitted from the user space )? If it is an integer, you can use it directly. If it is a pointer, we must ensure that this user address is valid, so we need to perform a correct check before use.

= Using this pointer through the following functions does not require detection (because detection has been implemented within these functions) (4 ):

--- Copy_from_user

--- Copy_to_user

--- Get_user

--- Put_user

= This pointer needs to be checked using the following functions (2 ):

--- _ Get_user

--- _ Put_user

= How to check this pointer?

Use int access_ OK (INT type, const void * ADDR, unsigned long size); Function

Parameters:

--- Type: the value that can be used is verify_read or verify_write, which indicates whether to read the user memory or write the user memory.

--- ADDR: Specifies the user memory address to be operated

--- Size: The operation length. For example, if you want to read an integer from the user space, the size parameter is equal to sizeof (INT)

Return Value:

Access_ OK returns a Boolean value: 1 is successful (access is OK), and 0 is failed (access is faulty ). If this function fails, IOCTL should return-efault

Eg:

If (_ ioc_dir (CMD) & _ ioc_read) Err = access_oc (verify_write, (void _ User *) Arg, _ ioc_size (CMD )); // Why does _ ioc_read correspond to verify_write? Ioc_read indicates that data is read from the device and then transmitted to the user space. Therefore, the data is stored in the user space and written to the region pointed to by the ARG pointer of the user space. So here we want to verify that the write else if (_ ioc_dir (CMD) & _ ioc_write) Err = access_ OK (verify_write, (void _ User *) Arg, _ ioc_size (CMD); If (ERR) Return-efault;

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.