You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: lkmpg.tex
+34-32Lines changed: 34 additions & 32 deletions
Original file line number
Diff line number
Diff line change
@@ -88,6 +88,7 @@ \subsection{Authorship}
88
88
Bob Mottram contributed to the guide by updating examples for Linux v3.8 and later.
89
89
Jim Huang then undertook the task of updating the guide for recent Linux versions (v5.0 and beyond),
90
90
along with revising the LaTeX document.
91
+
The guide continues to be maintained for compatibility with modern kernels (v6.x series) while ensuring examples work with older LTS kernels.
91
92
92
93
\subsection{Acknowledgements}
93
94
\label{sec:acknowledgements}
@@ -103,7 +104,7 @@ \subsection{What Is A Kernel Module?}
103
104
104
105
Involvement in the development of Linux kernel modules requires a foundation in the C programming language and a track record of creating conventional programs intended for process execution.
105
106
This pursuit delves into a domain where an unregulated pointer, if disregarded,
106
-
may potentially trigger the total elimination of an entire file system,
107
+
may potentially trigger the total elimination of an entire filesystem,
107
108
resulting in a scenario that necessitates a complete system reboot.
108
109
109
110
A Linux kernel module is precisely defined as a code segment capable of dynamic loading and unloading within the kernel as needed.
If there is no \verb|PWD := $(CURDIR)| statement in Makefile, then it may not compile correctly with \verb|sudo make|.
277
-
Because some environment variables are specified by the security policy, they can't be inherited.
277
+
If there is no \verb|PWD := $(CURDIR)| statement in the Makefile, then it may not compile correctly with \verb|sudo make|.
278
+
This is because some environment variables are specified by the security policy and cannot be inherited.
278
279
The default security policy is \verb|sudoers|.
279
280
In the \verb|sudoers| security policy, \verb|env_reset| is enabled by default, which restricts environment variables.
280
-
Specifically, path variables are not retained from the user environment, they are set to default values (For more information see: \href{https://www.sudo.ws/docs/man/sudoers.man/}{sudoers manual}).
281
+
Specifically, path variables are not retained from the user environment; they are set to default values (for more information see: \href{https://www.sudo.ws/docs/man/sudoers.man/}{sudoers manual}).
Another thing which may not be immediately obvious to anyone getting started with kernel programming is that indentation within your code should be using\textbf{tabs} and \textbf{not spaces}.
418
+
Another thing that may not be immediately obvious to anyone getting started with kernel programming is that indentation within your code should use\textbf{tabs} and \textbf{not spaces}.
418
419
It is one of the coding conventions of the kernel.
419
-
You may not like it, but you'll need to get used to it if you ever submit a patch upstream.
420
+
You may not like it, but you will need to get used to it if you ever submit a patch upstream.
420
421
421
422
\item Introducing print macros.
422
423
\label{sec:printk}
@@ -447,7 +448,7 @@ \subsection{Hello and Goodbye}
447
448
\label{hello_n_goodbye}
448
449
In early kernel versions you had to use the \cpp|init_module| and \cpp|cleanup_module| functions, as in the first hello world example, but these days you can name those anything you want by using the \cpp|module_init| and \cpp|module_exit| macros.
449
450
These macros are defined in \src{include/linux/module.h}.
450
-
The only requirement is that your init and cleanup functions must be defined before calling those macros, otherwise you'll get compilation errors.
451
+
The only requirement is that your init and cleanup functions must be defined before calling those macros, otherwise you will get compilation errors.
451
452
Here is an example of this technique:
452
453
453
454
\samplec{examples/hello-2.c}
@@ -471,7 +472,7 @@ \subsection{Hello and Goodbye}
471
472
As you can see, some things got hardwired into the kernel (\verb|obj-y|) but where have all those \verb|obj-m| gone?
472
473
Those familiar with shell scripts will easily be able to spot them.
473
474
For those who are not, the \verb|obj-$(CONFIG_FOO)| entries you see everywhere expand into \verb|obj-y| or \verb|obj-m|, depending on whether the \verb|CONFIG_FOO| variable has been set to \verb|y| or \verb|m|.
474
-
While we are at it, those were exactly the kind of variables that you have set in the \verb|.config| file in the top-level directory of Linux kernel source tree, the last time when you said\sh|make menuconfig| or something like that.
475
+
While we are at it, those were exactly the kind of variables that you have set in the \verb|.config| file in the top-level directory of the Linux kernel source tree, the last time you ran\sh|make menuconfig| or something similar.
475
476
476
477
\subsection{The \_\_init and \_\_exit Macros}
477
478
\label{init_n_exit}
@@ -502,7 +503,7 @@ \subsection{Licensing and Module Documentation}
502
503
Some examples are "GPL", "GPL v2", "GPL and additional rights", "Dual BSD/GPL", "Dual MIT/GPL", "Dual MPL/GPL" and "Proprietary".
503
504
They are defined within \src{include/linux/module.h}.
504
505
505
-
To reference what license you're using a macro is available called \cpp|MODULE_LICENSE|.
506
+
To reference what license you are using, a macro is available called \cpp|MODULE_LICENSE|.
506
507
This and a few other macros describing the module are illustrated in the below example.
507
508
508
509
\samplec{examples/hello-4.c}
@@ -517,7 +518,7 @@ \subsection{Passing Command Line Arguments to a Module}
517
518
The example code should clear up my admittedly lousy explanation.
518
519
519
520
The \cpp|module_param()| macro takes 3 arguments: the name of the variable, its type and permissions for the corresponding file in sysfs.
520
-
Integer types can be signed as usual or unsigned. If you'd like to use arrays of integers or strings see \cpp|module_param_array()| and \cpp|module_param_string()|.
521
+
Integer types can be signed as usual or unsigned. If you would like to use arrays of integers or strings, see \cpp|module_param_array()| and \cpp|module_param_string()|.
521
522
522
523
\begin{code}
523
524
int myint = 3;
@@ -812,8 +813,9 @@ \subsection{Code space}
812
813
Not real ones, anyway.
813
814
When a process is created, the kernel sets aside a portion of real physical memory and hands it to the process to use for its executing code, variables, stack, heap and other things which a computer scientist would know about.
814
815
This memory begins with 0x00000000 and extends up to whatever it needs to be.
815
-
Since the memory space for any two processes does not overlap, every process that can access a memory address, say 0xbffff978, would be accessing a different location in real physical memory! The processes would be accessing an index named 0xbffff978 which points to some kind of offset into the region of memory set aside for that particular process.
816
-
For the most part, a process like our Hello, World program can't access the space of another process, although there are ways which we will talk about later.
816
+
Since the memory space for any two processes does not overlap, every process that can access a memory address, say 0xbffff978, would be accessing a different location in real physical memory!
817
+
The processes would be accessing an index named 0xbffff978 which points to some kind of offset into the region of memory set aside for that particular process.
818
+
For the most part, a process like our Hello, World program cannot access the space of another process, although there are ways which we will talk about later.
817
819
818
820
The kernel has its own space of memory as well. Since a module is code which can be dynamically inserted and removed in the kernel (as opposed to a semi-autonomous object), it shares the kernel's codespace rather than having its own.
819
821
Therefore, if your module segfaults, the kernel segfaults.
For example, every character driver needs to define a function that reads from the device.
910
912
The \cpp|file_operations| structure holds the address of the module's function that performs that operation.
911
-
Here is what the definition looks like for kernel 5.4:
913
+
Here is what the definition looks like for kernel 5.4 and later versions:
912
914
913
915
\begin{code}
914
916
struct file_operations {
@@ -1098,7 +1100,7 @@ \subsection{Unregistering A Device}
1098
1100
\item\cpp|module_refcount(THIS_MODULE)|: Return the value of reference count of current module.
1099
1101
\end{itemize}
1100
1102
1101
-
It is important to keep the counter accurate; if you ever do lose track of the correct usage count, you will never be able to unload the module; it's now reboot time, boys and girls.
1103
+
It is important to keep the counter accurate; if you ever lose track of the correct usage count, you will never be able to unload the module; it is now reboot time.
1102
1104
This is bound to happen to you sooner or later during a module's development.
1103
1105
1104
1106
\subsection{chardev.c}
@@ -1112,12 +1114,12 @@ \subsection{chardev.c}
1112
1114
1113
1115
(or open the file with a program) and the driver will put the number of times the device file has been read from into the file.
1114
1116
We do not support writing to the file (like \sh|echo "hi" > /dev/hello|), but catch these attempts and tell the user that the operation is not supported.
1115
-
Don't worry if you don't see what we do with the data we read into the buffer; we don't do much with it.
1117
+
Do not worry if you do not see what we do with the data we read into the buffer; we do not do much with it.
1116
1118
We simply read in the data and print a message acknowledging that we received it.
1117
1119
1118
-
In the multiple-threaded environment, without any protection, concurrent access to the same memory may lead to the race condition, and will not preserve the performance.
1120
+
In a multi-threaded environment, without any protection, concurrent access to the same memory may lead to race conditions and will not preserve performance.
1119
1121
In the kernel module, this problem may happen due to multiple instances accessing the shared resources.
1120
-
Therefore, a solution is to enforce the exclusive access.
1122
+
Therefore, a solution is to enforce exclusive access.
1121
1123
We use atomic Compare-And-Swap (CAS) to maintain the states, \cpp|CDEV_NOT_USED| and \cpp|CDEV_EXCLUSIVE_OPEN|, to determine whether the file is currently opened by someone or not.
1122
1124
CAS compares the contents of a memory location with the expected value and, only if they are the same, modifies the contents of that memory location to the desired value.
1123
1125
See more concurrency details in the \ref{sec:synchronization} section.
@@ -1135,18 +1137,18 @@ \subsection{Writing Modules for Multiple Kernel Versions}
1135
1137
The way to do this is to compare the macro \cpp|LINUX_VERSION_CODE| to the macro \cpp|KERNEL_VERSION|.
1136
1138
In version \verb|a.b.c| of the kernel, the value of this macro would be \(2^{16}a+2^{8}b+c\).
1137
1139
1138
-
\section{The /proc File System}
1140
+
\section{The /proc Filesystem}
1139
1141
\label{sec:procfs}
1140
-
In Linux, there is an additional mechanism for the kernel and kernel modules to send information to processes --- the \verb|/proc| file system.
1142
+
In Linux, there is an additional mechanism for the kernel and kernel modules to send information to processes --- the \verb|/proc| filesystem.
1141
1143
Originally designed to allow easy access to information about processes (hence the name), it is now used by every bit of the kernel which has something interesting to report, such as \verb|/proc/modules| which provides the list of modules and \verb|/proc/meminfo| which gathers memory usage statistics.
1142
1144
1143
-
The method to use the proc file system is very similar to the one used with device drivers --- a structure is created with all the information needed for the \verb|/proc| file, including pointers to any handler functions (in our case there is only one, the one called when somebody attempts to read from the \verb|/proc| file).
1145
+
The method to use the proc filesystem is very similar to the one used with device drivers --- a structure is created with all the information needed for the \verb|/proc| file, including pointers to any handler functions (in our case there is only one, the one called when somebody attempts to read from the \verb|/proc| file).
1144
1146
Then, \cpp|init_module| registers the structure with the kernel and \cpp|cleanup_module| unregisters it.
1145
1147
1146
-
Normal file systems are located on a disk, rather than just in memory (which is where \verb|/proc| is), and in that case the index-node (inode for short) number is a pointer to a disk location where the file's inode is located.
1148
+
Normal filesystems are located on a disk, rather than just in memory (which is where \verb|/proc| is), and in that case the index-node (inode for short) number is a pointer to a disk location where the file's inode is located.
1147
1149
The inode contains information about the file, for example the file's permissions, together with a pointer to the disk location or locations where the file's data can be found.
1148
1150
1149
-
Because we don't get called when the file is opened or closed, there's nowhere for us to put \cpp|try_module_get| and \cpp|module_put| in this module, and if the file is opened and then the module is removed, there's no way to avoid the consequences.
1151
+
Because we do not get called when the file is opened or closed, there is nowhere for us to put \cpp|try_module_get| and \cpp|module_put| in this module, and if the file is opened and then the module is removed, there is no way to avoid the consequences.
1150
1152
1151
1153
Here is a simple example showing how to use a \verb|/proc| file.
1152
1154
This is the HelloWorld for the \verb|/proc| filesystem.
The \cpp|proc_ops| structure is defined in \src{include/linux/proc\_fs.h} in Linux v5.6+.
1176
-
In older kernels, it used \cpp|file_operations| for custom hooks in \verb|/proc| file system, but it contains some members that are unnecessary in VFS, and every time VFS expands \cpp|file_operations| set, \verb|/proc| code comes bloated.
1178
+
In older kernels, it used \cpp|file_operations| for custom hooks in \verb|/proc| filesystem, but it contains some members that are unnecessary in VFS, and every time VFS expands \cpp|file_operations| set, \verb|/proc| code comes bloated.
1177
1179
On the other hand, not only the space, but also some operations were saved by this structure to improve its performance.
1178
1180
For example, the file which never disappears in \verb|/proc| can set the \cpp|proc_flag| as \cpp|PROC_ENTRY_PERMANENT| to save 2 atomic ops, 1 allocation, 1 free in per open/read/close sequence.
1179
1181
@@ -1203,8 +1205,8 @@ \subsection{Manage /proc file with standard filesystem}
1203
1205
But it is also possible to manage \verb|/proc| file with inodes.
1204
1206
The main concern is to use advanced functions, like permissions.
1205
1207
1206
-
In Linux, there is a standard mechanism for file system registration.
1207
-
Since every file system has to have its own functions to handle inode and file operations, there is a special structure to hold pointers to all those functions, \cpp|struct inode_operations|, which includes a pointer to \cpp|struct proc_ops|.
1208
+
In Linux, there is a standard mechanism for filesystem registration.
1209
+
Since every filesystem has to have its own functions to handle inode and file operations, there is a special structure to hold pointers to all those functions, \cpp|struct inode_operations|, which includes a pointer to \cpp|struct proc_ops|.
1208
1210
1209
1211
The difference between file and inode operations is that file operations deal with the file itself whereas inode operations deal with ways of referencing the file, such as creating links to it.
1210
1212
@@ -1416,7 +1418,7 @@ \section{System Calls}
1416
1418
Then, you are mostly on your own.
1417
1419
1418
1420
Notice that this example has been unavailable since Linux v6.9.
1419
-
Specifically after this \href{https://github.com/torvalds/linux/commit/1e3ad78334a69b36e107232e337f9d693dcc9df2#diff-4a16bf89a09b4f49669a30d54540f0b936ea0224dc6ee9edfa7700deb16c3e11R52}{commit}, due to the system call table changing the implementation from an indirect function call table to a switch statement for security issue, such as Branch History Injection (BHI) attack.
1421
+
Specifically after this \href{https://github.com/torvalds/linux/commit/1e3ad78334a69b36e107232e337f9d693dcc9df2#diff-4a16bf89a09b4f49669a30d54540f0b936ea0224dc6ee9edfa7700deb16c3e11R52}{commit}, due to the system call table changing the implementation from an indirect function call table to a switch statement for security issues, such as Branch History Injection (BHI) attack.
1420
1422
See more information \href{https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2060909}{here}.
1421
1423
1422
1424
Should one choose not to use a virtual machine, kernel programming can become risky.
@@ -1891,7 +1893,7 @@ \subsection{GPIO}
1891
1893
1892
1894
There are other ways to register GPIOs.
1893
1895
For example, you can use \cpp|gpio_request_one()| to register a GPIO while setting its direction (input or output) and initial state at the same time.
1894
-
You can also use \cpp|gpio_request_array()| to register multiple GPIOs at once. However, note that \cpp|gpio_request_array()| has been removed since Linux v6.10+.
1896
+
You can also use \cpp|gpio_request_array()| to register multiple GPIOs at once. However, note that \cpp|gpio_request_array()| has been removed since Linux v6.10.
1895
1897
1896
1898
When using GPIO, you must set it as either output with \cpp|gpio_direction_output()| or input with \cpp|gpio_direction_input()|.
0 commit comments