Article Title: What is a module and how to write a module. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
I don't know what happened when something like module appeared in Linux. Indeed, it is a major innovation of Linux. With the module, writing the device driver is no longer a nightmare, and modifying the kernel is no longer a painful task. Because you don't need to test the driver every time and re-compile the kernel. It would be exhausting. The Module allows us to dynamically change the kernel, load the device driver, and shorten the driver development time. In this article, I will introduce the principle of the module and how to write a module.
Module translation into Chinese is a module, but in fact it is meaningless to translate this word. Before talking about the module, let me give an example. I believe many people have used RedHat. In RedHat, we can execute sndconfig to help us configure the sound card. After the configuration, if you get your sound card, your sound card will be ready for operation immediately, and you do not need to reactivate the computer. How did this happen? Module. The module is actually a general program. But it can be dynamically loaded into the kernel to become part of the kernel. The module loaded into the kernel has the same power as the kernel. You can access the data structure of any kernel. Have you heard of kdebug? It is used to debug the kernel. It first loads a module of it into the kernel, and gdb in the user space can communicate with this module to know the value of the data structure in the kernel. In addition, you can also change the data structure in the kernel through the module loaded to the kernel.
We know that when writing a C program, a program can only have one main. Kernel itself is actually a program, and it also has a main, called start_kernel (). When we load a module into the kernel, it will be integrated with the kernel to become part of the kernel. Think about it. can the module have main? The answer is obviously No. The reason is simple. A program can only have one main. When using the module, remember that the module is a passive role. It provides some functions for others to use.
There is a variable named module_list in the Kernel. every time the user loads a module into the kernel, this module will be recorded in module_list. When the kernel needs to use the function provided by the module, it will search the list, find the module, and then use the function or variable provided by the module. Each module can export some functions or variables for others to use. In addition, the module can also use the function provided by the module that has been loaded into the kernel. This situation is called module stack. For example, if module A uses module B, it is necessary to load module B before loading module. Otherwise, module A cannot be loaded. In addition to the module, the kernel itself also export some functions or variable. Similarly, the module can also use the export output by the kernel. Since we usually write user space programs, when we suddenly write a module, we will take the function used to write the program to the module for use. Something like printf. What I want to tell you is that the function or variable used by the module should be written in the module by itself, or provided by other modules, or provided by the kernel. You cannot use functions provided by libc or glibc. Something like printf. This may be something you need to be careful. (Maybe you can link it first and then load it to the kernel. I seem to have tried it, but forget it)
As we mentioned earlier, the kernel itself export some functions or variable for the module to use. However, we are not omnipotent. how do we know that there is something open in the kernel for us to use? Linux provides a command named ksyms. you only need to execute ksyms-a to know the functions or variable provided by the kernel or the module currently loaded into the kernel. The following is my system:
C0216ba0 drive_info_R744aa133
C01e4a44 boot_cpu_data_R660bd466
C01e4ac0 EISA_bus_R7413793a
C01e4ac4 MCA_bus_Rf48a2c4c
C010cc34 _ verify_write_R203afbeb
.....
In the kernel, a symbol table is used to record the function or variable of the export. In addition, the functions of the module export are recorded. In the above lines, the kernel provides the function/variable drive_info. Therefore, we can use it directly in the kernel. when it is loaded into the kernel, the link action is automatically completed. As a result, we can know that the module itself is not actually link some object code. The link will not be completed until the module is loaded with the kernel. You can see some strange strings after drive_info. _ R744aa133, which is the result of some encode based on the current kernel version. Why is this extra string required?
Linux does not know that since that version, a config option has been added, called Set version number in symbols of module. This is to avoid system instability. We know that Linux kernel is updated very quickly. In the kernel update process, sometimes some old data structures or functions are changed for efficiency, and the variable may be removed, some functions have different prototypes than the original ones. If this happens, the module of version 2.0.33 may be used to get the kernel of version 2.2.1. assume that the variable of version 2.0.33 kernel is called, however, in 2.2.1, A must be set to NULL for some reason. When this module is used on 2.2.1 kernel, if it is used directly without checking the value of A, it will cause system errors. Maybe the entire system will not die, but this module is definitely difficult to use its functions. For this reason, during the compile module in Linux, encode the number of the kernel version to each exported function and variable.
So, maybe we should not say that the kernel provides drive_info, but that the kernel provides driver_info_R744aa133 for our use. You may understand this. That is to say, kernel considers it to provide the driver_info_r744aa.pdf, instead of driver_info. Therefore, when loading a module, the system always tells you that a function cannot be resolved. This is because there is no function in the kernel, or the function used in your module is different from the result of the kernel encode. Therefore, resolve cannot be performed. The solution is to turn off the set version option in the kernel, and to convert the module compile into a type that the kernel can accept.
Some people will want to say that if the kernel determines that the function provided by it is called driver_info_R744aa133, then when we write the program, we can change the funnction to driver_info_R744aa133. The answer is Yes. However, if every function needs to be written like this, won't you be bored? For example, when writing a driver, many people will use the printk function. This is the function provided by the kernel. Its functions are similar to those of printf. The usage is almost the same. It is a good tool for debugging. If we use one hundred printks in the module, do we have to call one hundred printk_Rdd132261? Of course not. smart people will immediately think of using # define printk printk_Rdd132261. So ??? Inux helped us do this very well.
If you have enabled the set version option in your system, you can go to the/usr/src/linux/include/linux/modules Directory. There are many. ver files under this directory. These archives are actually used for # define. Let's take a look at the ksyms. ver file, which contains a line like this:
# Define printk _ set_ver (printk)
Set_ver is a macro that is used to add the version number after printk. If you are interested, you can view the macro statement on your own. Are these servers used? N, we can directly use the name printk in the module. And these ver files will automatically help us do the # define action. However, we can find that this directory has a lot of Ververs? N. Sometimes, how do we know that the function we are calling is defined in that ver file? Linux has helped us do one more thing. The/usr/src/linux/include/linux/modversions. h file has added all ver files. So we only need to include this file in our module, and the problem of the name is solved. However, here we advise you not to include the modversions. h file in the module. if you really want it, add the following lines:
# Ifdef MODVERSIONS
# Include
# Endif
The reason for adding these three lines is to prevent the module from include the file modversions. h on a system without setting the kernel version. You can try it out. when you turn off the set version option, the modversions. h and modules directories will not be seen. Without the above three lines, compile will not pass. Therefore, we generally choose to pass modversions. h to gcc during compile. As shown in the following figure.
Gcc-c-d1_kernel _-DMODULE-DMODVERSIONS main. c \
-Include usr/src/linux/include/linux/modversions. h
In this command line, we can see-d1_kernel __, which means to define the constant of _ KERNEL. Many header files related to the kernel must be defined to include this constant. So we recommend that you define it. There is also a-DMODVERSIONS. I forgot to talk about this constant. We just mentioned that the solution to fucntion or variable name encode is to include modversions. h. In addition, you must also define the MODVERSIONS constant. Then the constant MODULE is used. In fact, as long as you want to write a module, you must define this variable. You also need to include the module. h file, because _ set_ver is defined here.
At this point, I believe you should have some knowledge about the module. in the future, you will not be confused about the module unresolved. you should also have a solution.
What I just talked about is the name encode problem encountered on using others' functions. However, if our module wants
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.