Comparison between kernel modules and User Programs
Source: Internet
Author: User
Comparison between kernel modules and user programs-Linux general technology-Linux programming and kernel information. The following is a detailed description. 3.1.1. How does the kernel module start and end?
User Programs generally start from the main () function and execute a series of commands and end the program after the command execution is complete. The kernel modules are a little different. The kernel module either starts from the init_module function or the function call specified by the macro module_init. This is the entry function of the kernel module. It tells the kernel module to provide functional extensions and prepare the kernel to call it as needed. After this is done, the function execution is complete. The module does nothing before being called by the kernel.
All modules can either call cleanup_module or use the function specified by the macro module_exit. This is the exit function of the module. It revokes everything done by the entry function. For example, you can deregister the function registered by the entry function.
All modules must have entry functions and exit functions. Since we have more than one way to define these two functions, I will try to describe them using the "entry function" and "exit function. But when I only use init_module and cleanup_module, I want you to understand what I mean.
3.1.2. Module callable Functions
Programmers do not always write all the functions they use. A common basic example is printf (). You use these C Standard libraries, library functions provided by libc. These functions (like printf () do not actually enter your program before the connection. During the connection, these function calls will point to the library you are calling, so that your code can finally be executed.
The kernel modules are different. In the hello world module, you may have noticed that the printk () function we use does not contain the standard I/O library. This is because the module is connected to the target file only when the insmod is loaded. The symbolic links of the functions to be used are provided by the kernel itself. That is to say, the functions you can use in the kernel module only come from the kernel itself. If you are interested in the function symbolic links provided by the kernel, take a look at the file/proc/kallsyms.
Note the differences between database functions and system calls. Library functions are high-level and fully run in the user space, providing programmers with more convenient interfaces for calling systems that actually complete real transactions behind the scenes. System calls run in kernel mode and are provided by the kernel itself. The standard C library function printf () can be considered as a general output statement, but what it actually does is to convert the data into a formatted string and call the system to call write () output these strings.
Do you want to see which system calls are used by printf? This is easy to compile the following code.
# Include
Int main (void)
{Printf ("hello"); return 0 ;}
Use the command gcc-Wall-o hello. c to compile. Run the strace hello command to execute the executable file. Are you surprised? Each line corresponds to a system call. Strace [3] is a very useful program that tells you which system calls are used by the program and the parameters and return values of these system calls. This is a very valuable tool for viewing what the program is doing. At the end of the output, you should see a similar line of write (1, "hello", 5 hello ). This is what we are looking. Hidden in the real face of the mask printf. Since most people use library functions to operate on file I/O (such as fopen, fputs, and fclose ). You can view the second part of man's description using the command man 2 write .. The second part of man's description specifically describes system calls (such as kill () and read ()). The third part of man's description specifically describes library functions that you may be more familiar with (such as cosh () and random ()).
You can even write code to overwrite system calls, as we will soon do. Hackers often do this to install backdoors or Trojans for the system. But you can use it to do something more useful, like letting the kernel output "Tee hee, that tickles!" every time someone deletes a file !" .
3.1.3. user space and kernel space
The kernel is solely responsible for accessing hardware resources, regardless of whether the access is a display card, hard disk, or memory. User programs often compete for these resources. Just as I am saving this document and the local database is updating. The vim Process in my editor and the database update process both require access to the hard disk. The kernel must make these requests in an orderly manner, rather than providing computer resources as the user wishes. To facilitate this mechanism, the CPU can run in different States. Different States give you different freedom to operate the system. Intel 80836 architecture has four statuses. Unix only uses two of them, the highest level of State (operation status 0, that is, "super state", can execute any operation) and the lowest level (that is, "user status ").
Recall the following discussion of library functions and system calls. Common Library functions are executed in user State. Library functions call one or several system calls, and these system calls complete the work for library functions, but in the super state. Once the system call is completed, the system call will return the user State and the program will return the user State.
3.1.4. namespace
If you just write some short C Programs, you can give your variables a convenient and easy-to-understand variable name. However, if the code you write is only part of the code written by many others, some of your global code will conflict with the global variables in it. Another case is that a program has too many variable names that are hard to understand, which may cause variable namespaces to be contaminated in large projects. You must remember the reserved variable names, or use a unified method for unique naming.
When writing kernel code, even the smallest module connects to the entire kernel, which is indeed a headache. The best solution is to declare your variable as static and use a well-defined prefix for your symbol. Traditionally, the kernel prefix of lowercase letters is used. If you do not want to declare everything as static, another option is to declare a symbol table and register it with the kernel. We will discuss it later.
The file/proc/kallsyms stores all the symbols known to the kernel and you can access them because they are part of the kernel code space.
3.1.5. Code Space
Memory Management is a very complex topic. O 'Reilly's "Understanding The Linux Kernel" is mostly discussing memory management! We are not prepared to focus on memory management, but we still need to know something.
If you have not carefully considered what memory design flaws mean, you may be surprised to know that a pointer does not point to a specific memory area. When a process is created, the kernel allocates a portion of the actual memory space for it and delivers it to the process, stack and other computer science experts can understand how to use [4]. The memory starts from $0 $ and can be extended to the desired place. These memory spaces do not overlap, so even if the process accesses the same memory address, such as 0xbffff978, the actual physical memory address is actually different. A process actually points to a memory area at the offset of 0xbffff978 In the allocated memory. In most cases, a process like a normal "Hello, World" cannot access the memory space of other processes, even though there are methods to implement this mechanism. We will discuss it later.
The kernel also has memory space. Since a kernel module can be dynamically loaded and detached from the kernel, it actually shares the memory space of the kernel rather than having independent memory space. Therefore, once your module has a memory design defect, the kernel is a memory design defect. If you overwrite data by mistake, then you are destroying the kernel code. This is worse than it sounds. So proceed with caution.
By the way, the operating system I mentioned above is true for any single kernel [5]. There are also modular micro-kernel operating systems, such as GNU Hurd and QNX Neutrino.
3.1.6. Device Drivers
A kernel module is a device driver that is written to use hardware devices such as video cards and serial ports. In Unix, any device is processed as a device file in the path/dev, and the hardware access method is provided through these device files. The device driver allows the user program to access the hardware device. For example, the sound card device driver es1370.o will associate the device file/dev/sound with the sound card hardware Ensoniq IS1370. In this way, user programs like mp3blster can run by accessing the device file/dev/sound without having to know that the sound card hardware is installed on the system.
3.1.6.1. Major and Minor Numbers
Let's look at several device files. Several device files represent the first three partitions on a primary IDE Hard Disk:
Note the two columns separated by commas. The first digit is called the master device number, and the second digit is called the slave device number. The master device number determines the device driver used. Different devices are assigned different master device numbers. All device files with the same master device number are controlled by the same driver. In the above example, the master device numbers are all 3, indicating that they are all controlled by the same driver.
The device number is used to differentiate multiple devices controlled by the driver. The slave device numbers in the preceding example are different because they are identified as several devices.
Devices are divided into two categories: character devices and Block devices. The difference is that block devices have buffer zones, so they can optimize the sorting of requests. This is especially important for storage devices, Because reading and writing adjacent files is faster than reading and writing files that are far away from each other. The other difference is that the input and output of Block devices are in the unit of data blocks, but character devices can read and write arbitrary bytes. Most hardware devices are character devices, because they do not need a buffer and data is not transmitted by block. You can use the command ls-l to output the first letter to identify the device type. If 'B' is a block device, or 'C' is a character device. What you see above is a block device. Here are some character device files (Serial Port ):
If you want to see which device the assigned master device number is, check the file/usr/src/linux/Documentation/devices.txt.
During system installation, all these device files are created by the command mknod. Create a new device file named coffee, with the master device number 12 and the slave device Number 2, as long as you simply execute the command mknod/dev/coffee c 12 2. You do not have to put the device files in the/dev directory. This is just a tradition. Linus himself does this, so you 'd better be no exception. However, when you test a module, it is good to create a device file in the working directory. You only need to ensure that it is placed in the location found by the driver.
I would also like to declare the points implied in the above discussion. When the system accesses a system file, the system kernel only uses the master device number to differentiate the device type and decide which kernel module to use. The system kernel does not need to know the slave device number. Kernel module drivers focus on device numbers and use them to differentiate different devices they manipulate.
In addition, the hardware I mentioned here is a little more abstract than the PCIe card that can be held in my hand. View the following two device files:
Now you understand immediately that this is the device file of the fast device and they are operated by the same driver kernel module (the master device number is 2 )). You may also realize that they are all your floppy drive, even if you actually only have one floppy drive. Why are two device files? Because one of them represents your 1.44 MB volume drive, and the other represents your 1.68 MB volume, which is called a "Super formatted" drive by some people. This is an example where different slave device numbers represent the same hardware device. Please be aware that the hardware we mentioned may sometimes be very abstract.
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.