Home | Projects | Notes > Linux Device Drivers > Debugging with printk & Kernel Log Levels
printk & Kernel Log Levels
printkprint is one of the best debugging tools we have in user-level applications.
When you work in kernel space, you will not have any access to the C standard library functions like printf or scanf.
As their counterpart, the kernel has its own printf-like API called printk, where the letter k signifies "Kernel space printing".
Examples;
xxxxxxxxxx41printf("User space.\n");2printk("Kernel space.\n"); /* Kernel space */3printf("data1 = %d, data2 = %d\n, d1, d2");4printk("data1 = %d, data2 = %d\n, d1, d2"); /* Kernel space */When using printk, the message will go into the kernel ring buffer (a.k.a. Kernel log) and we can print and control the kernel ring buffer using the command dmesg.
To check the latest 5 kernel messages:
xxxxxxxxxx11dmesg | tail -5To check the first 20 kernel messages:
xxxxxxxxxx11dmesg | head -20printk format specifiers
xxxxxxxxxx141Variable Type printk Format Specifier2================== =======================3int %d or %x4unsigned int %u or %x5long %ld or %lx6unsigned long %lu or %lx7long long %lld or %llx8unsigned long long %llu or %llx9size_t %zu or %zx10ssize_t %zd or %zx11s32 %d or %x12u32 %u or %x13s64 %lld or %llx14u64 %llu or %llx
printkdoes not support floating-point formats (%e,%f,%g).
[!] Reference: https://www.kernel.org/doc/Documentation/printk-formats.txt
Based on the kernel log level you can control the priority of the printk messages.
There are 8 log levels
The lower the level number, the higher the priority
The default printk log level or priority is usually set to 4. (i.e., KERN_WARNING)
xxxxxxxxxx151/* include/linux/kern_levels.h */2
3/* ASCII Start Of Header */45
6/* system is unstable */7/* action must be taken immediately */8/* critical conditions */9/* error conditions */10/* warning conditions */11/* normal but significant condition */12/* informational */13/* debug-level messages */14
15/* the default kernel loglevel */The log level will be used by the kernel to understand the priority of the message. Based on the priority the kernel will decide whether the message should be presented to the user immediately by printing directly on to the console.
All kernel messages will have their own log level.
You may have to specify the log level while using printk. If not specified, the kernel will add the default log level set by the kernel config item CONFIG_MESSAGE_LOGLEVEL_DEFAULT whose value is 4.
So, the following statement
xxxxxxxxxx11prink("Kernel space\n");is equivalent to
xxxxxxxxxx31prink(KERN_WARNING "Kernel space\n");2// ------------ --------------3// Log level String argNotice that there's NO comma (,) between the log level and the string argument!
Default message log level can be configured via the kernel menuconfig (make ARCH=arm menuconfig)

There is another log level we need to consider; the current console log level.
The kernel message log level will be compared with the current console log level. If the kernel message log level is lower (i.e., higher priority) than the current console log level, the message will be directly printed on the current console.
By default, the console log level will have the value of config item CONFIG_CONSOLE_LOGLEVEL_DEFAULT whose default value is set to 7. This value can be changed via the kernel menuconfig or running commands.
To check the current console log level status, run
xxxxxxxxxx21cat /proc/sys/kernel/printk27 4 1 7The results shows the current, default, minimum and boot-time-default log levels.
pr_info (i.e., KERN_INFO level) used in the hello world LKM is of log level 6. This is why the message is getting printed when the LKM gets inserted into the kernel.
At run-time, you can change the current console log level (for example to 6) by running the following command:
xxxxxxxxxx21sudo -s2echo 6 > /proc/sys/kernel/prinkNow, if you check the current console log level:
xxxxxxxxxx21cat /proc/sys/kernel/printk26 4 1 7The current console log level has changed from 7 to 6.
Since the current console log level is now the same as pr_info (i.e., KERN_INFO level), the message will not get printed when the hello world LKM gets inserted into the kernel.
prink wrappers (Defined in include/linux/printk.h)
| Name | Log Level | Alias Function |
|---|---|---|
| KERN_EMERG | "0" | pr_emerg |
| KERN_ALERT | "1" | pr_alert |
| KERN_CRIT | "2" | pr_crit |
| KERN_ERR | "3" | pr_err |
| KERN_WARNING | "4" | pr_warning |
| KERN_NOTICE | "5" | pr_notice |
| KERN_INFO | "6" | pr_info |
| KERN_DEBUG | "7" | pr_debug (works only if DEBUG is defined) |
| KERN_DEFAULT | "" | - |
pr_err- Useful for reporting errors
pr_info- Useful for printing general information
pr_warning- Useful for reporting warning
pr_alert,pr_crit- Useful for reporting critical situations
For example:
xxxxxxxxxx11printk(KERN_INFO "Kernel version 4.14\n");Can be re-written as
xxxxxxxxxx11pr_info("Kernel version 4.14\n");