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
+35-32Lines changed: 35 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 {
@@ -1096,7 +1098,8 @@ \subsection{Unregistering A Device}
1096
1098
\item\cpp|module_refcount(THIS_MODULE)|: Return the value of reference count of current module.
1097
1099
\end{itemize}
1098
1100
1099
-
Note: The use of \cpp|try_module_get(THIS_MODULE)| and \cpp|module_put(THIS_MODULE)| within a module's own code is considered unsafe and should be avoided. The kernel automatically manages the reference count when file operations are in progress, so manual reference counting is unnecessary and can lead to race conditions.
1101
+
Note: The use of \cpp|try_module_get(THIS_MODULE)| and \cpp|module_put(THIS_MODULE)| within a module's own code is considered unsafe and should be avoided.
1102
+
The kernel automatically manages the reference count when file operations are in progress, so manual reference counting is unnecessary and can lead to race conditions.
1100
1103
This is bound to happen to you sooner or later during a module's development.
1101
1104
1102
1105
\subsection{chardev.c}
@@ -1110,12 +1113,12 @@ \subsection{chardev.c}
1110
1113
1111
1114
(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.
1112
1115
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.
1113
-
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.
1116
+
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.
1114
1117
We simply read in the data and print a message acknowledging that we received it.
1115
1118
1116
-
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.
1119
+
In a multi-threaded environment, without any protection, concurrent access to the same memory may lead to race conditions and will not preserve performance.
1117
1120
In the kernel module, this problem may happen due to multiple instances accessing the shared resources.
1118
-
Therefore, a solution is to enforce the exclusive access.
1121
+
Therefore, a solution is to enforce exclusive access.
1119
1122
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.
1120
1123
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.
1121
1124
See more concurrency details in the \ref{sec:synchronization} section.
@@ -1133,18 +1136,18 @@ \subsection{Writing Modules for Multiple Kernel Versions}
1133
1136
The way to do this is to compare the macro \cpp|LINUX_VERSION_CODE| to the macro \cpp|KERNEL_VERSION|.
1134
1137
In version \verb|a.b.c| of the kernel, the value of this macro would be \(2^{16}a+2^{8}b+c\).
1135
1138
1136
-
\section{The /proc File System}
1139
+
\section{The /proc Filesystem}
1137
1140
\label{sec:procfs}
1138
-
In Linux, there is an additional mechanism for the kernel and kernel modules to send information to processes --- the \verb|/proc| file system.
1141
+
In Linux, there is an additional mechanism for the kernel and kernel modules to send information to processes --- the \verb|/proc| filesystem.
1139
1142
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.
1140
1143
1141
-
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).
1144
+
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).
1142
1145
Then, \cpp|init_module| registers the structure with the kernel and \cpp|cleanup_module| unregisters it.
1143
1146
1144
-
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.
1147
+
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.
1145
1148
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.
1146
1149
1147
-
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.
1150
+
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.
1148
1151
1149
1152
Here is a simple example showing how to use a \verb|/proc| file.
1150
1153
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+.
1174
-
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.
1177
+
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.
1175
1178
On the other hand, not only the space, but also some operations were saved by this structure to improve its performance.
1176
1179
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.
1177
1180
@@ -1201,8 +1204,8 @@ \subsection{Manage /proc file with standard filesystem}
1201
1204
But it is also possible to manage \verb|/proc| file with inodes.
1202
1205
The main concern is to use advanced functions, like permissions.
1203
1206
1204
-
In Linux, there is a standard mechanism for file system registration.
1205
-
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|.
1207
+
In Linux, there is a standard mechanism for filesystem registration.
1208
+
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|.
1206
1209
1207
1210
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.
1208
1211
@@ -1414,7 +1417,7 @@ \section{System Calls}
1414
1417
Then, you are mostly on your own.
1415
1418
1416
1419
Notice that this example has been unavailable since Linux v6.9.
1417
-
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.
1420
+
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.
1418
1421
See more information \href{https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2060909}{here}.
1419
1422
1420
1423
Should one choose not to use a virtual machine, kernel programming can become risky.
@@ -1889,7 +1892,7 @@ \subsection{GPIO}
1889
1892
1890
1893
There are other ways to register GPIOs.
1891
1894
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.
1892
-
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
+
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.
1893
1896
1894
1897
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