Skip to content

Commit 1d1f01c

Browse files
committed
Clarify kernel module output goes to dmesg, not console
This commit resolves confusion where users expected module output to appear directly in terminal. It also updates documentation to clearly explain that: - Module output goes to kernel log ring buffer, not console - Use 'dmesg' to view module messages - Terminal environment doesn't affect where output goes - Provides concrete examples in hello world section Close #171
1 parent a9caf93 commit 1d1f01c

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

lkmpg.tex

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ \subsection{Authorship}
9393
\subsection{Acknowledgements}
9494
\label{sec:acknowledgements}
9595

96-
The following people have contributed corrections or good suggestions:
96+
The following people have contributed corrections or good suggestions:
9797

9898
\begin{flushleft}
9999
\input{contrib}
@@ -176,12 +176,12 @@ \subsection{Before We Begin}
176176
Working on these tasks within the X Window System is discouraged.
177177

178178
Modules cannot directly print to the screen like \cpp|printf()| can,
179-
but they can log information and warnings that are eventually displayed on the screen,
180-
specifically within a console.
181-
If a module is loaded from an \sh|xterm|, the information and warnings will be logged,
182-
but solely within the systemd journal. These logs will not be visible unless consulting the \sh|journalctl|.
179+
but they can log information and warnings to the kernel's log ring buffer.
180+
This output is \emph{not} automatically displayed on any console or terminal.
181+
To view kernel module messages, you must use \sh|dmesg| to read the kernel log ring buffer,
182+
or check the systemd journal with \sh|journalctl -k| for kernel messages.
183183
Refer to \ref{sec:helloworld} for more information.
184-
For instant access to this information, it is advisable to perform all tasks from the console.
184+
The terminal or environment from which you load the module does not affect where the output goes—it always goes to the kernel log.
185185
\item SecureBoot.
186186
Numerous modern computers arrive pre-configured with UEFI SecureBoot enabled—an essential security standard ensuring booting exclusively through trusted software endorsed by the original equipment manufacturer.
187187
Certain Linux distributions even ship with the default Linux kernel configured to support SecureBoot.
@@ -265,7 +265,7 @@ \subsection{The Simplest Module}
265265
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
266266
\end{code}
267267
268-
In \verb|Makefile|, \verb|$(CURDIR)| can be set to the absolute pathname of the current working directory (after all \verb|-C| options are processed, if any).
268+
In \verb|Makefile|, \verb|$(CURDIR)| can be set to the absolute pathname of the current working directory (after all \verb|-C| options are processed, if any).
269269
See more about \verb|CURDIR| in \href{https://www.gnu.org/software/make/manual/make.html}{GNU make manual}.
270270

271271
And finally, just run \verb|make| directly.
@@ -277,7 +277,7 @@ \subsection{The Simplest Module}
277277
If there is no \verb|PWD := $(CURDIR)| statement in the Makefile, then it may not compile correctly with \verb|sudo make|.
278278
This is because some environment variables are specified by the security policy and cannot be inherited.
279279
The default security policy is \verb|sudoers|.
280-
In the \verb|sudoers| security policy, \verb|env_reset| is enabled by default, which restricts environment variables.
280+
In the \verb|sudoers| security policy, \verb|env_reset| is enabled by default, which restricts environment variables.
281281
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}).
282282
You can see the environment variable settings by:
283283

@@ -314,7 +314,7 @@ \subsection{The Simplest Module}
314314
\begin{enumerate}
315315
\item {
316316
You can use the \verb|-E| flag to temporarily preserve them.
317-
317+
318318
\begin{codebash}
319319
$ sudo -E make -p | grep PWD
320320
PWD = /home/ubuntu/temp
@@ -324,11 +324,11 @@ \subsection{The Simplest Module}
324324
}
325325
326326
\item {
327-
You can disable \verb|env_reset| by editing \verb|/etc/sudoers| as root using \verb|visudo|.
327+
You can disable \verb|env_reset| by editing \verb|/etc/sudoers| as root using \verb|visudo|.
328328
329329
\begin{code}
330330
## sudoers file.
331-
##
331+
##
332332
...
333333
Defaults env_reset
334334
## Change env_reset to !env_reset in previous line to keep all environment variables
@@ -345,11 +345,11 @@ \subsection{The Simplest Module}
345345
echo "root:" >> env_reset.log; sudo env >> env_reset.log
346346
\end{codebash}
347347
348-
You can view and compare these logs to find differences between \verb|env_reset| and \verb|!env_reset|.
348+
You can view and compare these logs to find differences between \verb|env_reset| and \verb|!env_reset|.
349349
}
350350
351-
\item {You can preserve environment variables by appending them to \verb|env_keep| in \verb|/etc/sudoers|.
352-
351+
\item {You can preserve environment variables by appending them to \verb|env_keep| in \verb|/etc/sudoers|.
352+
353353
\begin{code}
354354
Defaults env_keep += "PWD"
355355
\end{code}
@@ -391,7 +391,13 @@ \subsection{The Simplest Module}
391391
\end{codebash}
392392
393393
Notice that the dash was replaced by an underscore.
394-
To see what just happened in the logs:
394+
To see the module's output messages, use \sh|dmesg| to view the kernel log ring buffer:
395+
\begin{codebash}
396+
sudo dmesg | tail -10
397+
\end{codebash}
398+
399+
You should see messages like ``Hello world 1.'' and ``Goodbye world 1.'' from your module.
400+
Alternatively, you can check the systemd journal for kernel messages:
395401
\begin{codebash}
396402
journalctl --since "1 hour ago" | grep kernel
397403
\end{codebash}
@@ -427,6 +433,9 @@ \subsection{The Simplest Module}
427433
They can be found within \src{include/linux/printk.h}.
428434
Take time to read through the available priority macros.
429435
436+
\textbf{Important:} These functions write to the kernel log ring buffer, \emph{not} directly to any terminal or console.
437+
To view the output from your kernel modules, you must use \sh|dmesg| or \sh|journalctl -k|.
438+
430439
\item About Compiling.
431440
Kernel modules need to be compiled a bit differently from regular userspace apps.
432441
Former kernel versions required us to care much about these settings, which are usually stored in Makefiles.
@@ -526,7 +535,7 @@ \subsection{Passing Command Line Arguments to a Module}
526535
\end{code}
527536

528537
Arrays are supported too, but things are a bit different now than they were in the olden days.
529-
To keep track of the number of parameters you need to pass a pointer to a count variable as third parameter.
538+
To keep track of the number of parameters you need to pass a pointer to a count variable as third parameter.
530539
At your option, you could also ignore the count and pass \cpp|NULL| instead. We show both possibilities here:
531540

532541
\begin{code}
@@ -1530,7 +1539,7 @@ \section{System Calls}
15301539
# Reboot
15311540
$ sudo grep sys_call_table /boot/System.map-$(uname -r)
15321541
ffffffff82000300 R sys_call_table
1533-
$ sudo grep sys_call_table /proc/kallsyms
1542+
$ sudo grep sys_call_table /proc/kallsyms
15341543
ffffffff86400300 R sys_call_table
15351544
\end{verbatim}
15361545
If \verb|KASLR| is enabled, we have to take care of the address from \verb|/proc/kallsyms| each time we reboot the machine.
@@ -1577,8 +1586,8 @@ \section{System Calls}
15771586
When A is removed, it sees that the system call was changed to \cpp|B_openat| so that it is no longer pointing to \cpp|A_openat|, so it will not restore it to \cpp|sys_openat| before it is removed from memory.
15781587
Unfortunately, \cpp|B_openat| will still try to call \cpp|A_openat| which is no longer there, so that even without removing B the system would crash.
15791588

1580-
For x86 architecture, the system call table cannot be used to invoke a system call after commit
1581-
\href{https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e3ad78334a69b36e107232e337f9d693dcc9df2}{1e3ad78} since v6.9.
1589+
For x86 architecture, the system call table cannot be used to invoke a system call after commit
1590+
\href{https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e3ad78334a69b36e107232e337f9d693dcc9df2}{1e3ad78} since v6.9.
15821591
This commit has been backported to long term stable kernels, like v5.15.154+, v6.1.85+, v6.6.26+ and v6.8.5+, see this \href{https://stackoverflow.com/a/78607015}{answer} for more details.
15831592
In this case, thanks to Kprobes, a hook can be used instead on the system call entry to intercept the system call.
15841593

@@ -1672,8 +1681,8 @@ \subsection{Completions}
16721681

16731682
Completions as code synchronization mechanism have three main parts, initialization of struct completion synchronization object, the waiting or barrier part through \cpp|wait_for_completion()|, and the signalling side through a call to \cpp|complete()|.
16741683

1675-
In the subsequent example, two threads are initiated: crank and flywheel.
1676-
It is imperative that the crank thread starts before the flywheel thread.
1684+
In the subsequent example, two threads are initiated: crank and flywheel.
1685+
It is imperative that the crank thread starts before the flywheel thread.
16771686
A completion state is established for each of these threads, with a distinct completion defined for both the crank and flywheel threads.
16781687
At the exit point of each thread the respective completion state is updated, and \cpp|wait_for_completion| is used by the flywheel thread to ensure that it does not begin prematurely.
16791688
The crank thread uses the \cpp|complete_all()| function to update the completion, which lets the flywheel thread continue.
@@ -1961,12 +1970,12 @@ \subsection{DHT11 sensor}
19611970

19621971
Check the Output of the DHT11 Sensor:
19631972
\begin{codebash}
1964-
sudo cat /dev/dht11
1973+
sudo cat /dev/dht11
19651974
\end{codebash}
19661975

19671976
Expected Output:
19681977
\begin{verbatim}
1969-
$ sudo cat /dev/dht11
1978+
$ sudo cat /dev/dht11
19701979
Humidity: 61%
19711980
Temperature: 30°C
19721981
\end{verbatim}

0 commit comments

Comments
 (0)