printk

{{Short description|Printf-like function for the Linux kernel}}

{{lowercase title}}

{{Use mdy dates|date=February 2025}}

{{Use American English|date=February 2025}}

printk is a printf-like function of the Linux kernel interface for formatting and writing kernel log entries.{{Cite web|title=Message logging with printk — The Linux Kernel documentation|url=https://www.kernel.org/doc/html/latest/core-api/printk-basics.html|access-date=2020-09-09|website=www.kernel.org}} Since the C standard library (which contains the ubiquitous printf-like functions) is not available in kernel mode, {{code|printk}} provides for general-purpose output in the kernel.{{Cite book|title=ISO/IEC 9899:2018|publisher=International Standards Organization|year=2018}} Due to limitations of the kernel design, the function is often used to aid debugging kernel mode software.

printk can be called from anywhere in the kernel except during early stages of the boot process; before the system console is initialized. The alternative function early_printk is implemented on some architectures and is used identically to printk but during the early stages of the boot process.

Use

{{code|printk}} has the same syntax as {{code|printf}}, but somewhat different semantics. Like {{code|printf}}, {{code|printk}} accepts a format c-string argument and a list of value arguments. Both format text based on the input parameters and with significantly similar behavior, but there are also significant differences. The {{code|printk}} function prototype (which matches that of {{code|printf}}) is:

{{syntaxhighlight|lang=c|code=int printk(const char *format, ...);}}

The features different from printf are described below.

=Log level=

printk allows a caller to specify a log level {{endash}} the type and importance of the message being sent. The level is specified by prepending text that identifies a log level. Typically the text is prepended via C's string literal concatenation and via one of the macros designed for this purpose. For example, a message could be logged at the informational level as:

printk(KERN_INFO "Message: %s", arg)

The text specifying the log level consists of the ASCII SOH character followed by a digit that identifies the log level or the letter 'c' to indicate the message is a continuation of the previous message.{{Cite web|title=kern_levels.h|url=https://raw.githubusercontent.com/torvalds/linux/8f02f363f76f99f08117336cfac7f24c76b25be3/include/linux/kern_levels.h|access-date=2020-09-27|website=GitHub|language=en}} The following table lists each log level with its canonical meaning.{{Cite web|date=2007-08-30|title=printk()|url=http://book.chinaunix.net/special/ebook/Linux_Kernel_Development/0672327201/ch18lev1sec3.html|archive-url=https://archive.today/20070830070012/http://book.chinaunix.net/special/ebook/Linux_Kernel_Development/0672327201/ch18lev1sec3.html|url-status=dead|archive-date=2007-08-30|access-date=2020-09-09|website=archive.is}}

class="wikitable"
0KERN_EMERGAn emergency condition; the system is probably dead
1KERN_ALERTA problem that requires immediate attention
2KERN_CRITA critical condition
3KERN_ERRAn error
4KERN_WARNINGA warning
5KERN_NOTICEA normal, but perhaps noteworthy, condition
6KERN_INFOAn informational message
7KERN_DEBUGA debug message

When no log level is specified, the entry is logged as the default level which is typically {{var|KERN_WARNING}}, but can be set; such as via the {{var|1=loglevel=}} boot argument.{{Cite web|title=The kernel's command-line parameters|url=https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html|access-date=2023-09-27|website=kernel.org|language=en}}

Log levels are defined in header file {{mono|}}. Which log levels are printed is configured using the sysctl file {{mono|/proc/sys/kernel/printk}}.

=Pointer formats=

The %p format specifier which is supported by printf, is extended with additional formatting modes. For example, requesting to print a {{code|struct sockaddr *}} using %pISpc formats an IPv4/v6 address and port in a human-friendly format such as {{samp|1.2.3.4:12345}} or {{samp|[1:2:3:4:5:6:7:8]:{{wbr}}12345}}.{{Cite web|title=How to get printk format specifiers right — The Linux Kernel documentation|url=https://www.kernel.org/doc/html/latest/core-api/printk-formats.html#printk-specifiers|access-date=2020-09-09|website=www.kernel.org}}

= No floating point support =

While printf supports formatting floating point numbers, printk does not, since the Linux kernel does not support floating point numbers.{{Cite web|title=Re: Linux kernel and floating point.|url=https://www.redhat.com/archives/axp-list/2002-April/msg00121.html|access-date=2020-09-09|website=www.redhat.com|archive-date=2019-07-21|archive-url=https://web.archive.org/web/20190721023736/https://www.redhat.com/archives/axp-list/2002-April/msg00121.html|url-status=dead}}

Implementation

The function tries to lock the semaphore controlling access to the Linux system console.{{Cite web|title=Driver Basics — The Linux Kernel documentation|url=https://www.kernel.org/doc/html/latest/driver-api/basics.html#c.console_lock|access-date=2020-09-09|website=www.kernel.org}} If it succeeds, the output is logged and the console drivers are called. If it is not possible to acquire the semaphore the output is placed into the log buffer, and the current holder of the console semaphore will notice the new output when they release the console semaphore and will send the buffered output to the console before releasing the semaphore.

One effect of this deferred printing is that code which calls printk and then changes the log levels to be printed may break. This is because the log level to be printed is inspected when the actual printing occurs.

References

{{Reflist}}