Wei Dongshan uboot_kernel_root file system study notes 5.1~5.3-chapter 005_character device driver_section 001~003_character device driver concept introduction/character device driver LED driver_write and compile

A driver concept introduction

Insert picture description here
Insert picture description here

  1. Execute swi+XXXassembly instructions to trigger the kernel's exception handling interrupt.
  2. System Call Interface calls different processing functions according to the interrupt source. eg:open->swi value1/read->swi value2/write->swi value3. Call sys_read/sys_open/sys_write according to the different values ​​(value1/value2/value3) passed in.
  3. These functions sys_read/sys_open/sys_write belong to the Virtual File System (VFS).

As a kernel subsystem, VFS provides file system-related interfaces for user space programs. All actual file systems rely on the VFS to coexist and work on the VFS system.
1. VFS provides a common file system interface: user space programs can use standard UNIX file system calls, such as open()\read()\write(), to operate on different file systems on different physical media.
2. VFS provides a file system abstraction layer: VFS provides a general file system model, which includes all common functions and behaviors of actual file systems. The VFS abstraction layer defines the basic and conceptual interfaces and data structures supported by all actual file systems, so VFS can connect to various actual file systems.

  1. For the same open function, the following two behaviors are obviously different. Who will implement the different behaviors? VFS finds corresponding different drivers according to different opened files, and calls open/read/write functions in different drivers.
    Insert picture description here
    Open the device property is c (character device), find the major device numbermajor

LED driver of two character device driver_write compile

  1. Regarding the major device number, the major
    device files are usually in the /dev directory. Check the devices loaded on the ubuntu virtual machine:
    Insert picture description here
    Insert picture description here

c: character device;
-: regular file
d: directory
10: major device number, major
175: minor device number, minor

  1. Regarding the main device number and the role of the register_chrdev function: the
    application program finds the specific driver corresponding to the main device number file_operations. In performing register_chrdevthe time function to the kernel driver in a linked list corresponding to majorthe index to find a last location, the structure file_operations drivers need to mount a filling inside.
major = register_chrdev(0, "hello", &hello_drv); /* /dev/hello,其中0表示主设备号,hello表示驱动程序名字,hello_drv为file_operations结构体*/

Insert picture description here

  1. Summary process: the connection between the driver and the application
    (1) the driver side
    Insert picture description here
    (2) from the application side
    Insert picture description here

  2. Makefile analysis

(1) The makefile source code is as follows:

KERN_DIR = /work/system/linux-2.6.22.6

all:
	make -C $(KERN_DIR) M=`pwd` modules 			//-C表示进入某个目录

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= myleds.o

(2) Makefile analysis

obj-m += module_test.o  

It means to compile our module_test.o into a module.

make -C $(KERN_DIR) M=`pwd` modules  

-C $(KERN_DIR): The parameter specifies the kernel source tree directory. When the make command is executed, it will jump to this directory and execute it instead of executing make in the current directory. This is why when you run the module on ubuntu and the development board, The reason for KERN_DIR is different.

M= pwd: "` "here is not only a quotation mark, but a single back quotation mark, used to specify the return directory after the make command is executed, that is, the current directory.

Modules is a target, so this statement is connected as follows: Jump to the specified directory to execute make modules, after the execution, return to the current directory, and copy the compiled modules to the current directory; so you can see modules It must be a target in the Makefile under the kernel source tree. This target defines the compilation rules of the kernel module, so modules must not be changed randomly, so we know that our Makefile here is just an entry point, the real module compilation work It is done in the Makefile under the kernel source tree, so we need to specify an entry address (that is, the path of the kernel source tree) to our make manager in this Makefile.

.PHONY:clean

Declaring that the clean target is a pseudo-target is the same as the last sentence, except that the defined target is different.

Summary: The makefile of the module is very simple. It does not compile the module itself. Instead, it enters the kernel source tree through make -C and borrows the kernel source code system to complete the compilation and linking of the module. This Makefile itself is very modular. Parts 3 and 4 will never be moved, only 1 and 2 need to be moved. 1 is the directory of the kernel source tree. You must modify the path according to your own compilation environment.

LED driver for three-character device driver_test improvement

  1. Record an error
    (1) The executable program compiled by ubuntu is executed on the arm development board and the following error is reported.
    Insert picture description here
    (2) After searching on the Internet, it is found that the compilation instruction error
    is due to the compilation instruction error when I wrote a simple makefile. When writing the compilation command, it was written as:
$(CC) -o $(OUT_FILE) -c $(SRC_FILE)

In fact, the -c option should be removed and compiled directly into an executable file:

$(CC) -o $(OUT_FILE) $(SRC_FILE)

The -c option of gcc means:

-c only activates preprocessing, compilation, and assembly, that is, he only makes programs into obj files. Example usage: gcc -c hello.c. He will generate the .o obj file

That is, if you don't add -c, the executable file will be compiled directly by default. If you add -c, it
will only compile into the target obj file, and you will not continue to compile into the executable file.
See the blog post for details:

https://www.cnblogs.com/cainiaoaixuexi/p/3890453.html

  1. Explanation of register_chrdev function After
    the register_chrdevfunction is executed in the driver , check the /proc/devices file (execution instruction cat /proc/devices)

/proc/devices file: This file lists the major device numbers of the character and block devices that Linux has loaded, and the device names assigned to these device numbers.
lsmod (list modules) command: List all modules loaded into the system.
/dev directory: This directory contains all the external devices used in the Linux system.

  1. Automatically create device nodes
    (1) the simplest driver framework
    Insert picture description here

Manually create device node command syntax by major device number:

 mknod /dev/??? 设备类型 主设备号 次设备号
 eg:mknod /dev/xxx c 252 0

Corresponding to the syntax when operating this device on the app side:

fd = open("/dev/xxx", O_RDWR);

It is tedious to manually create a device node when loading the driver, so how to automatically create a device node?
(2) Automatic creation of device nodes
There is a "udev" mechanism in the application, which is mdev for busybox. Create the device node that is the /dev/xxx file by reading the kernel information (refer to the busybox-1.7.0/doc/mdev.txt file for usage).
a. What is the system information?
The driver needs to generate corresponding information in the /sys/module directory and provide it to mdev!

/sys directory analysis: Sysfs file system is a special file system similar to the proc file system, used to organize the devices in the system into a hierarchical structure and provide detailed kernel data structure information to user-mode programs. In fact, in the user mode, you can view some drivers or devices in the kernel mode by accessing the sys file system.
Insert picture description here

Analysis of the /sys/devices directory: Under this directory is the global device structure system, including all discovered physical devices registered on various buses. Generally speaking, all physical devices are displayed according to their topology on the bus. /sys/devices is the hierarchical expression model of all devices in the system by the kernel, and it is also the most important directory structure for the /sys file system to manage devices. why? Because other directories are basically classified and organized linked files, they actually point to the contents of the directory.
Insert picture description here

Analysis of the /sys/module directory: This directory contains all the module information in the system. Regardless of whether these modules are compiled into the kernel image file inlined or compiled into an external module (.ko file), they may appear in / sys/module. That is, the module directory contains all the modules loaded into the kernel.
Insert picture description here

Analysis of the /sys/class directory: This directory contains all the device types registered in the kernel. This is a device model classified according to device functions. Each device type represents a device with one function. Each device type subdirectory contains symbolic links to various specific devices of this type, and these links point to specific devices under /sys/devices/name. There is no one-to-one correspondence between device types and devices. A physical device may have multiple device types; a device type only expresses a device with one function, for example: all input devices in the system will appear in /sys/class/input No matter what bus they are connected to the system. (/sys/class is also part of the linux unified device model)
Insert picture description here

Insert picture description here

How to provide?

firstdrv_class = class_create(THIS_MODULE, "firstdrv");//在sys目录下创建firstdrv设备类目录:/sys/module/firstdrv

Insert picture description here
Insert picture description here

How to create a device node based on the above information? That is to replace the mknodinstruction.

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); //在dev目录下创建xyz目录:/dev/xyz
//firstdrv_class:创建设备所属的类
//NULL:该设备的父设备,如果没有就指定为NULL
//MKDEV(major, 0):主设备号
//NULL:从设备号
//"xyz":设备名称

In the figure below: Major device number: 252/Minor device number: 0/c: character device
Insert picture description here

Insert picture description here

  1. Why does mdev automatically recognize the information in the /sys directory when the driver is automatically loaded?
    Because when the root file system is created, the script file /etc/init.d/rcS is shown in the following figure. Once a device is loaded or unloaded,...don’t understand
    Insert picture description here

  2. Automatically load the app program corresponding to the device node

The driver mentioned above, the following code creates the /dev/xyz directory, the application can use it directly fd = open("/dev/xyz", O_RDWR);without ignoring its major device number and call the driver.

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); //在dev目录下创建xyz目录:/dev/xyz

Guess you like

Origin blog.csdn.net/xiaoaojianghu09/article/details/104228404