The IOCTL for advanced character driver operations
Ioctl
User space prototype: intioctl (int fd, unsigned long cmd, ...);
"..." is not a mutable parameter, but an optional parameter that prevents the compiler from doing type checking.
Driver prototypes: Int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg);
The inode and flip are the original fd,cmd intact, ARG is an additional parameter, and the type check is turned off.
Select the IOCTL command:
The old pact:
New conventions, you should first review the include/asm/ioctl.h and documentation/ioctl-number.txt two files.
The new method for defining numbers uses 4 bit fields, and the new symbols described below are defined in <linux/ioctl.h>
Type
Magic number, select a number (remember to read Ioctl-number.txt first), and use this number in the entire driver, there are 8 bits wide (_ioc_typebits)
Number
Ordinal (sequential number). 8-bit width (_ioc_nrbits).
Direction
Define data transfer direction, _ioc_none (no data transfer), _ioc_read, _ioc_write, and _ioc_read|_ioc_write (bidirectional data transfer)
Size
The size of the user data involved. The width of this field is architecture-related, typically 13 or 14, where specific values for a particular architecture can be found by _ioc_sizebits. The kernel does not check this bit field
The <asm/ioctl.h> header files included in <linux/ioctl.h> define some macros that construct the command number:
_io (TYPE,NR) for constructing parameterless commands
_ior (Type,nr,datatype)
_iow (Type,nr,datatype)
_IOWR (Type,nr,datatype)
The size field goes through datatype to sizeof.
To unlock a macro:
_ioc_dir (NR), _ioc_type (NR), _ioc_nr (NR), _ioc_size (NR)
return value:
Some return-enval (invalidargument, illegal arguments) when the IOCTL is not matched by a legitimate operation. POSIX rules should return-enotty (Inappropriateioctl for device, not suitable for the appliance's IOCTL)
Pre-defined commands:
There are commands that can be identified by the kernel, which are resolved before our operation is invoked, so if our own commands use the same number as those commands, we never receive requests for that command, and the command conflicts, and the behavior of the application is unpredictable.
Divided into three groups:
Commands that can be used with any file (normal, device, FIFO, and socket)
Commands for normal files only
Commands specific to the file system type
The first set of magic numbers are "T"
The following IOCTL commands are predefined for any file, including device-specific files:
Fioclex
Fionclex
Fioasync
Fioqsize
Fionbio
Use the IOCTL parameter:
If the argument is a pointer, you should be concerned about whether the user space pointed to is a legitimate issue. Copy_from_user and Copy_to_user can safely exchange data with user space, but the IOCTL involves small data items and is inefficient.
The address can be verified by the function ACCESS_OK, which is declared in <asm/uaccess.h>:
INTACCESS_OK (int type, const void *ADDR, unsigned long size);
The first parameter is Verify_read or Verify_write. Unlike the other, returning 1 indicates success, and returning 0 indicates that the failed driver typically returns-efault to the caller
After calling ACCESS_OK, the data can be transferred safely.
You can also use functions that are optimized for the most commonly used data size (1,24,8), which are defined in <asm/uaccess.h>, listed below:
Put_user (DATUM,PTR)
__put_user (DATUM,PTR)
When these macro definitions are expanded without type checking, Put_user checks to ensure that the process can write to the specified memory address and returns 0 on success, returning-efault on error. __put_user does less checking (it does not call ACCESS_OK), but if the address only wants memory that the user cannot write, the operation fails, so __put_user should be used after the memory area has been tested with ACCESS_OK.
The general usage is that when you implement a read method, you can call __put_user to save several clock cycles, or to call a ACCESS_OK before copying multiple data.
Get_user (LOCAL,PTR)
__get_user (LOCAK,PTR)
If you attempt to pass a numeric value that does not conform to any particular value using the functions listed above, the result is usually a strange message from the compiler, such as "Conversionto Non-scalar type requested (need to be converted to non-scalar type)".
Empowerment and restricted operations
All-in-one operation can be found in <linux/capability.h>, which contains ownership energy that the system can understand, without modifying the kernel source code, and the power to the driver developers is as follows:
Cap_dac_override
The ability to bypass the access rights (data access control or DAC) of a file or directory
Cap_net_admin
The ability to perform network management tasks, including those that can affect network interfaces
Cap_sys_module
Ability to load or unload kernel modules
Cap_sys_rawio
Ability to perform bare Io, such as accessing device interfaces or communicating directly with USB devices
Cap_sys_admin
The ability to intercept, which provides access to many system management operations
Cap_sys_tty_config
Ability to perform TTY configuration tasks
function definition of check power in <sys/linux.h>
intcapable (int capability);
This article is from the "No Front" blog, please be sure to keep this source http://qianyang.blog.51cto.com/7130735/1620572
The IOCTL for advanced character driver operations