Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the basic knowledge points of Linux system-driven development

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the Linux system driver development of the basic knowledge of what the relevant knowledge, the content is detailed and easy to understand, the operation is simple and fast, has a certain reference value, I believe that you will have some gains after reading this basic knowledge of Linux system driver development, let's take a look at it.

Basic summary 1, linux drivers are generally divided into three categories: * character devices * block devices * network devices

2. Development environment construction: * Cross tool chain construction * NFS and tftp server installation

3. Hardware designed in driver development: * knowledge of digital circuits * knowledge of ARM hardware * proficiency in the use of multimeters and oscilloscopes * understanding of chip manuals and schematics

4. Linux kernel source code directory structure:

* the arch/: arch subdirectory contains all the core code related to the architecture. Each of its subdirectories represents a supported architecture, such as i386, which is a subdirectory about intel cpu and its compatible architecture.

* block/: partial block device driver

* crypto: commonly used encryption and hashing algorithms (such as AES, SHA, etc.), as well as some compression and CRC check algorithms

* documentation/: documentation directory, no kernel code, just a set of useful documents

* drivers/: places all the device drivers in the system; each driver occupies a subdirectory: for example, / block is the block device driver, such as ide (ide.c). If you want to see how all the devices that may contain file systems are initialized, you can look at device_setup () in drivers/block/genhd.c.

* fs/: has all the file system code and various types of file manipulation code, and each of its subdirectories supports a file system, such as fat and ext2

* the include/: include subdirectory includes most of the header files needed to compile the core. Platform-independent header files are in the include/linux subdirectory, intel cpu-related header files are in the include/asm-i386 subdirectory, and the include/scsi directory is the header file directory for scsi devices

* the init/: directory contains the core initialization code (note: not the boot code of the system) and contains two files, main.c and Version.c, which is one of the good starting points for studying how the core works.

* ipc/: this directory contains the core code for interprocess communication

* the main core code of kernel/:, the files in this directory implement the kernel functions of most linux systems, of which the most important file is sched.c;, and the architecture-related code is under arch/i386/kernel

* lib/: places the core library code

* mm/: this directory includes all memory management code independent of cpu architecture, such as page storage management memory allocation and release, etc., while architecture-related memory management code is located under arch/i386/mm/

* net/: core network-related code

* scripts/: description file, script, for core configuration

* security: mainly a SELinux module

* sound: drivers for common audio devices, etc.

* usr: implements cpio for packaging and compression.

5. Five subsystems of the kernel: * process debugging (SCHED), memory management (MM), virtual file system (VFS), network interface (NET), interprocess communication (IPC).

6. Compilation of linux kernel: * configure kernel: make menuconfig, after use, generate a .confiig configuration file that records which parts are compiled into the kernel and which parts are compiled into kernel modules. * method of compiling kernels and modules: make zImage Make modules * after executing the above command, the compressed kernel image zImage is obtained in the arch/arm/boot/ directory, and the selected kernel modules are obtained in the corresponding directories of the kernel.

7. Add a program to the linux kernel (compile it directly into the kernel) to complete the following three tasks: * copy the written source code into the corresponding directory of the linux kernel source code * add the compilation configuration option for the project corresponding to the new source code in the Kconifg file of the directory * add the compilation entry for the new source code to the Makefile file of the directory

8. The characteristics of C programming under linux: Documentation/CodingStyle under the kernel describes the coding style requirements of the linux kernel. Specific requirements are not listed one by one, the following should be noted: * the application of spaces in the code * the current function name: GNU C predefines two identifiers to save the name of the current function, _ _ FUNCTION__ saves the name of the function in the source code, and _ _ PRETTY_FUNCTION__ saves the name with language characteristics. Since C99 already supports the _ _ func__ macro, you should not use _ _ FUNCTION__, in linux programming. You should use _ _ func__. * built-in functions: the naming of other built-in functions that are not part of the library function usually starts with _ _ builtin.

9, kernel module kernel module mainly consists of the following parts: (1) module loading function (2) module unloading function (3) module license statement (commonly used are Dual BSD/GPL,GPL, etc.) (4) module parameters (optional) it refers to the value that can be passed to the module when it is loaded, which corresponds to the global variables within the module. For example, an example with module parameters on page P88: insmod book.ko book_name= "GOOD BOOK" num=5000 (5) Module export symbols (optional) the exported symbols can be used by other modules and only need to be declared before use. (6) Declaration information such as module author (optional) the following is a typical kernel module:

/ * A kernel module: book * This example is to introduce module params * * The initial developer of the original code is Baohua Song *. All Rights Reserved. * / # include # include static char * book_name = "dissecting Linux Device Driver"; static int num = 4000; static int book_init (void) {printk (KERN_INFO "book name:%s\ n", book_name); printk (KERN_INFO "book num:%d\ n", num); return 0;} static void book_exit (void) {printk (KERN_INFO "Book module exit\ n") } module_init (book_init); module_exit (book_exit); module_param (num, int, S_IRUGO); module_param (book_name, charp, S_IRUGO); MODULE_AUTHOR ("Song Baohua, author@linuxdriver.cn"); MODULE_LICENSE ("Dual BSD/GPL"); MODULE_DESCRIPTION ("A simple Module for testing module params"); MODULE_VERSION ("V1.0") 12345678910111213141516171819202122324262728293031323334 Note: functions marked with init are placed in the .init.text section when linked, and a function pointer is saved in .initcall.init. During initialization, the kernel will call the init function through these function pointers, and release the init section after initialization is complete. Module compiles commonly used templates:

KVERS = $(shell uname-r) # Kernel modules obj-m + = book.o # Specify flags for the module compilation. # EXTRA_CFLAGS=-g-O0 build: kernel_modules kernel_modules: make-C / lib/modules/$ (KVERS) / build kernel $(CURDIR) modules clean: make-C / lib/modules/$ (KVERS) / build kernel $(CURDIR) clean1234567891011 note that the kernel version should be specified and matched-- the kernel version used by the compiler module should be the same as the kernel version to which the module is to be loaded. Commands that are frequently used in modules:

Insmod,lsmod,rmmod 1 system call:

Int open (const char * pathname,int flags,mode_t mode); 1flag indicates file opening flag, such as: O_RDONLY mode indicates file access permission, such as S_IRUSR (user readable), S_IRWXG (group can read, write, execute)

10. The relationship between Linux file system and device driver

The interface between the application and VFS is the system call, while the interface between the VFS and the disk file system and ordinary devices is the file_operation structure member function. Two important functions: (1) the struct file structure definition is defined in / linux/include/linux/fs.h (Linux 2.6.11 kernel). The file structure represents an open file, and each open file in the system has an associated struct file in kernel space. It is created by the kernel when the file is opened and passed to any function that operates on the file. After all instances of the file are closed, the kernel releases this data structure. In kernel creation and driver source code, the pointer to struct file is usually named file or filp. In driver development, file read / write mode mode and flag f_flags are all concerned by the device driver, while the private data pointer private_data is widely used in the driver, mostly pointing to the device driver custom structure used to describe the device. Similar code is commonly used in the driver to detect how the user opens the file to read and write:

If (file- > f_mode & FMODE_WRITE) / / user requires writable {} if (file- > f_mode & FMODE_READ) / / user requires readable {} 123456 the following code can be used to determine whether to open device files in a blocking or non-blocking manner:

If (file- > f_flags & O_NONBLOCK) / / non-blocking pr_debug ("open:non-blocking\ n"); else / / blocking pr_debug ("open:blocking\ n"); 1234 (2) struct inode structure defined in linux/fs.h

11 the relationship among devfs linux devfs, sysfs and udev: (1) there are special file systems for managing devices under devfs linux, and devfs and sysfs are two of them. Kernel 4 has been using devfs,devfs to mount in the / dev directory, providing a file-like method to manage all devices located in the / dev directory. We know that every file in the / dev directory corresponds to a device, regardless of whether the device exists or not, and these special files are located on the root file system. We have established these device files when making the file system, so we can interact with the kernel by manipulating these special files. But the devfs file system has some disadvantages, such as: uncertain device mapping, sometimes a device mapping may be different, for example, my USB disk may correspond to sda and may not have enough primary / secondary device numbers for sdb;, which will obviously become a problem when there are too many devices; / dev directory is too many files and can not represent the actual devices on the current system Naming is not flexible enough to specify arbitrarily, and so on. (2) because of the above problems, sysfs introduces a new file system sysfs after the linux2.6 kernel, which is mounted in the / sys directory. Like devfs, it is also a virtual file system and is used to manage the devices of the system. It organizes the devices and buses actually connected to the system into a hierarchical file. User-space programs can also use this information to interact with the kernel. The file system is an intuitive reflection of the actual device tree on the current system. It establishes this information through the kobject subsystem. When a kobject is created, the corresponding files and directories are created, located in the relevant directory under / sys, since each device has a unique corresponding directory in the sysfs. Then it can be read and written by user space. Udev, a tool in user space, uses the information provided by sysfs to achieve all the functions of devfs, but the difference is that udev runs in user space, while devfs runs in kernel space, and udev does not have the inherent defects of devfs.

(3) udev udev is a tool that can dynamically update device files according to the status of hardware devices in the system, including the creation and deletion of device files. Device files are usually placed in the / dev directory, and after using udev, only the real devices in the system are included under / dev. It is independent of hardware platform, located in user space, and needs the support of kernel sysfs and tmpfs. Sysfs provides device entry and uevent channel for udev, and tmpfs provides storage space for udev device files.

1210 Linux device model:

In the linux kernel, bus_type,device_driver,device is used to describe the bus, driver, and device, respectively, and these three structures are defined in the include/linux/ device.h header file. The driver and device are paired through the match () function in bus_type.

13, important structure parsing (1) cdev structure in the linux2.6 kernel, use cdev structure to describe a character device, defined as follows:

Struct cdev {struct kobject kobj;// embedded kobject object struct module * owner;// belongs to the module struct file_operations * ops;// file operation structure struct list_head list; dev_t dev;// device number, which is 32 bits long, of which the high 12 is the primary device number and the lower 20 bits are this device number unsigned int count;} 12345678 (2) the file_operations structure file_operations is defined in the header file linux/fs.h and is used to store pointers to functions provided by the driver kernel module to perform various operations on the device. These functions are actually called when the application makes linux system calls such as open (), write (), read (), close (), and so on. Each domain of the structure corresponds to the address of the function used by the driver kernel module to handle a requested transaction. The source code (2.6.28.7) is as follows:

Struct file_operations {struct module*owner; loff_t (* llseek) (struct file*,loff_t,int); ssize_t (* read) (struct file*,char__user*,size_t,loff_t*); ssize_t (* write) (struct file*,constchar__user*,size_t,loff_t*); ssize_t (* aio_read) (struct kiocb*,cons tstruct iovec*,unsigned long,loff_t) Ssize_t (* aio_write) (struct kiocb*,const struct iovec*,unsigned long,loff_t); int (* readdir) (struct file*,void*,filldir_t); unsigned int (* poll) (struct file*,struct poll_table_struct*); int (* ioctl) (struc inode*,struct file*,unsigned int,unsigned long); long (* unlocked_ioctl) (struct file*,unsigned int,unsigned long) Long (* compat_ioctl) (struct file*,unsigned int,unsigned long); int (* mmap) (struct file*,struct vm_area_struct*); int (* open) (struct inode*,struct file*); int (* flush) (struct file*,fl_owner_t id); int (* release) (struct inode*,struct file*); int (* fsync) (struct file*,struct dentry*,int datasync) Int (* aio_fsync) (struct kiocb*,int datasync); in (* fasync) (int,struct file*,int); int (* lock) (struct file*,int,struct file_lock*); ssize_t (* sendpage) (struct file*,struct page*,int,size_t,loff_t*,int); unsigned long (* get_unmapped_area) (struct file*,unsigned long,unsigned long,unsigned long,unsigned long); int (* check_flags) (int) Int (* dir_notify) (structfile*filp,unsignedlongarg); int (* flock) (structfile*,int,structfile_lock*); ssize_t (* splice_write) (struct pipe_inode_info*,struct file*,loff_t*,size_t,unsig ned int); ssize_t (* splice_read) (structfile*, loff_t*,struct pipe_inode_info*,size_t,unsigned int) Int (* setlease) (struct file*,long,struct file_lock**); 1234567891011121314151617181920212223242526272829 parsing:

Struct module*owner; / * the first file_operations member is not an operation at all; it is a pointer to the module that owns this structure. This member is used to prevent the module from being unloaded while its operation is still in use. Almost all the time, it is simply initialized to THIS_MODULE, a macro defined in. This macro is more complex, and it is generally initialized to THIS_MODULE when performing simple learning operations. * / loff_t (* llseek) (struct file*filp,loff_tp,int orig); / * (pointer parameter filp is the pointer of the target file structure for reading information; parameter p is the target offset of the file location The parameter orig is the starting address of the location of the file. This value can be used to change the current read / write position in the file by the llseek method at the beginning of the file (SEEK_SET,0, current location (SEEK_CUR,1), end of the file (SEEK_END,2)), and the new location is returned as (positive). The loff_t parameter is a "longoffset" and is at least 64 bits wide even on a 32-bit platform. The error is indicated by a negative return value. If this function pointer is a NULL,seek call, the position counter in the file structure will be modified in a potentially unpredictable way (described in the "file structure" section). * / ssize_t (* read) (struct file * filp,char__user * buffer,size_t size,loff_t * p) / * (the pointer parameter filp is the target file for reading information, the pointer parameter buffer is the corresponding buffer for placing the information (that is, the user space memory address), the parameter size is the length of the information to be read, and the parameter p is the offset of the reading position from the beginning of the file. After reading the information, the pointer generally moves, and the moving value is the length value of the information to be read.) this function is used to obtain data from the device. A null pointer at this location causes the read system call to fail with-EINVAL ("Invalidargument"). A non-negative return value represents the number of bytes successfully read (the return value is a "signedsize" type, often an integer type local to the target platform). * / ssize_t (* aio_read) (struct kiocb*,char__user * buffer,size_t size,loff_t p) / * you can see that the first and third parameters of this function are different from those of the read () function in this structure. The third parameter of asynchronous read and write passes the value directly, while the third parameter of synchronous read and write passes a pointer, because AIO never needs to change the location of the file. The first parameter of an asynchronous read and write is a pointer to the kiocb structure, while the first parameter of a synchronous read and write is a pointer to the file structure, each of which corresponds to a kiocb structure); initialize an asynchronous read-a read that may not end until the function returns. If this method is NULL, all operations will be performed by read instead (synchronously). (you can refer to the relevant information about linux Asynchronous Ibank O. The detailed answer is given in "detailed explanation of linux device driver Development") * / ssize_t (* write) (struct file*filp,const char__user * buffer,size_t count,loff_t * ppos) / * (parameter filp is the pointer to the structure of the target file, buffer is the information buffer to be written to the file, count is the length of the information to be written, and ppos is the current offset position. This value is usually used to determine whether the write file is out of bounds.) send data to the device. If NULL,-EINVAL returns to the program that calls the write system call. If non-negative, the return value represents the number of bytes successfully written. (note: both this operation and the file read operation above are blocking operations) * / ssize_t (* aio_write) (struct kiocb*,const char__user * buffer,size_t count,loff_t * ppos); / * initialize an asynchronous write on the device. The parameter type is the same as the aio_read () function; * / int (* readdir) (struct file*filp,void*,filldir_t); / * for device files, this member should be NULL;, which is used to read directories and is only useful for file systems. * / unsigned int (* poll) (struct file*,struct poll_table_struct*) / * (this is a polling function in a device driver, the first parameter is the file structure pointer and the second is the polling table pointer) this function returns the available state of the device resource, that is, the bit "OR" result of macros such as POLLIN,POLLOUT,POLLPRI,POLLERR,POLLNVAL. Each macro indicates a state of the device, such as: POLLIN (defined as 0x0001) means that the device can read without blocking, and POLLOUT (defined as 0x0004) means that the device can write without blocking. The poll method is the back end of three system calls: poll,epoll, and select, all of which are used to query whether reading or writing to one or more file descriptors is blocked. The poll method should return a bitmask indicating whether non-blocking read or write is possible and, possibly, provide the kernel with information to make the calling process sleep until it becomes possible. If a driver's poll method is NULL, the device is assumed to be readable and writable without blocking. (here, the device is usually treated as a file for related operations, and the value of the polling operation is directly related to the response of the device, which can be the result of blocking operation or non-blocking operation) * / int (* ioctl) (struct inode*inode,struct file*filp,unsigned int cmd,unsigned long arg) / * (the inode and filp pointers are the values of the file descriptor FD passed by the corresponding application, the same parameters passed to the open method. The cmd parameter is passed unchanged from the user, and the optional parameter arg is passed in the form of a unsignedlong, regardless of whether it is given by the user as an integer or a pointer. If the caller does not pass the third argument, the argon value received by the driven operation is undefined. Because type checking is turned off on this extra parameter, the compiler cannot warn you that if an invalid parameter is passed to ioctl, and any associated errors will be difficult to find.) ioctl system calls provide a way to issue device-specific commands (such as formatting a track on a floppy disk, which is neither read nor write). In addition, several ioctl commands are recognized by the kernel without referring to the fops table. If the device does not provide an ioctl method, for any undefined request (- ENOTTY, "device does not have such ioctl"), the system call returns an error. * / int (* mmap) (struct file*,struct vm_area_struct*); / * mmap is used to request that the device memory be mapped to the address space of the process. If this method is the NULL,mmap system call returns-ENODEV. (if you want to have a thorough understanding of this function, please see the book on "process address space") * / int (* open) (struct inode * inode,struct file * filp); / * (inode is a file node, there is only one node, no matter how many files the user opens, it only corresponds to an inode structure. But filp is different, as long as a file is opened, it corresponds to a file structure, which is usually used to track the status of the file at run time.) although this is often the first operation on the device file, the driver is not required to declare a corresponding method. If this item is NULL, the device opens successfully, but your driver will not be notified. Corresponding to the open () function is the release () function. * / int (* flush) (struct file*); / * the flush operation is called when the process closes the copy of its device file descriptor; it should perform (and wait for) any unfinished operations on the device. This must not be confused with the fsync operation of the user query request. Currently, flush is used in few drivers; SCSI tape drivers use it, for example, to ensure that all written data is written to tape before the device is shut down. If flush is NULL, the kernel simply ignores requests from user applications. * / int (* release) (struct inode*,struct file*) / * release () function when the last user process that opens the device executes the close () system call, the kernel will call the driver release () function: void release (struct inode inode,struct file * file). The main task of the release function is to clean up unfinished input and output operations, release resources, user-defined reset of exclusive flags, and so on. This operation is referenced when the file structure is released. Just as open,release can NULL.*/ int (* synch) (struct file*,struct dentry*,intdatasync); / / flush the data to be processed, allowing the process to flush all dirty buffers to disk. Int (* aio_fsync) (struct kiocb*,int); / * this is the asynchronous version of the fsync method. The so-called fsync method is a system call function. The system call fsync writes all dirty buffers of the file specified by the file to disk (including buffers with index nodes, if necessary). The corresponding service routine gets the address of the file object and then invokes the fsync method. Usually this method ends with a call to the function _ _ writeback_single_inode (), which writes back to disk the dirty pages associated with the selected index node and the index node itself. * / int (* fasync) (int,struct file*,int); / / this function is a device driver that supports asynchronous notification. The following is the template for this function: static int***_fasync (intfd,structfile*filp,intmode) {struct***_dev*dev=filp- > private_data; returnfasync_helper (fd,filp,mode,&dev- > async_queue); / / the fourth parameter is the pointer to the fasync_struct structure pointer. / / this function is used to handle the FASYNC flag. (FASYNC: for BSD-compatible fcntl synchronization) when this flag is changed, the fasync () function in the driver is executed. } / * this operation is used to notify the device of a change in its FASYNC flag. Asynchronous notification is a high-level topic described in Chapter 6. This member can be NULL if the driver does not support asynchronous notification. * / int (* lock) (struct file*,int,struct file_lock*); / / the lock method is used to implement file locking; locking is an essential feature for regular files, but device drivers almost never implement it. Ssize_t (* readv) (structfile*,const struct iovec*,unsigned long,loff_t*); ssize_t (* writev) (structfile*,const struct iovec*,unsigned long,loff_t*); / * these methods implement divergent / convergent read and write operations. Applications occasionally need to do a single read or write operation that contains multiple memory areas; these system calls allow them to do so without having to make additional copies of the data. If these function pointers are called for NULL,read and write methods (perhaps more than once). * / ssize_t (* sendfile) (struct file*,loff_t*,size_t,read_actor_t,void*); / * this method reads sendfile system calls, moving data from one file descriptor to another with minimal copies. For example, it is used by a web server that needs to send the contents of a file to a network connection. Device drivers often make sendfile NULL.*/ ssize_t (* sendpage) (structfile*,structpage*,int,size_t,loff_t*,int); / * sendpage is the other half of sendfile; it is called by the kernel to send data, one page at a time, to the corresponding file. The device driver does not actually implement sendpage.*/ unsignedlong (* get_unmapped_area) (struct file*,unsigned long,unsignedlong,unsigned long,unsignedlong); / * the purpose of this method is to find a suitable location in the address space of the process to map to the memory segment on the underlying device. This task is usually performed by memory management code; this method exists so that the driver can enforce any alignment requests that a particular device may have. Most drivers can set this method to NULL. [10] * / int (* check_flags) (int) / / this method allows module checks to be passed to fnctl. The flag for the call. Int (* dir_notify) (struct file*,unsigned long); / / this method is called when the application uses fcntl to request directory change notification. Only useful for the file system; the driver does not need to implement dir_notify.12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959614, the basic character device driver design major number and secondary number (both are device numbers): a character device or block device has a major number and a secondary number. The primary device number is used to identify the driver connected to the device file and to reflect the device type. The secondary number is used by the driver to identify which device is operating and to distinguish between devices of the same type. In the linux kernel, the device number is described by dev_t, which is defined in 2.6.28 as follows:

Typedef u_long dev_t;1 is 4 bytes in a 32-bit machine, with the high 12 bits representing the primary setting number and the low 12 bits representing the secondary setting number.

You can use the following macros to obtain the primary and secondary device numbers from the dev_t: you can also use the following macros to generate dev_t from the primary and secondary device numbers:

MAJOR (dev_tdev); MKDEV (intmajor,intminor); MINOR (dev_tdev); 123 assign device number (two methods): (1) static application:

Int register_chrdev_region (dev_t from,unsigned count,const char * name); 1 (2) dynamic allocation:

Int alloc_chrdev_region (dev_t * dev,unsigned baseminor,unsigned count,const char * name); 1 Log out the device number:

Void unregister_chrdev_region (dev_t from,unsigned count); 1 create device file: use cat/proc/devices to view the applied device name and device number. (1) manual creation using mknod: mknod filename type major minor (2) automatic creation; using udev (mdev) to achieve automatic creation of device files, first of all, it should be guaranteed to support udev (mdev), which is configured by busybox. Call class_create in the driver initialization code to create a class for the device, and then call device_create for each device to create the corresponding device.

15, character device driver design device registration: the registration of character devices is divided into three steps: (1) assign

Cdev:struct cdev * cdev_alloc (void); 1 (2) initialization

Cdev:void cdev_init (struct cdev * cdev,const struct file_operations * fops); 1 (3) add

The realization of cdev:int cdev_add (struct cdev * pforce devolution dev,unsigned count) 1 device operation: the realization of file_operations function set.

Struct file_operations xxx_ops= {.owner = THIS_MODULE, .llholder = xxx_llseek, .read = xxx_read, .write = xxx_write, .ioctl = xxx_ioctl, .open = xxx_open, .release = xxx_release,... 12345678910 pay special attention to the data exchange of driver applications: data exchange between drivers and applications is very important. The read () and write () functions in file_operations are used to exchange data between drivers and applications. Through data exchange, drivers and applications can learn about each other. But drivers and applications belong to different address spaces. The driver cannot directly access the address space of the application; similarly, the application cannot directly access the address space of the driver, otherwise it will destroy the data in each other's space, resulting in a system crash or data corruption. The safe way is to use the special functions provided by the kernel to exchange data between the application space and the driver space. These functions strictly check and convert the pointers passed by the user program, so as to ensure the security of exchanging data between the user program and the driver. These functions are:

Unsigned long copy_to_user (void__user * to,constvoid * from,unsigned long n); unsigned long copy_from_user (void * to,constvoid _ user * from,unsigned long n); put_user (local,user); get_user (local,user); 1234 device logout:

The void cdev_del (struct cdev * p); 116dint ioctl function indicates that ioctl is a function in the device driver to manage the device's Imax O channel. The so-called management of the Icano channel is to control some characteristics of the equipment, such as the transmission baud rate of the serial port, the speed of the motor and so on. The number of its calls is as follows:

Int ioctl (int fd,ind cmd, …) 1 where fd is the file identifier returned by the user program when opening the device using the open function, cmd is the control command of the user program to the device, and the following ellipses are some supplementary parameters, which are related to the meaning of cmd. The ioctl function is an attribute component of the file structure, that is, if your driver provides support for ioctl, the user can use the ioctl function to control the device's Imax O channel in the user program.

There is something particular about the organization of commands, because we must make sure that commands and devices correspond one to one, so that the correct commands will not be sent to the wrong devices, or the wrong commands will be sent to the right devices, or the wrong commands will be sent to the wrong devices. So this is how a command code is defined in the Linux core:

Device type serial number direction data size 8bit8bit2bit13~14bit

In this way, a command becomes a command code in the form of an integer. But the command code is very unintuitive, so LinuxKernel provides some macros that can generate command codes based on strings that are easy to understand, or get strings that users can understand from the command code to indicate the device type, device serial number, data transfer direction and data transfer size corresponding to the command. Click (here) to collapse or open

/ * used to create numbers*/ # 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 _ IOR_BAD (type,nr,size) _ IOC (_ IOC_READ, (type), (nr), sizeof (size)) # define _ IOW_BAD (type,nr,size) _ IOC (_ IOC_WRITE, (type), (nr), sizeof (size)) # define _ IOWR_BAD (type,nr) Size) _ IOC (_ IOC_READ | _ IOC_WRITE, (type), (nr), sizeof (size)) # define _ IOC (dir,type,nr,size)\ ((dir) what are the basic knowledge points of Linux system driver development? Thank you for reading! I believe that everyone has a certain understanding of "what are the basic knowledge points of Linux system-driven development". If you want to learn more knowledge, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report