Getting started learning device drivers

1.What categories does Linux divide devices into?

Insert image description here
Insert image description here

2. Device driver hierarchy

Insert image description here
Insert image description here

3. The process of user process requesting device services

Insert image description here

4. Every bit of driving

What is a driver?

(1) The driver is the bridge between software and hardware.
(2) Drivers are special programs added to the operating system.
(3) A driver is a special program that enables a computer and a device to communicate.

Why do you need a driver?

(1) The software system cannot directly identify the device to be connected and what functions it has.
(2) Hardware devices can only understand electronic signals and cannot directly understand commands issued by the software system.

Who made the driver?

​ Drivers are configuration files written by hardware manufacturers based on the operating system.

The role of driver

​ Driver is the bridge between software and hardware

​ (1) Inform the operating system of the functions of the hardware itself, and complete the mutual translation between the electronic signals of the hardware device and the high-level programming language (java, etc.) of the operating system and software.
(2) Convey the standard instructions of the operating system to the hardware device
(3) When the operating system needs to use certain hardware, such as letting the sound card play music, it will first send the corresponding instructions to the sound card driver, and the sound card driver receives After that, it is immediately translated into electronic signal commands that can only be understood by the sound card, thereby allowing the sound card to play music.

5.What is the function of the file_operations() structure?

The file_operations structure completes device reading, writing, saving, etc. These operations are all handled by these function pointers stored in the file_operations structure. The functions pointed to by these function pointers need to be implemented in the driver module. .

struct file_operations {
	struct module *owner;    //拥有该结构的模块的指针,一般为THIS_MODULES
	......
	int (*mmap) (struct file *, struct vm_area_struct *);    //用于请求将设备内存映射到进程地址空间
	......
	int (*open) (struct inode *, struct file *);    //打开
	......
}

6.What role does the device number play in the driver? Why do we need a major device number and a minor device number?

Each file is a device, and the device number is composed of a major device number and a minor device number.

Major device number:

  1. It is generally believed that a major device number corresponds to a driver
  2. One driver can manage multiple devices, that is, one major device number corresponds to multiple devices
  3. One major device number can also correspond to multiple drivers

Minor device number:

  1. A minor device number corresponds to a device

A driver can manage multiple devices of this type, and the number of devices can be 2 to the 20th power. The reason is that the minor device number has 20 digits, but it is impossible to actually have so many devices.

7. What are the driver registration and unregistration functions of character devices? Why do you need to register and cancel?

Registered functions for character device drivers:

static inline int register_chrdev(unsigned int major, const char *name,
				  const struct file_operations *fops)
{
	return __register_chrdev(major, 0, 256, name, fops);
}
/*__register_chrdev() - 创建并注册一个占有较小大小的字符设备
  major:主设备号,当用户设置为0时,内核会动态分配一个设备号。
  baseminor: 次设备号,要在一定范围内从0开始
  count: 次设备号的范围
  name: 设备名称
  fops: 文件系统的接口指针
  
  如果major == 0,此函数将动态分配一个major并返回它的编号。
  如果major > 0,此函数将尝试使用给定的主设备号来保留设备,成功时将返回0。
  
  失败时返回-ve errno。
*/
int __register_chrdev(unsigned int major, unsigned int baseminor,
		      unsigned int count, const char *name,
		      const struct file_operations *fops)
{
	struct char_device_struct *cd;
	struct cdev *cdev;
	int err = -ENOMEM;

	cd = __register_chrdev_region(major, baseminor, count, name);	//注册一个主设备号和一个一定范围内具体的次设备号
	if (IS_ERR(cd))
		return PTR_ERR(cd);

	cdev = cdev_alloc();	//分配空间
	if (!cdev)
		goto out2;
	//对cdev进行赋值操作
	cdev->owner = fops->owner;
	cdev->ops = fops;
	kobject_set_name(&cdev->kobj, "%s", name);

	err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);	//把这个设备添加到系统中
	if (err)
		goto out;

	cd->cdev = cdev;	//完成cd与cdev的关联

	return major ? 0 : cd->major;
out:
	kobject_put(&cdev->kobj);
out2:
	kfree(__unregister_chrdev_region(cd->major, baseminor, count));
	return err;
}

Unregister function for character device driver:

static inline void unregister_chrdev(unsigned int major, const char *name)
{
	__unregister_chrdev(major, 0, 256, name);
}
void __unregister_chrdev(unsigned int major, unsigned int baseminor,
			 unsigned int count, const char *name)
{
	struct char_device_struct *cd;

	cd = __unregister_chrdev_region(major, baseminor, count);
	if (cd && cd->cdev)
		cdev_del(cd->cdev);
	kfree(cd);
}

Registration is to generate the corresponding device driver for use

Logging off is to free up memory so that other processes can run.

8.I/O ports and I/O memory

When located in I/O space, often referred to as an I/O port

When located in memory space, the corresponding memory space is called I/O memory

Insert image description here

9. Read and write the global memory in the character device in the user program

Insert image description here

10. Register block device driver

Insert image description here

11. The difference between block devices and character devices

Insert image description here

(1) The file system can be mounted on block devices, but not on character devices. Obviously this is an advantage brought by random access, because the file system needs to be able to store data in blocks, and it also needs to be able to read and write data randomly.

(2) Data passing through a block device needs to go through a data buffer layer compared to operating a character device. That is to say, when the application transfers data to a block device, it does not directly interact with the character device, but must go through an intermediate buffer layer to store the data. Only then can the data be used, in order to improve overall system performance (throughput).

(3) The interface of the character driver is relatively clear and easy to use, but the interface of the block driver is slightly more complicated. There are two reasons for this: one is because of its history - the block driver interface has been in every version of Linux since the first version and has proven difficult to modify or improve; Performance, a slow character device driver is undesirable but still acceptable, but a slow block driver will affect overall system performance. Therefore, the interface design of a block driver is often influenced by speed requirements.

Guess you like

Origin blog.csdn.net/qq_58538265/article/details/133916635