Debugfs in the Linux kernel

Source: Internet
Author: User
Tags wrapper

DebugFS, as the name implies, is a virtual file system for kernel debugging, in which kernel developers exchange data through DebugFS and user space. Similar virtual file systems, such as PROCFS and SYSFS, are not actually stored on the hard disk, but are built after the Linux kernel is running.

Typically, the most commonly used kernel debugging means is PRINTK. But PRINTK not all things are good, such as printing data may be too much, we really care about the data in a lot of output is not so obvious, or we may need to modify some kernel variables in the debugging, in this case PRINTK can not do anything, And if the kernel is recompiled or the driver is too inefficient in order to modify a value, a temporary filesystem is needed to map the data we need to care to the user space. In the past, PROCFS can achieve this, in the 2.6 era, the newly introduced SYSFS can also be achieved, but whether PROCFS or SYSFS, using them to achieve some of the requirements of debug, seems to deviate from the original intention of their creation. PROCFS, for example, is designed to reflect the state of the process, while SYSFS is used primarily for Linux device models. The interfaces of either PROCFS or SYSFS should remain relatively stable because the user-state program is likely to rely on them. Of course, if we are only temporarily borrowing PROCFS or SYSFS for debug purposes, deleting the relevant debug code before the code is released is not an issue. But if the relevant debugging excuses are to be present in the kernel for a long time, it is not appropriate to put them in Procfs and Sysfs. Therefore, Debugfs was born.

By default, Debugfs will be mounted under directory/sys/kernel/debug, if you do not have an automatic mount in your distribution, you can do it manually using the following command:

# mount -t debugfs none /your/debugfs/dir

The Linux kernel provides a very concise API for DEBUGFS, which will be introduced in a real example, and sample code can be downloaded from here.

This implementation will create the following directory structure in Debugfs:

Where a corresponds to a U8 type of variable in the module, B and subdir the following C is a character array in the corresponding module, but they are implemented differently.

In Module_init, we first set up the root directory mydebug:

1 my_debugfs_root = debugfs_create_dir("mydebug", NULL);

The first parameter is the name of the directory, and the second parameter specifies the parent directory of the directory, and if it is null, it is placed in the root directory of the Debugfs.

Subdirectories are also implemented with Debugfs_create_dir:

1 sub_dir = debugfs_create_dir("subdir", my_debugfs_root);

The code for building file A is very simple:

1 debugfs_create_u8("a", 0644, my_debugfs_root, &a);

This means that the file name is "a", the file attribute is 0644, and the parent directory is the "Mydebug" created above, and the corresponding variable is a in the module.

The Linux kernel also provides additional APIs for creating Debugfs files, see the appendix to this article.

b is an array of 32-bytes characters, in Debugfs, arrays can be implemented with BLOB wrapper.

123456 charhello[32] = "Hello world!\n";struct debugfs_blob_wrapper b; b.data = (void*)hello;b.size = strlen(hello) + 1;debugfs_create_blob("b", 0644, my_debugfs_root, &b);

It is important to note that the data defined by the Blob wrapper can only be read-only. In this example, although we set the permission of file B to 0644, the actual file is still read-only, and if you attempt to overwrite the file, the system will prompt an error.

If you need to write to the kernel array, blob wrapper will not be able to meet the requirements, we can only do this through our own definition of file operations. In this practice, you can refer to the implementation of file C. C and B correspond to the same block of characters in the module, except that B is read-only and C is read and written at the same time by a custom file operation.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 staticintc_open(structinode *inode, structfile *filp){    filp->private_data = inode->i_private;    return0;}staticssize_t c_read(structfile *filp, char__user *buffer,        size_tcount, loff_t *ppos){    if(*ppos >= 32)        return0;    if(*ppos + count > 32)        count = 32 - *ppos;    if (copy_to_user(buffer, hello + *ppos, count))        return-EFAULT;    *ppos += count;    returncount;}staticssize_t c_write(struct file *filp, constchar__user *buffer,        size_tcount, loff_t *ppos){    if(*ppos >= 32)        return0;    if(*ppos + count > 32)        count = 32 - *ppos;    if(copy_from_user(hello + *ppos, buffer, count))        return-EFAULT;    *ppos += count;     returncount;}structfile_operations c_fops = {    .owner = THIS_MODULE,    .open = c_open,    .read = c_read,    .write = c_write,};debugfs_create_file("c", 0644, sub_dir, NULL, &c_fops);

Note: In the code, C_open does not actually have any use, because C_read and c_write directly refer to the global variable hello. Here, we can also change the wording, in the Read/write function with Filp->private_data to refer to the character array hello.

Here, three files and subdirectories have been created. In Module_exit, we have to remember to release the created data.

1 debugfs_remove_recursive(my_debugfs_root);

Debugfs_remove_recursive can help us to gradually remove each assigned dentry, and if you want a manual removal, you can also call Debugfs_remove directly.

Appendix:

Create and revoke directories and files

123456 struct dentry *debugfs_create_dir(constchar*name, structdentry *parent);structdentry *debugfs_create_file(constchar*name, mode_t mode,         struct dentry *parent, void*data,         conststructfile_operations *fops);voiddebugfs_remove(structdentry *dentry);voiddebugfs_remove_recursive(struct dentry *dentry);

Create a single-value file

1234567891011121314151617181920 structdentry *debugfs_create_u8(constchar*name, mode_t mode,         structdentry *parent, u8 *value);structdentry *debugfs_create_u16(const char*name, mode_t mode,         structdentry *parent, u16 *value);structdentry *debugfs_create_u32(constchar*name, mode_t mode,         structdentry *parent, u32 *value);structdentry *debugfs_create_u64(constchar*name, mode_t mode,         structdentry *parent, u64 *value);structdentry *debugfs_create_x8(constchar*name, mode_t mode,         structdentry *parent, u8 *value);structdentry *debugfs_create_x16(constchar*name, mode_t mode,         structdentry *parent, u16 *value);structdentry *debugfs_create_x32(constchar*name, mode_t mode,         structdentry *parent, u32 *value);structdentry *debugfs_create_size_t(constchar*name, mode_t mode,         struct dentry *parent, size_t*value);structdentry *debugfs_create_bool(constchar*name, mode_t mode,         structdentry *parent, u32 *value);

Where the three functions suffix x8, x16, and x32 refer to the data in Debugfs in hexadecimal notation.

Create Blob file

1234567 structdebugfs_blob_wrapper {    void*data;    unsigned longsize;};structdentry *debugfs_create_blob(constchar *name, mode_t mode,          structdentry *parent, structdebugfs_blob_wrapper *blob);

Other

12345 structdentry *debugfs_rename(structdentry *old_dir, structdentry *old_dentry,         structdentry *new_dir, constchar*new_name);structdentry *debugfs_create_symlink(constchar*name,         struct dentry *parent, constchar*target);

Debugfs in the Linux kernel

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.