The ioctl20160705 of Linux

Source: Internet
Author: User
Tags readable

IOCTL (Fdacodec, Acodec_get_adcl_vol, &vol_ctrl)//Get or set data from the kernel driver
The kernel driver also uses Acodec_get_adcl_vol for case, because the magic number and cardinality in this cmd are defined by the system function IOWR, the kernel driver will know.
#define Acodec_get_adcl_vol \//acodec_get_adcl_vol This cmd is equivalent to _IOWR (...), using this function to define CMD_IOWR (Ioc_type_acodec, ioc_nr_get_ Adcl_vol, Acodec_vol_ctrl)
_IOWR (Ioc_type_acodec, Ioc_nr_get_dacl_vol, Acodec_vol_ctrl)//ioc_type_acodec magic number Ioc_nr_get_dacl_vol cardinality ...
Acodec_vol_ctrl variable type, using the ARG variable to specify the size of the transmitted data, but not directly substituting the input, but substituting the variable or the type of the variable
int ioctl (int fd, int cmd, void *data)
_io (magic number, radix);
_ior (magic number, cardinality, variable type)
_iow (magic number, cardinality, variable type)
_IOWR (magic number, cardinality, variable type)
The device driver obtains the magic number from the command passed in, and then compares it to the number of demons it handles, and if the same is handled, the difference is not handled
The cardinality is used to differentiate between various commands. Typically, increments starting from 0
The variable type uses the ARG variable to specify the size of the data being transferred, but instead of substituting the input directly, substituting the variable or the type of the variable

IOCTL and kernel exchange data
1. Preface

Using the IOCTL system call is one of the most common ways to exchange data between user space and the kernel, and from the name of the IOCTL, it is intended to be a control operation for I/O devices, but the actual I/O device is not limited, it can be any kernel device.

2. Basic process

In kernel space, the IOCTL is a member function of many kernel operation structures, such as the file operation structure struct file_operations (include/linux/fs.h), the protocol operation structure struct proto_ops (include/ Linux/net.h), such as the TTY operation structure struct tty_driver (include/linux/tty_driver.h), which correspond to various kernel devices, as long as the devices are opened in user space, such as i/ o The device can be opened with open (2), the network protocol may be opened with a socket (2), etc., and after obtaining a file descriptor, it is possible to invoke the IOCTL (2) on this descriptor to exchange data to the kernel.

3. IOCTL (2)

The basic use format for the IOCTL (2) function is:
int ioctl (int fd, int cmd, void *data)
The first parameter is the file descriptor; cmd is an operation command, generally divided into get, set and other types of commands, get is the user space process from the kernel read data, set is the user space process to the kernel to write data, cmd is an integer, but there is a certain parameter format, the following detailed description The third parameter is the data start position pointer,
The cmd command parameter is a 32-bit integer, divided into four parts:
DIR (2b) size (14b) type (8b) NR (8b)
Detailed definition of CMD to include these 4 parts can be defined using macro _IOC (Dir,type,nr,size), and in the simplest case use _io (type, NR) to define it, these macros are defined in Include/asm/ioctl.h
This article cmd is defined as:
#define Newchar_ioc_magic ' M '
#define Newchar_set _io (newchar_ioc_magic, 0)
#define Newchar_get _io (newchar_ioc_magic, 1)
#define NEWCHAR_IOC_MAXNR 1

To define your own IOCTL operations, there are two ways to add the relevant code directly to the existing kernel code, such as the use of the socket descriptor for IOCTL operations, which can be Inet_ioctl () in net/ipv4/af_inet.c function to add their own defined commands and related handlers, recompile the kernel, but this method is generally not recommended, the second method is to define their own kernel devices, through the device's IOCTL () to operate, can be compiled into modules, which does not affect the original kernel, this is the most common practice.

4. Kernel devices

The most common use of a character device for IOCTL operations is to define other types of devices as well. In user space, you can use the Mknod command to establish a character type device file, assuming that the device has a primary device number of 123 and a secondary device number of 0:
Mknode/dev/newchar C 123 0
If you are programming, you can use the Mknode (2) function to create a device file.

After the device file is established and the kernel module file of the device is inserted into the kernel, the/dev/newchar file can be opened using open (2), then the IOCTL (2) is invoked to pass the data, and finally the device is closed with close (2). Open (2) fails if the device's module is not plugged into the kernel.

Because the kernel memory space and the user memory space are different, to copy the kernel data to the user space, to use the special copy function Copy_to_user (); To copy the user-space data to the kernel, use Copy_from_user ().
The simplest implementation of the above functions, the kernel module only need to implement the device's open, IOCTL and release three functions can be,
The following describes the program snippet:
static int newchar_ioctl (struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg);
static int Newchar_open (struct inode *inode, struct file *filep);
static int newchar_release (struct inode *inode, struct file *filep);
Defines the file operation structure, in which other elements in the structure are empty
struct File_operations newchar_fops =
{
Owner:this_module,
Ioctl:newchar_ioctl,
Open:newchar_open,
Release:newchar_release,
};
Define the data block structure to be transferred
struct newchar{
int A;
int b;
};
#define MAJOR_DEV_NUM 123
#define DEVICE_NAME "Newchar"

Turning on the device is very simple, which is to add the module counter to prevent the module from being removed when the device is turned on.
Of course you want to make it complicated. Various restrictions can be checked, such as allowing only the specified user to open and so on:
static int Newchar_open (struct inode *inode, struct file *filep)
{
Mod_inc_use_count;
return 0;
}

Turn off the device, also very simple, minus the module counter:
static int newchar_release (struct inode *inode, struct file *filep)
{
Mod_dec_use_count;
return 0;
}

Basic handler function for IOCTL invocation
static int newchar_ioctl (struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg)
{
int ret;
First check if CMD is legal
if (_ioc_type (cmd)! = newchar_ioc_magic) Return-einval;
if (_ioc_nr (cmd) > Newchar_ioc_maxnr) return-einval;
Default return value in case of error
ret = EINVAL;
Switch (CMD)
{
Case Knewchar_set:
Set up operations to copy data from user space to kernel space
{
struct Newchar NC;
if (Copy_from_user (&NC, (const char*) arg, sizeof (NC))! = 0)
Return-efault;
ret = Do_set_newchar (&NC);
}
Break
Case Knewchar_get:
A get operation typically passes a partial initial value as a data lookup condition in the data buffer, getting all
The data is then re-written back to the buffer
Of course, you can get the data directly to the kernel, depending on the situation.
{
struct Newchar NC;
if (Copy_from_user (&NC, (const char*) arg, sizeof (NC))! = 0)
Return-efault;
ret = Do_get_newchar (&NC);
if (ret = = 0) {
if (Copy_to_user ((unsigned char *) arg, &NC, sizeof (NC))!=0)
Return-efault;
}
}
Break
}
return ret;
}
Module initialization function, registering character device
static int __init _init (void)
{
int result;
Registering the character device, which is the basic method before 2.4, has changed after 2.6,
is done using Mkdev and Cdev_init (), this article is still based on the old method
result = Register_chrdev (Major_dev_num, Device_name, &newchar_fops);
if (Result < 0) {
PRINTK (kern_warning __function__ ": Failed register character device for/dev/newchar\n");
return result;
}
return 0;
}
Module Exit function, logout character device
static void __exit _cleanup (void)
{
int result;
result = Unregister_chrdev (Major_dev_num, device_name);
if (Result < 0)
PRINTK (__function__ ": Failed unregister character device for/dev/newchar\n");
Return
}
Module_init (_init);
Module_exit (_cleanup);

5. Conclusion

The use of the IOCTL () in the user space and kernel space to pass data is one of the most common methods, simple and convenient, and can be in the same ioctl to different commands to send different data structures, this article is only convenient for the description of the different commands used the same data structure.


Cmd
In the driver, the variable cmd that is passed on the IOCTL () function is the value that the application uses to differentiate the contents of the device driver request processing. In addition to distinguishing numbers, CMD contains several appropriate information that can help with processing. The size of CMD is 32 bits and is divided into 4 domains:
The Bit31~bit30 2-bit is a "read-and-write" area that distinguishes between a read command or a write command.
bit29~bit15 14 bits is the data size area, which represents the amount of memory transferred by the ARG variable in the IOCTL ().
The bit20~bit08 8-bit is the "magic number" (also known as the "magic number") area, which is used to differentiate from the IOCTL commands of other device drivers.
bit07~bit00 8-bit is the "difference ordinal" area, which is a command sequence ordinal that distinguishes commands.
The value in the "read-write zone" 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 4 macros _io (), _ior (), IOW (), and _IOWR () to assist in generating the above cmd. The following is an analysis of the implementation of _io (), other similar:< xmlnamespace prefix = "o" ns = "Urn:schemas-microsoft-com:office:office"/>

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

As can be seen, the final result of _io () is a combination of the 4 parameter shifts in _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

By the definition above, the upward push gets:

Reference

_ioc_typeshift = 8

_ioc_sizeshift = 16

_ioc_dirshift = 30

Therefore, the (dir) << _ioc_dirshift) Table is dir moving to the left 30 bits, that is, moving to bit31~bit30 two bits, to obtain the direction (read and write) properties;
(size) << _ioc_sizeshift) bit left 16 bits get "data size" area;
(type) << _ioc_typeshift) shift left 8 to get "magic number Area";
(NR) << _ioc_nrshift) move left 0 bits (bit7~bit0).
In this way, the macro value of _io () is obtained.

These 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 Numbers (magic number)
The magic number range is 0~255. Typically, the English characters "a" ~ "Z" or "a" ~ "Z" are represented. The device driver obtains the magic number from the command passed in, and then compares it to the number of demons it handles, and if the same is handled, the difference is not processed. The magic number is the primary auxiliary state that denies misuse. The device driver can get the magic number by _ioc_type (CMD). Different device drivers are best to set different magic numbers, but not absolute, but also the number of magic numbers that can be used by other device drivers.
Number of base (serial number)
The cardinality is used to differentiate between various commands. Typically, the value is incremented from 0, which 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 switch when differentiating commands and uses the command variable cmd value directly. The macro generated by creating a command is composed of multiple domains, so even the same cardinality is judged as a different command. To get the cardinality from the command, the device driver uses the following macro:
_IOC_NR (CMD)
Typically, the case value in switch uses the command itself.
Variable type
The variable type uses the ARG variable to specify the size of the data being transferred, but instead of substituting the input directly, it is substituting the variable or the type of the variable, because the sizeof () Compile command is already included in the use of the macro creation command. For example, the _ior () macro is defined as:

Reference

#define _ior (type,nr,size) _ioc (_ioc_read, (Type), (NR), (_ioc_typecheck (size)))

And the definition of _ioc_typecheck () is:

Reference

#define _ioc_typecheck (t) (sizeof (t))

The following macro functions are used by the device driver to obtain the corresponding value from the routed command:
_ioc_size (CMD)

_IO macro

The macro function does not have a variable that can be transferred, but is used to transfer commands. For example, the following conventions:

Reference

#define Test_drv_reset _io (' Q ', 0)

At this point, omit the ARG variable passed by the application or substitute 0. When you use the macro in your application, such as:

IOCTL (Dev, test_dev_reset, 0) or ioctl (Dev, test_drv_reset).
This is because the effective factor of the variable is the variable factor. When used only as a command, it is not necessary to determine the output or input of the data on the device. Therefore, it is not necessary for the device driver to perform the related processing of the device File open option.

_IOR macro
This function is used to create commands that read data from the device, such as the following conventions:

Reference

#define Test_dev_read _IRQ (' Q ', 1, int)

This indicates that the application reads data from the device to the size int. The following macro is used to determine the read and write status of the cmd command delivered to the device driver:
_ioc_dir (CMD)
When you run the macro, the type of the return value is as follows:
? _ioc_none: No Attributes
? _ioc_read: Readable properties
? _ioc_write: Writable Properties
? _ioc_read | _ioc_write: Readable, writable property

When you use this command, the ARG variable value of the application's IOCTL () specifies the cache (struct) address when the data is read on the device driver.
_IOW macro
Used to create a command to write data on the device, the remainder is the same as _ior. Typically, when you use this command, the ARG variable value of the IOCTL () specifies the cache (struct) address when the data is written on the device driver.
_IOWR macro
The command used to create read and write data on the device. The remainder is the same as _ior. Typically, when you use this command, the ARG variable value of the IOCTL () specifies the cache (struct) address when the data is written or read on the device driver.
Definition of _ior (), _iow (), IORW ():
#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)))

The ioctl20160705 of Linux

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.