When doing kernel-driven development, you can use the files under/proc to get the corresponding information for debugging.
Most/proc files are read-only, but to demonstrate the integrity of the sample, a write method is provided.
Method One: Create the proc file using Create_proc_entry (simple, but the write operation has a buffer overflow critical);
Method Two: Use Proc_create and Seq_file to create the proc file (method three concise);
Method Three: Use Proc_create_data and Seq_file to create the proc file (more cumbersome, but more complete);
Demo Example four: Use a demo sample of the kernel list in the proc file (method three).
--------------------------------------------------------------------------------------------------------------- -----
Four
PROC_TEST04.C Source Code
#include <linux/module.h> #include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/ seq_file.h> #include <linux/uaccess.h> #include <linux/slab.h>struct proc_head{struct list_head lhead; int item_count;int str_count;}; struct proc_item{struct list_head litem;char *buf;int num;}; struct Proc_head *gp_head;//linux/seq_file.h//void * (*start) (struct seq_file *m, loff_t *pos);//Void (*stop) (struct Seq_file *m, void *v);//void * (*next) (struct seq_file *m, void *v, loff_t *pos);//Int (*show) (struct seq_file *m, voi D *v);/*** author:aran* fuction:seq_operations, start*/static void *my_seq_start (struct seq_file *m, loff_t *pos) { struct Proc_item *entry;if (0 = = *pos) {seq_printf (M, "List have%d items, total%d bytes\n", Gp_head->item_count, Gp_hea D->str_count);} Get first Item++*pos;list_for_each_entry (entry, &gp_head->lhead, litem) {if (*pos = = Entry->num) {return Entry;}} return NULL;} /*** author:aran* Fuction:seq_operatIons-next*/static void *my_seq_next (struct seq_file *m, void *v, loff_t *pos) {struct Proc_item *entry;//get Next it Em++*pos;list_for_each_entry (entry, &gp_head->lhead, litem) {if (*pos = = entry->num) {return entry;}} return NULL;} /*** author:aran* fuction:seq_operations-stop*/static void my_seq_stop (struct seq_file *m, void *v) {//clean sth. Nothing to do}/*** author:aran* fuction:seq_operations-show*/static int my_seq_show (struct seq_file *m, void * V) {struct Proc_item *tmp = v;seq_printf (M, "%s", tmp->buf); return 0;} Global varstatic struct Seq_operations my_seq_fops = {. start= my_seq_start,.next= my_seq_next,.stop= my_seq_stop,. show= my_seq_show,};//file_operations//Int (*open) (struct inode *, struct file *)//ssize_t (*write) (struct file *, CO NST Char __user *, size_t, loff_t *)/*** author:aran* fuction:file_operations-open*/static int Proc_seq_open (stru CT inode *inode, struct file *file) {return Seq_open (file, &my_seq_fops);} /** * author:aran* fuction:file_operations, write*/static ssize_t proc_seq_write (struct file *file, const char __user *buffer, size_t count, loff_t *f_pos) {struct Proc_item *tmp;int ret;//Allocate proc_itemtmp = (struct Proc_item *) Kzallo C (sizeof (*TMP), gfp_kernel); if (NULL = = tmp) {ret =-enomem;goto err_kzalloc1;} Init_list_head (&tmp->litem);//Allocate str BUFTMP->BUF = (char *) Kzalloc (count, Gfp_kernel); if (NULL = = tmp-& GT;BUF) {ret =-enomem;goto err_kzalloc2;} if (0! = Copy_from_user (tmp->buf, buffer, count)) {ret = -1;goto err_copy;} List_add (&tmp->litem, &gp_head->lhead); Gp_head->item_count++;gp_head->str_count + = count;tmp- >num = gp_head->item_count; Return Count;err_copy:kfree (TMP->BUF); Err_kzalloc2:kfree (TMP); err_kzalloc1:return ret;} Global varstatic struct File_operations proc_seq_fops = {. owner= this_module,.open= proc_seq_open,.read= Seq_read,. write= proc_seq_write,.llseek= seq_lseek,.release= seq_release,};static int __init my_init (void) {struct proc_dir_entry *file;int ret;//Allocate & init proc_headgp_head = (struct Proc_head *) Kzalloc (siz EOF (*gp_head), gfp_kernel); if (NULL = = gp_head) {ret =-enomem;goto err_kzalloc;} Gp_head->item_count = 0;gp_head->str_count = 0;init_list_head (&gp_head->lhead);//create "/PROC/PROC_ Seq "filefile = Proc_create_data (" Proc_seq ",//name0666,//modenull,//parent dir_entry&proc_seq_fops,//File_ operationsnull//data), if (NULL = = file) {PRINTK ("Count not create/proc/proc_seq file!\n"); ret = -1;goto Err_proc_create_ data;} Return 0;err_proc_create_data:kfree (Gp_head); err_kzalloc:return ret;} static void __exit my_exit (void) {struct Proc_item *tmp1, *tmp2;remove_proc_entry ("Proc_seq", NULL); List_for_each_ Entry_safe (TMP1, TMP2, &gp_head->lhead,litem) {List_del (&tmp1->litem); Kfree (TMP1->BUF); Kfree ( TMP1);} Kfree (Gp_head);} Module_init (My_init); Module_exit (My_exit); Module_author ("Aran"); Module_license ("GPL");
Makefile File:
obj-m:= proc_test04.okernel:=/lib/modules/' uname-r '/build #for mint/ubuntu#kernel:=/lib/modules/' uname-r '/source # For Redhatall:make-c $ (KERNEL) m= ' pwd ' modulesinstall:make-c $ (KERNEL) m= ' pwd ' modules_installdepmod-aclean:make-c $ (K Ernel) m= ' pwd ' clean
Test Results:
Ubuntu/linux Mint Three ways to create a proc file (iv)