While searching for techniques to debugging a Linux kernel, one of the ways is to use the dev_*() family functions.
These functions are defined in the /include/linux/device.h
file.
The function list is as below:
`dev_emerge()`<br>
`dev_alert()`<br>
`dev_crit()`<br>
`dev_err()`<br>
`dev_warning()`<br>
`dev_notice()`<br>
`dev_info()`<br>
I have already experimented with the pr_*()[pr_emerge()
, pr_alert()
, pr_crit()
...] family functions, which are similar to printk() in some way.
An experiment is done using simple kernel modules where I'm calling these functions. Furthermore I have also gone through a priority of messages displayed in syslog
and dmesg
(kernel ring buffer depending console_loglevel-a kernel variable).
But I'm unable to understand the use of dev_*() family. I mean, how do I use it in a program to debug kernel functionality?
While searching for techniques to debugging a Linux kernel, one of the ways is to use the dev_* () family functions. These functions are defined in the /include/linux/device.h file. The function list is as below:
After you mount debugfs, a large number of different directories and files will turn up in the /sys/kernel/debug/ directory. These are all virtual and dynamically generated by the kernel, like the files in procfs or sysfs. The files can be used to help debug different kernel subsystems, or just perused to see what is happening to ...
The debugfs filesystem is also intended to not serve as a stable ABI to user space; in theory, there are no stability constraints placed on files exported there. The real world is not always so simple, though 1 ; even debugfs interfaces are best designed with the idea that they will need to be maintained forever. (Or an equivalent /etc/fstab line).
If ERR_PTR (-ENODEV) is returned, that is an indication that the kernel has been built without debugfs support and none of the functions described below will work. The most general way to create a file within a debugfs directory is with:
The pr_*()
functions are the same as plain printk()
, but with the KERN_xxx
log level already included.
The dev_*()
functions are the same as the corresponding pr_*()
functions, but also print identifying information about the struct device
.
If your message is related to some device (which is normally the case in drivers), you should use dev_*()
.
For example, in a USB driver:
struct usb_device *usb_dev;
dev_info(&usb_dev->dev, "hello\n");
struct usb_interface *usb_intf;
dev_info(&usb_intf->dev, "hello\n");
or in a PCI driver:
struct pci_dev *pci;
dev_info(&pci->dev, "hello\n");
dev_*
functions are similar to pr_*
, but also print some information about device(struct device
), passed to them as the first argument. This information may help to filter system log for messages, belonging to concrete device.
So, you can use dev_*
function instead of pr_*
whenever message is applicable to concrete device(and you have destriptor of it).
Check what it prints yourself with QEMU
This is what it prints for a PCI device:
<6>lkmc_pci 0000:00:04.0: pci_probe
which is of format:
<level><kernel-module> <pci-address>: <message>
So as others said, it gives extra device information compared to a simple printk
, namely:
I tested that with QEMU's "edu" device, which is simple educational PCI device, for which I wrote a minimal Linux kernel module.
The key module code is:
static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
dev_info(&(dev->dev), "pci_probe\n");
Character devices don't expose a struct device
apparently, so you can't test it that way: How do you get a struct device for a Linux character device
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With