# printk

* [Printk](#printk)
  * [Message logging](#message-logging)
  * [Specifiers](#specifiers)
  * [Printk Index](#printk-index)
  * [Subsystem specific prefix](#subsystem-specific-prefix)
  * [References](#references)

## Printk

* `printk()` is one of the most widely known functions in the Linux kernel
* standard tool we have for printing messages and usually the **most basic way** of tracing and debugging
* All printk() messages are printed to the kernel log buffer, which is a **ring buffer** exported to userspace through `/dev/kmsg`. The usual way to read it is using `dmesg`.

### Message logging

* `printk()` can specify a log level : `printk(KERN_INFO "Message: %s\n", arg);`

| Name          | String | Alias function                                                                                                                                                                        |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| KERN\_EMERG   | “0”    | [`pr_emerg()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_emerg)                                                                                                        |
| KERN\_ALERT   | “1”    | [`pr_alert()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_alert)                                                                                                        |
| KERN\_CRIT    | “2”    | [`pr_crit()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_crit)                                                                                                          |
| KERN\_ERR     | “3”    | [`pr_err()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_err)                                                                                                            |
| KERN\_WARNING | “4”    | [`pr_warn()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_warn)                                                                                                          |
| KERN\_NOTICE  | “5”    | [`pr_notice()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_notice)                                                                                                      |
| KERN\_INFO    | “6”    | [`pr_info()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_info)                                                                                                          |
| KERN\_DEBUG   | “7”    | [`pr_debug()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_debug) and [`pr_devel()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_devel) if DEBUG is defined |
| KERN\_DEFAULT | “”     |                                                                                                                                                                                       |
| KERN\_CONT    | “c”    | [`pr_cont()`](https://docs.kernel.org/core-api/printk-basics.html#c.pr_cont)                                                                                                          |

* To check the current *console\_loglevel* : (shows *current*, *default*, *minimum* and *boot-time-default* log levels)

```shell
$ cat /proc/sys/kernel/printk
4        4        1        7
```

* This can be changed using `# echo 8 > /proc/sys/kernel/printk` or `# dmesg -n 5`.
* `pr_info`, `pr_debug` are macros that help to print logs at different levels

### Specifiers

There are many print specifiers present, it’s better to check these specifiers before using printk. These are available at : [Printk Formats - Kernel Docs](https://docs.kernel.org/core-api/printk-formats.html).

The common types are :

* Integer Types (signed char, unsigned char, int, unsigned short int, etc.)
* Pointer Types
  * Plain Pointers
  * Error Pointers
  * Symbol/Function Pointers (Eg : `%pS versatile_init+0x0/0x110`)
  * Probe pointers from BPF/tracing
  * Kernel Pointers
  * Unmodified address
  * Pointer Differences
  * Struct Resources
  * Physical addresses (`%pa[p] 0x01234567 or 0x0123456789abcdef`)
  * DMA addresses (`%pad 0x01234567 or 0x0123456789abcdef`)
  * Raw buffer
  * MAC addresses (`%pM 00:01:02:03:04:05`)
  * IPv4/v6 Addresses (`%pI4 1.2.3.4`)
  * UID/GUID (`%pUb 00010203-0405-0607-0809-0a0b0c0d0e0f`)
  * Dentrys (`%pd{,2,3,4}`)
  * And many more …

### Printk Index

> The kernel messages are evolving together with the code. As a result, particular kernel messages are not `KABI` and never will be! (See : [Kernel ABI doc](/linux-kernel-notes/misc/kabi.md) for KABI)

* The printk index helps to find changes in the message formats. Also it helps to track the strings back to the kernel sources and the related commit.
* The index of printk formats are split in into separate files.

```
/sys/kernel/debug/printk/index/vmlinux
/sys/kernel/debug/printk/index/ext4
/sys/kernel/debug/printk/index/scsi_mod
```

The content is inspired by the dynamic debug interface and looks like:

```shell
$> head -1 /sys/kernel/debug/printk/index/vmlinux; shuf -n 5 vmlinux
# <level[,flags]> filename:line function "format"
<5> block/blk-settings.c:661 disk_stack_limits "%s: Warning: Device %s is misaligned\n"
<4> kernel/trace/trace.c:8296 trace_create_file "Could not create tracefs '%s' entry\n"
<6> arch/x86/kernel/hpet.c:144 _hpet_print_config "hpet: %s(%d):\n"
<6> init/do_mounts.c:605 prepare_namespace "Waiting for root device %s...\n"
<6> drivers/acpi/osl.c:1410 acpi_no_auto_serialize_setup "ACPI: auto-serialization disabled\n"
```

### Subsystem specific prefix

* The macro `pr_fmt()` macro allows to define a prefix that is printed before the string generated by the related `printk()` calls.

```c
#define pr_fmt(fmt) "ACPI: OSL: " fmt

static int __init acpi_no_auto_serialize_setup(char *str)
{
      acpi_gbl_auto_serialize_methods = FALSE;
      pr_info("Auto-serialization disabled\n");

      return 1;
}
```

This results in the following `printk` index entry:

```
<6> drivers/acpi/osl.c:1410 acpi_no_auto_serialize_setup "ACPI: auto-serialization disabled\n"
```

### References

* [Printk Basics - Kernel Docs](https://docs.kernel.org/core-api/printk-basics.html)
* [Printk Formats - Kernel Docs](https://docs.kernel.org/core-api/printk-formats.html)
* [Printk Index - Kernel Docs](https://docs.kernel.org/core-api/printk-index.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lagnos.gitbook.io/linux-kernel-notes/core-apis/core-utilities/printk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
