Study notes and personal understanding. If there are any mistakes, please correct me.
Reminder: It is recommended to read the code in the order of the numbers in the comments
Test method: cat /proc/abc_proc
echo any string>/proc/abc_pro (requires root privilege)
/************************************************* An example of using the seq_file interface to implement readable and writable proc files For kernels after 3.10 Author: ZhangN Date: 2015-5-17 *************************************************/ #include <linux/module.h> #include <linux/sched.h> #include <linux/uaccess.h> #include <linux/proc_fs.h> #include <linux/fs.h> #include <linux/seq_file.h> #include <linux/slab.h> static char *str = NULL; /*5, implement the show function The role is to output kernel data to user space will be called on proc file output */ static int my_proc_show(struct seq_file *m, void *v) { /* Functions like printfk cannot be used here A special set of functions to output using seq_file See page 91 of ldd3 for details */ seq_printf(m, "current kernel time is %ld\n", jiffies); seq_printf(m, "str is %s\n", str); return 0; } /*3, implement open and write functions */ static ssize_t my_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *f_pos) { char *tmp = kzalloc((count+1), GFP_KERNEL); if(!tmp) return -ENOMEM; if(copy_from_user(tmp, buffer, count)) { kfree(tmp); return EFAULT; } kfree(str); str = tmp; return count; } static int my_proc_open(struct inode *inode, struct file *file) { /*4, call single_open in the open function to bind the seq_show function pointer It should be noted that the seq interface introduced in ldd3 uses this to call the seq_open function Its calling form is as follows: return sep_open(file, &scull_seq_ops); scull_seq_ops is a struct seq_operations structure Bind the show function pointer in the structure Need to prepare seq_operations structure To call the single_open function, you only need to directly specify the function pointer of show. Personal guess may be that the seq_operations structure is implemented in the single_open function As for whether it is not known, I did not check the specific implementation Interested students can refer to the document: Documentation\filesystems\seq_file.txt Regarding the third parameter, its type should be viod*, NULL passed in some places in the kernel, inode->i_private passed in in some places, and other values passed in Let's see how data is used in the single_open function: if (!res) ((struct seq_file *)file->private_data)->private = data; data is a private member of the seq_file structure. So how is data actually used? It is found that the first parameter of the show function is of type seq_file. In the show function, You can convert the private member of seq_file to the corresponding type for use. That is, the data parameter can be passed to the show function through the private member of seq_file */ return single_open(file, my_proc_show, NULL); } /*2, fill in the flie_operations structure called in the proc_create function The function at the beginning of my is the function implemented by itself, The beginning of seq and single is a good function for the kernel, just fill it in directly open is a function that must be filled See page 93 of ldd3 here for details */ static struct file_operations my_fops = { .owner = THIS_MODULE, .open = my_proc_open, .release = single_release, .read = seq_read, .llseek = seq_lseek, .write = my_proc_write, }; static int __init my_init(void) { struct proc_dri_entry *file; /* New interface for the kernel's proc file after 3.10 Need to associate file_operations*/ /*1, first call the function that creates the proc file, you need to bind flie_operations*/ file = proc_create("abc_proc", 0644, NULL, &my_fops); if(!file) return -ENOMEM; return 0; } /*6, delete the proc file */ static void __exit my_exit(void) { remove_proc_entry("abc_proc", NULL); kfree(str); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("ZhangN");