Linux character devices are placed in the "/dev" directory. Character devices refer to devices that can only be read and written byte by byte. Generally, each character device or block device will correspond to a device file in the "/dev" directory, and each device file must have a main/ Devices with the same minor device number and major device number are similar devices and use the same driver.
#The operating environment of this tutorial: linux7.3 system, Dell G3 computer.
The Linux system divides devices into three categories: Character devices, block devices, and network Device , among these three categories, character devices are relatively simple. Applications access character devices through character device files. This lecture mainly introduces character devices. If you are interested in block devices and network devices, you can refer to the related information and gain an in-depth understanding of it.
Character device refers to a device that can only read and write byte by byte. Certain data in the device cannot be read randomly, and data must be read in order. Character devices are stream-oriented devices. Common character devices include mice, keyboards, serial ports, consoles, and LEDs.
Generally, each character device or block device will correspond to a device file in the /dev directory, and each device file must have a main/ Devices with the same minor device number and major device number are similar devices and use the same driver.
Linux user-level programs use drivers to operate character devices or block devices through device files.
You can use the
cat /proc/devices
command to view the major device number of the currently loaded device driver.
You can see the major and minor device numbers of all device files by executing the command
ls -l
in the /dev directory:
The common device files are explained as follows:
/dev/hd[a-t]:IDE设备 /dev/sd[a-z]:SCSI设备 /dev/fd[0-7]:标准软驱 /dev/md[0-31]:软raid设备 /dev/loop[0-7]:本地回环设备 /dev/mem:内存 /dev/null:无限数据接收设备,相当于黑洞 /dev/zero:无限零资源 /dev/tty[0-63]:虚拟终端 /dev/ttyS[0-3]:串口 /dev/lp[0-3]:并口 /dev/console:控制台 /dev/fb[0-31]:framebuffer /dev/cdrom => /dev/hdc /dev/modem => /dev/ttyS[0-9] /dev/pilot => /dev/ttyS[0-9]
There are two ways to create a device file. One is through the system call mknod(). Calling this function in programming can create a new device file name. The other is through the mknod command. The first one of the command The parameter is the device file name, the second parameter is the device type, for example, c represents a character device, and the third and fourth parameters are the major device number and minor device number of the device file, such as 231 and 0. The combination of the major device number and the minor device number uniquely determines a device. The major device numbers of different types of the same device are the same, but the minor device numbers are different. For example, multiple partitions of a hard disk have different minor device numbers. The device number can associate the device file with the driver.
mknod filename type major minor
struct cdev { struct kobject kobj; // 内嵌内核对象 struct module *owner; //该字符设备所在的内核模块 const struct file_operations *ops; //文件操作结构体 struct list_head list; //已注册字符设备链表 dev_t dev; //由主、次设备号构成的设备号 unsigned int count;//同一主设备号的次设备号的个数 };
struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); };
As shown in the figure, in the Linux kernel, on the far left, the cdev structure is used to describe the character device; its member dev_t is used to define the device number (divided into major and minor device numbers) to determine the uniqueness of the character device; through its member dev_t The member file_operations defines the interface functions provided by the character device driver to the virtual file system VFS, such as the common open(), read(), write(), etc. These functions actually operate the hardware device.
Let’s look at this picture based on the previous picture. The character device driver is loaded into the kernel in the form of a kernel module. First, the module loading function presses static or Dynamic method Get the device number ; then the character device initialization function establishes the connection between cdev and file_operations, and adds it to the system through registration function A cdev to complete the registration; when the module is unloaded, corresponding to the loading, the cdev needs to be logged out and the device number is released.
In the user program, these functions implemented by the driver in the kernel can be called through system calls such as open(), read(), write(), etc. In this way, the path between user mode and kernel driver is opened.6.1 Application and release of device number
A character device or block device has a major device number and A minor device number.The major device number is used to identify the driver connected to the device file and is used to reflect the device type. The secondary device number is used by the driver to identify which device is being operated and to distinguish devices of the same type . Apply for a device number when registering, and release the device number when logging out. Just like everyone has a student ID when they enroll, and this student ID is released when they graduate and leave.
6.2 Transmission of user space and kernel space data
When we When the read() function is called in the user program, it falls into the kernel space. In fact, the data in the kernel space buffer must be copied to the user space buffer through the kernel's copy_to_user() function. On the contrary, when we call the write() function When, the kernel copies the user space data to the kernel buffer by calling the copy_from_user() function. Related recommendations: "Linux Video Tutorial"
The above is the detailed content of Where is the linux character device placed?. For more information, please follow other related articles on the PHP Chinese website!