Explanation of what happens when printk

advertisement
Explanation of what happens when printk-ing a message in
the kernel space (and why kernel messages don’t appear in the
shell in a graphics mode):
A summary of how to get the kernel messages without reading all these long
explanations are at the very end.
The kernel has a circular buffer of compile-time configurable size (by default
16KB) to which all printks go. So, basically, printks just formats the string
and appends it to the buffer, optionally writing it to the console. We'll get
back to the 'console' a bit later.
The kernel exposes the contents of the circular buffer to userspace by 2 means:
1. A /proc file named /proc/kmsg. If you cat the file you'll see the messages
as they are printk-ed by the kenrel.
2. a syslog() syscall (whose wrapper is called klogctl() for historical
reasons) that can manipulate the buffer (e.g. clear it) and read it.
A system daemon called klogd uses one of these methods (command-line
configurable, the 1st by default) to listen to new kernel messages, and passes
them to another daemon called syslogd. syslogd gets messages from different
sources (be it klogd, logging from another program, logs from a remote
computer, ...) and aggregates them in a few log files. The exact filenames and
what goes where is configurable in /etc/syslog.conf, but on RedHat, usually
everything goes into /var/log/messages.
A small side note: when one process opens /proc/kmsg, any other process
attempting to open it is blocked, so if one tries to "cat /proc/kmsg", he'll
get blocked and not see anything since klogd also reads that file.
A solution is just to kill klogd (use ps to find its pid) and then to read the
file.
A utility called dmesg uses the second method and reads the whole circular
buffer.
Bottom line till now: one can see all kernel messages in /proc/kmsg (if no
other process holds it open) and in /var/log/messages (intermixed with other
logs, but prefixed with something like "kernel", so easy to recognize), or by
running dmesg.
OK, now let's get back to the 'console'.
For Linux, a console is a device to which you can write text data and read text
data. By default, the console is the (text-mode) screen and keyboard. One can
switch to that console by pressing Ctrl+Alt+Fn, where n is 1 to 6. These are 6
virtual consoles that schare the same screen and keyboard. The kernel messages
appear on the currently selected console (unless otherwise configured), so no
misses due to virtual console switches are possible. To return to the graphical
interface, press Ctrl+Alt+F7.
When one boots his PC, the kernel prints a lot of messages, like "initializing
this...", "initializing that...". These all get printed via printk that sends
the message to the console driver.
When the kernel boots, one can tell it to use another console for
(instead of, or in addition to the default console). Usually this
console is chosen to be a serial port /dev/ttyS0 (COM1 is Windows
if, for example the machine hangs, you can still see the log from
machine connected via a null-modem cable to the first one.
the messages
second
terms), so
another
So why don't the kernel messages appear when in graphics mode?
In Linux, graphics mode is implemented not inside the kernel (and thus it
cannot print messages in graphics mode), but as a usermode process called X, or
sometimes X server. Every program that wants to, say, display a window, sends a
message via IPC to the X server and says it how it (the X server) should draw
the window. Of course, this message passing is implemented in a shared library,
so from the application writer point of view, it's just a call to a function
that displays the window.
xterm is one of the many graphical applications (Konsole and gnome-terminal are
the other two well-known programs) that emulates a terminal. What this means is
that xterm runs another program, usually a shell, for which it pretends to be a
regular terminal (just like the one on Ctrl+Alt+F1), but for the outer world,
it's just an application in it's own window. xterm passes all keystrokes to the
shell it runs and the resultant text is drawn graphically using the selected
font (by using some functions in a shared library that send messages to the X
server and tell it to draw the characters). Kernel messages are not output from
the shell, so xterm does not receive them, and therefore does not print (err..
draw) them.
Bottom line: here are a few ways to see kernel messages:
1. Switch to Crtl+Alt+Fn (n=1..6). All messages will appear right away.
2. Kill klogd and run "cat /proc/kmsg" (can be run from an xterm or from a
text-mode console). Messages will also appear immediately.
All other methods below allow to view the messages on demand and not when they
appear.
3. Run dmesg.
4. View (e.g. via "less") /var/log/messages (on RedHat and clones) and
/var/log/kernel.log (on Debian and clones).
5. Write your own application that uses klogctl to retrieve the log.
Alex Landau
Download