Skip to content

Commit b9ed1a7

Browse files
committed
Proofread
1 parent 53c6bbc commit b9ed1a7

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

lkmpg.tex

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ \subsection{Authorship}
8888
Bob Mottram contributed to the guide by updating examples for Linux v3.8 and later.
8989
Jim Huang then undertook the task of updating the guide for recent Linux versions (v5.0 and beyond),
9090
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.
9192

9293
\subsection{Acknowledgements}
9394
\label{sec:acknowledgements}
@@ -103,7 +104,7 @@ \subsection{What Is A Kernel Module?}
103104

104105
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.
105106
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,
107108
resulting in a scenario that necessitates a complete system reboot.
108109

109110
A Linux kernel module is precisely defined as a code segment capable of dynamic loading and unloading within the kernel as needed.
@@ -131,7 +132,7 @@ \subsection{Kernel module package}
131132
\subsection{What Modules are in my Kernel?}
132133
\label{sec:modutils}
133134

134-
To discover what modules are already loaded within your current kernel use the command \sh|lsmod|.
135+
To discover what modules are already loaded within your current kernel, use the command \sh|lsmod|.
135136
\begin{codebash}
136137
lsmod
137138
\end{codebash}
@@ -190,7 +191,7 @@ \subsection{Before We Begin}
190191
If this message ``\emph{Lockdown: insmod: unsigned module loading is restricted;
191192
see man kernel lockdown.7}'' appears in the \sh|dmesg| output,
192193
the simplest approach involves disabling UEFI SecureBoot from the boot menu of your PC or laptop,
193-
allowing the successful insertion of ``hello world'' module.
194+
allowing the successful insertion of the ``hello world'' module.
194195
Naturally, an alternative involves undergoing intricate procedures such as generating keys, system key installation,
195196
and module signing to achieve functionality.
196197
However, this intricate process is less appropriate for beginners. If interested,
@@ -273,11 +274,11 @@ \subsection{The Simplest Module}
273274
make
274275
\end{codebash}
275276

276-
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.
278279
The default security policy is \verb|sudoers|.
279280
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}).
281282
You can see the environment variable settings by:
282283

283284
\begin{verbatim}
@@ -301,7 +302,7 @@ \subsection{The Simplest Module}
301302
echo $(PWD)
302303
\end{verbatim}
303304
304-
The \verb|PWD| variable won't be inherited with \verb|sudo|.
305+
The \verb|PWD| variable will not be inherited with \verb|sudo|.
305306
306307
\begin{verbatim}
307308
$ sudo make -p | grep PWD
@@ -323,7 +324,7 @@ \subsection{The Simplest Module}
323324
}
324325
325326
\item {
326-
You can set the \verb|env_reset| disabled by editing the \verb|/etc/sudoers| with root and \verb|visudo|.
327+
You can disable \verb|env_reset| by editing \verb|/etc/sudoers| as root using \verb|visudo|.
327328
328329
\begin{code}
329330
## sudoers file.
@@ -374,7 +375,7 @@ \subsection{The Simplest Module}
374375
\end{codebash}
375376
376377
should return nothing.
377-
You can try loading your shiny new module with:
378+
You can try loading your new module with:
378379
\begin{codebash}
379380
sudo insmod hello-1.ko
380381
\end{codebash}
@@ -414,9 +415,9 @@ \subsection{The Simplest Module}
414415
415416
\begin{enumerate}
416417
\item A point about coding style.
417-
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}.
418419
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.
420421
421422
\item Introducing print macros.
422423
\label{sec:printk}
@@ -447,7 +448,7 @@ \subsection{Hello and Goodbye}
447448
\label{hello_n_goodbye}
448449
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.
449450
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.
451452
Here is an example of this technique:
452453
453454
\samplec{examples/hello-2.c}
@@ -471,7 +472,7 @@ \subsection{Hello and Goodbye}
471472
As you can see, some things got hardwired into the kernel (\verb|obj-y|) but where have all those \verb|obj-m| gone?
472473
Those familiar with shell scripts will easily be able to spot them.
473474
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.
475476

476477
\subsection{The \_\_init and \_\_exit Macros}
477478
\label{init_n_exit}
@@ -502,7 +503,7 @@ \subsection{Licensing and Module Documentation}
502503
Some examples are "GPL", "GPL v2", "GPL and additional rights", "Dual BSD/GPL", "Dual MIT/GPL", "Dual MPL/GPL" and "Proprietary".
503504
They are defined within \src{include/linux/module.h}.
504505

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|.
506507
This and a few other macros describing the module are illustrated in the below example.
507508

508509
\samplec{examples/hello-4.c}
@@ -517,7 +518,7 @@ \subsection{Passing Command Line Arguments to a Module}
517518
The example code should clear up my admittedly lousy explanation.
518519

519520
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()|.
521522

522523
\begin{code}
523524
int myint = 3;
@@ -812,8 +813,9 @@ \subsection{Code space}
812813
Not real ones, anyway.
813814
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.
814815
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.
817819

818820
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.
819821
Therefore, if your module segfaults, the kernel segfaults.
@@ -908,7 +910,7 @@ \subsection{The file\_operations Structure}
908910

909911
For example, every character driver needs to define a function that reads from the device.
910912
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:
912914

913915
\begin{code}
914916
struct file_operations {
@@ -1098,7 +1100,7 @@ \subsection{Unregistering A Device}
10981100
\item \cpp|module_refcount(THIS_MODULE)|: Return the value of reference count of current module.
10991101
\end{itemize}
11001102

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.
11021104
This is bound to happen to you sooner or later during a module's development.
11031105

11041106
\subsection{chardev.c}
@@ -1112,12 +1114,12 @@ \subsection{chardev.c}
11121114

11131115
(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.
11141116
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.
11161118
We simply read in the data and print a message acknowledging that we received it.
11171119

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.
11191121
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.
11211123
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.
11221124
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.
11231125
See more concurrency details in the \ref{sec:synchronization} section.
@@ -1135,18 +1137,18 @@ \subsection{Writing Modules for Multiple Kernel Versions}
11351137
The way to do this is to compare the macro \cpp|LINUX_VERSION_CODE| to the macro \cpp|KERNEL_VERSION|.
11361138
In version \verb|a.b.c| of the kernel, the value of this macro would be \(2^{16}a+2^{8}b+c\).
11371139

1138-
\section{The /proc File System}
1140+
\section{The /proc Filesystem}
11391141
\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.
11411143
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.
11421144

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).
11441146
Then, \cpp|init_module| registers the structure with the kernel and \cpp|cleanup_module| unregisters it.
11451147

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.
11471149
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.
11481150

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.
11501152

11511153
Here is a simple example showing how to use a \verb|/proc| file.
11521154
This is the HelloWorld for the \verb|/proc| filesystem.
@@ -1173,7 +1175,7 @@ \section{The /proc File System}
11731175
\subsection{The proc\_ops Structure}
11741176
\label{sec:proc_ops}
11751177
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.
11771179
On the other hand, not only the space, but also some operations were saved by this structure to improve its performance.
11781180
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.
11791181

@@ -1203,8 +1205,8 @@ \subsection{Manage /proc file with standard filesystem}
12031205
But it is also possible to manage \verb|/proc| file with inodes.
12041206
The main concern is to use advanced functions, like permissions.
12051207

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|.
12081210

12091211
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.
12101212

@@ -1416,7 +1418,7 @@ \section{System Calls}
14161418
Then, you are mostly on your own.
14171419

14181420
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.
14201422
See more information \href{https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2060909}{here}.
14211423

14221424
Should one choose not to use a virtual machine, kernel programming can become risky.
@@ -1891,7 +1893,7 @@ \subsection{GPIO}
18911893

18921894
There are other ways to register GPIOs.
18931895
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.
18951897

18961898
When using GPIO, you must set it as either output with \cpp|gpio_direction_output()| or input with \cpp|gpio_direction_input()|.
18971899

0 commit comments

Comments
 (0)