In the Linux kernel, printk() is what you use instead of printf() . Here's an example :
printk( KERN_WARNING "%s: buffer overflow, lost %d messages\n", bufname, cnt );
That first part before the format string, KERN_WARNING here, is the log level and indicates how important the message is. You have several choices :
To use printk(), include linux/printk.h .
One way to see the messages is with the dmesg command. Additionally, the messages are displayed on the system console. To see the system console on your typical graphics-based desktop Linux machine, press ctl-alt-F1, and to get back to your main graphics screen press ctl-alt-F7 or ctl-alt-F8. On embedded Linux systems, the console may be on a serial port.
Most systems are set to discard messages with higher log levels like KERN_NOTICE, KERN_INFO, KERN_DEBUG. To change that setting at boot, you can set the kernel parameter loglevel= to one of the numbers given in the table above. All messages with that number or greater will be discarded (Its easier to think of it as the "discard loglevel"). This is especially useful if your system is panicking early. You can also use the kernel parameter ignore_loglevel so that all messages are shown on the console.
Once booted, the dmesg command also allows you to change the console loglevel with the -n option, so after
dmesg -n 5
only messages less than KERN_NOTICE will be displayed.
To find out the current console loglevel, use :
cat /proc/sys/kernel/printk
and you'll see something like :
4 4 1 7
The first digit, 4 here, tells me that messages with log levels 4 and greater will be discarded. To see all messages, I can change it to 8 (until the next reboot) by entering :
sudo bash -c "echo 8 > /proc/sys/kernel/printk"
To change the default discard level at boot, you have to change the kernel's value for DEFAULT_CONSOLE_LOGLEVEL in kernel/printk.c and rebuild the kernel.
The kernel is starting to use a new set of functions instead of printk().
The pr_ functions act just like printk(), but you don't need KERN_WARNING and the others, for example like this :
pr_warning("%s: buffer overflow, lost %d messages\n", bufname, cnt );
The dev_ functions take an extra parameter for a device structure before the format, and display the name of the device :
dev_warning(mydev, "%s: buffer overflow, lost %d messages\n", cnt );
Here are all the pr_ and dev_ functions :
For the pr_ functions, you need to include linux/printk.h, and for the dev_ functions, you need to include linux/device.h .
pr_debug(), pr_devel(), and dev_dbg() are designed to be removed by the compiler if DEBUG is not defined, saving space. The one exception is that pr_debug() and dev_debug() will remain and take up space if CONFIG_DYNAMIC_DEBUG is defined. To define DEBUG for a module, add a line to the Makefile in that module's directory like this:
CFLAGS_[filename].o := -DDEBUG
printk()'s format specifiers appear to be very similar to printf()'s, but these are different enough that we need an entirely new table to keep track of them.
Flags, the minimum field-width, and the precision field, all work like you expect.
Special pointer formatting is specified with alphanumeric characters following the 'p'. These additions make printk() handy for kernel and device driver debugging.
Notice that printk() doesn't support floating point numbers.
Argument type is determined by format and size modifier.
Here are the number formats :
Here are the size modifiers possible for each number format :
You're probably familiar with c format for characters and s format for strings :
In printk(), the n format has the z size modifier instead of h.
print_hex_dump() is a versatile way to see what you've got in a buffer.
print_hex_dump( level, prefix_str, prefix_type, rowsize, groupsize, buf, len, ascii);
A shorthand version, that uses log level KERN_DEBUG and shows 16 bytes on each line with ASCII, is
print_hex_dump_bytes( prefix_str, prefix_type, buf, len);
Include linux/printk.h for these.
When wanting details on regular printf(), If I don't have "C A Reference Manual" by Harbison and Steele available, I refer to The Open Group's printf() description.
Linux's prink() source is located in kernel/printk.c. For formatting, printk() uses vsnprintf() in lib/vsprintf.c.
(Copyright 2012 & 2020, Norm)