📋 Table of Contents
Introduction to Kernel Logging in Embedded Systems
What is printk and Why Does It Matter?
Understanding the Kernel Ring Buffer
Finding Your Kernel Log Buffer Size
Viewing Messages with Log Levels
Understanding Linux Kernel Log Levels
The Four Values in /proc/sys/kernel/printk
Practical Example: Writing a Kernel Module with printk
Advanced Configuration: Increasing Buffer Size at Boot
Best Practices for Kernel Logging in Embedded Systems
Introduction to linux kernel logging in Embedded Systems
Hello students welcome to this free embedded systems course. In this lecture i will explain you about What is linux kernel logging, why we use linux kenrel logging and all hands on examples about linux kernel logging for more free embedded systems courses please visit embeddedpathashala.com.
When developing Linux device drivers and working with embedded systems, understanding the kernel’s logging mechanism is essential. The printk function serves as the primary debugging and logging tool for kernel-level programming. Whether you’re building custom device drivers for embedded Linux or troubleshooting kernel modules, mastering printk is a fundamental skill every embedded systems engineer should possess.
In this comprehensive tutorial, we’ll explore how the Linux kernel manages log messages, configure the kernel ring buffer, work with different log levels, and use practical examples to solidify your understanding. This guide is part of our free embedded systems course at EmbeddedPathashala, where we help aspiring engineers master Linux kernel programming.
What is printk in linux kernel logging and Why Does It Matter?
Unlike the standard printf function used in user-space applications, printk is specifically designed for kernel-space operations. It writes messages to the kernel ring buffer – a circular buffer that stores kernel log messages. This mechanism is crucial because:
- Real-time debugging: Monitor kernel module behavior during development
- System diagnostics: Track hardware initialization and driver operations
- Production logging: Capture critical system events in embedded devices
- Driver development: Essential tool for Linux device driver debugging
Understanding the Kernel Ring Buffer
What is the Ring Buffer?
The kernel ring buffer is a fixed-size circular buffer that stores kernel log messages. When you use printk continuously, the buffer updates with new messages. Once the buffer reaches its capacity, old messages are overwritten by newer ones – hence the “ring” or circular nature.
Finding Your Kernel Log Buffer Size
The kernel log buffer size is determined by the __LOG_BUF_LEN macro, which is calculated as:
__LOG_BUF_LEN = (1 << CONFIG_LOG_BUF_SHIFT)
Method 1: Using System Configuration File
You can check your current kernel configuration by examining the boot config file:
cat /boot/config-$(uname -r) | grep CONFIG_LOG_BUF_SHIFT
Method 2: Using Kernel Menuconfig
For custom kernel builds, you can configure this value using menuconfig:
make menuconfig
Navigate to: General Setup → Kernel log buffer size
Practical Buffer Size Example
If CONFIG_LOG_BUF_SHIFT is set to 18:
Buffer Size = 1 << 18 = 256KB = 256,000 bytes
Working with dmesg Command
The dmesg command reads and displays messages from the kernel ring buffer. By default, dmesg reads only 16,392 bytes. If your kernel uses a larger log buffer, you must specify the size explicitly.
Reading Larger Buffers
For a 256KB buffer:
dmesg -s 256000
Viewing Messages with Log Levels
To see log levels alongside messages:
dmesg -x
Adjusting Console Log Level
You can change which messages appear on the console:
sudo dmesg -n 3
This sets the console log level to 3, displaying only messages with priority 3 or lower.
Understanding Linux Kernel Log Levels
The Linux kernel defines 8 log levels (0-7), with lower numbers indicating higher priority:
| Level | Priority | Description |
|---|---|---|
| 0 | KERN_EMERG | System is unusable |
| 1 | KERN_ALERT | Action must be taken immediately |
| 2 | KERN_CRIT | Critical conditions |
| 3 | KERN_ERR | Error conditions |
| 4 | KERN_WARNING | Warning conditions |
| 5 | KERN_NOTICE | Normal but significant |
| 6 | KERN_INFO | Informational messages |
| 7 | KERN_DEBUG | Debug-level messages |
⚠️ Default Log Level: When you don’t specify a log level, printk uses KERN_WARNING (level 4) by default.
The Four Values in /proc/sys/kernel/printk
When you examine the kernel printk settings:
cat /proc/sys/kernel/printk
You’ll see four numbers, for example: 4 4 1 7
Here’s what each value represents:
- Console Log Level (4): Messages with priority ≤ this value appear on the console
- Default Message Level (4): Default priority for printk messages without explicit priority
- Minimum Console Level (1): Lowest log level allowed for console output
- Boot-time Default Level (7): Log level used during system boot
Modifying Console Log Level
You can dynamically change the console log level:
echo 8 > /proc/sys/kernel/printk
This changes the console log level to 8, allowing all messages to appear on the console.
Practical Example: Writing a Kernel Module with printk
Let’s create a simple kernel module demonstrating printk usage with different log levels.
Module Source Code (printk1.c)
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int test_hello_init(void)
{
printk("\001""4""%s: In init\n", __func__);
return 0;
}
static void test_hello_exit(void)
{
printk("\001""2""%s: In exit\n", __func__);
}
module_init(test_hello_init);
module_exit(test_hello_exit);
Understanding the Code
\001is the SOH (Start of Header) character- The digit following it (e.g., “4” or “2”) represents the log level
__func__is a compiler macro that expands to the current function name- The init function uses log level 4 (WARNING)
- The exit function uses log level 2 (CRITICAL)
Makefile
obj-m := printk1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Building and Testing
Step 1: Compile the module
make
Step 2: Load the module
sudo insmod ./printk1.ko
Step 3: Check kernel messages
dmesg | tail
Expected output:
[1778.935293] test_hello_init: In init
Step 4: Remove the module
sudo rmmod printk1
Step 5: Verify exit message
dmesg | tail
Expected output:
[1798.288262] test_hello_exit: In exit
Advanced Configuration: Increasing Buffer Size at Boot
You can increase the kernel log buffer size by adding a kernel parameter to your bootloader configuration:
log_buf_len=4M
This sets the buffer to 4 megabytes, useful for systems that generate extensive kernel logging.
Modifying GRUB Configuration
Edit /etc/default/grub:
GRUB_CMDLINE_LINUX="log_buf_len=4M"
Then update GRUB:
sudo update-grub sudo reboot
Best Practices for Kernel Logging in Embedded Systems
- Use Appropriate Log Levels: Match the severity of your message with the correct log level
- Avoid Excessive Logging: Too many printk statements can impact system performance
- Buffer Size Planning: Configure buffer size based on your system’s logging requirements
- Production Optimization: Reduce debug-level logging in production embedded devices
- Rate Limiting: Use
printk_ratelimited()for messages in loops to prevent buffer flooding
Common Pitfalls and Troubleshooting
Messages Not Appearing on Console
Problem: Your printk messages don’t appear on the console.
Solution: Check if the message log level is higher than the console log level:
cat /proc/sys/kernel/printk
Adjust the console log level if needed:
sudo dmesg -n 7
Buffer Overflow
Problem: Important messages are being overwritten.
Solution: Increase the kernel log buffer size using CONFIG_LOG_BUF_SHIFT or boot parameter.
Missing Log Levels
Problem: Unable to filter messages by priority.
Solution: Always specify log levels explicitly in your printk statements using KERN_* macros.
Conclusion: Mastering Kernel Logging for Embedded Development
Understanding printk and the kernel ring buffer is fundamental to embedded Linux development and device driver programming. Whether you’re debugging a custom driver, developing embedded systems applications, or learning Linux kernel internals, these concepts form the foundation of kernel-space debugging.
The ability to configure log buffers, understand log levels, and effectively use dmesg will significantly improve your productivity as an embedded systems engineer.
🎓 Learn More: Free Embedded Systems Course
This tutorial is part of our comprehensive free embedded systems course at EmbeddedPathashala. We offer in-depth tutorials on:
- Linux kernel programming and device drivers
- Embedded Linux development
- Real-time operating systems
- Hardware-software integration
- Bootloader development
- Kernel module programming
Related Topics You Might Find Useful
- Linux Device Driver Development Tutorial
- Understanding Kernel Space vs User Space
- Writing Your First Linux Kernel Module
- Debugging Embedded Linux Systems
- Linux Kernel Build Configuration Guide
Keywords: Linux kernel printk, kernel ring buffer, dmesg command, Linux device drivers, embedded systems programming, kernel module development, CONFIG_LOG_BUF_SHIFT, kernel log levels, embedded Linux tutorial, free embedded systems course, Linux kernel debugging, printk log levels, kernel logging, embedded systems engineer, device driver development
