linux kernel logging – complete tutorial

Linux Kernel Device Drivers Embedded Systems Kernel Programming Free Tutorial

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:

  1. Console Log Level (4): Messages with priority ≤ this value appear on the console
  2. Default Message Level (4): Default priority for printk messages without explicit priority
  3. Minimum Console Level (1): Lowest log level allowed for console output
  4. 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

  • \001 is 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

  1. Use Appropriate Log Levels: Match the severity of your message with the correct log level
  2. Avoid Excessive Logging: Too many printk statements can impact system performance
  3. Buffer Size Planning: Configure buffer size based on your system’s logging requirements
  4. Production Optimization: Reduce debug-level logging in production embedded devices
  5. 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

Visit EmbeddedPathashala.com →

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

Leave a Reply

Your email address will not be published. Required fields are marked *