“Since the module is not linked to any of the standard libraries, the source code of the module should not include regular header files. In kernel modules, only those functions that are exported by the kernel can be used. All header files that are related to the kernel are located in the include / linux and include / asm directories, inside the directory tree with the kernel sources (usually, this is the / usr / src / linux directory).
Early versions of Linux (based on libc version 5 and earlier) installed symbolic links from / usr / include / linux and / usr / include / asm to the actual directories from the kernel sources, so the libc header file tree could refer to the kernel header files . This made it possible to include the kernel header files in user applications when the need arose.
But even now, when the kernel header files are separated from the header files used by application programs, it is still sometimes necessary to include them in programs running in user space in order to use definitions that are not found in regular header files. However, most of the definitions from the kernel header files belong exclusively to the kernel and are “invisible” for normal applications, since access to these definitions is enclosed in #ifdef __KERNEL__ blocks. By the way, this is one of the reasons why it is necessary to define the __KERNEL__ symbol when building a module. ”
“The printk function is defined in the kernel and in its behavior resembles the printf function from the standard C library. Why then does the kernel have its own function? Everything is simple - the core is an independent code that is compiled without auxiliary libraries of the C language. "
"Device Drivers in Linux" says:
“The application is performed as an integral task, from beginning to end. The module simply registers itself in the kernel, preparing it for servicing possible requests, and its main function completes its work immediately after the call. In other words, the task of the init_module function (entry point) is to prepare the functions of the module for subsequent calls. She seems to say to the nucleus: “Hey! I'm here! Here is what I can do! “. The second entry point to the module, cleanup_module, is called immediately before the module is unloaded. She tells the core: “I'm leaving! Don't ask me about anything else! “. „
"Device Drivers in Linux" says:
"<...> The kernel code can determine the current process accessing the module through the global current element — a pointer to the struct task_struct , which is declared in the 2.4 kernel in the <asm / current.h> file. The current pointer refers to the current user process. In the process of making system calls, such as read or write , the process making the call is considered current. The kernel can use information about the current process using the current pointer if the need arises. <...>
In fact, current is no longer a global kernel variable, as it was before. The developers have optimized access to the structure that describes the current process, moving it onto the stack. You will find the implementation of current in the <asm / current.h> file. But before you go exploring this file, you must remember that Linux is an SMP-compatible system (from the English. SMP - Symmetric Multi-Processing) and therefore a simple global variable is simply not applicable here. Implementation details are in other kernel subsystems and yet, the device driver can plug in the header file <linux / sched.h> and access the current pointer.
From the point of view of the module, current is a regular external link, such as printk . A module can access current whenever it deems necessary. For example, the following code displays the identifier (ID) of the process and the name of the command that launched the process:
printk ("The process is \"% s \ "(pid% i) \ n", current-> comm, current-> pid);
The command name is stored in the field current-> comm and is the name of the program file.
Source: https://habr.com/ru/post/233503/
All Articles