When doing kernel-driven development, you can use the files under/proc to get the appropriate information for debugging.
Most of the files under/proc are read-only, but for the completeness of the example, a write method is provided.
Method One: Use Create_proc_entry to create the proc file (simple, but the write operation has the danger of buffer overflow);
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);
Example four: an example of using a kernel-linked list in a proc file (method three).
--------------------------------------------------------------------------------------------------------------- -----
Three
PROC_TEST03.C Source
#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> #define BUF_SIZE 128//Global varstatic Char *str = null;//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, void *v);/** * author:aran* fuction:seq_operations, start*/static void *my_seq_start (struct seq_file *m, loff_t *pos) {if (0 = = *pos) {++*pos;return (void *) 1;//return anything but null, just for Test}return null;} /*** author:aran* fuction:seq_operations-next*/static void *my_seq_next (struct seq_file *m, void *v, loff_t *pos) {//only once, so no Nextreturn 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) {char buf[buf_size];int ret = 0;ret = sprintf (buf, "Current kernel time was%llu\n", (unsigned long Long) get_jiffies_64 ()); ret + = sprintf (buf + ret, "STR is% s\n ", str); seq_printf (M,"%s ", buf); return 0; //!! Must be 0, or would show nothing t.t}//global varstatic struct seq_operations my_seq_fops = {. start= my_seq_start,.next= m y_seq_next,.stop= my_seq_stop,.show= my_seq_show,};//file_operations//Int (*open) (struct inode *, struct file *)//Ssiz e_t (*write) (struct file *, const char __user *, size_t, loff_t *)/*** author:aran* fuction:file_operations-Open */static int Proc_seq_open (struct 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 __us Er *buffer, size_t count, loff_t *f_pos) {//Allocate temporary buffer char *tmp = Kzalloc ((count+1), gfp_kernel); if (!tmp) return-enomem;//copies the user-state write string to the kernel space//copy_to|from_user (to,from,cnt) if (Copy_from_user (TMP, buffer, count)) {Kfree (TMP); Return-efault;} The old space of Str is freed and the TMP is assigned to Strkfree (str); str = Tmp;return count;} 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;//Create "/proc/proc_seq" Filefile = Proc_create_data ("Jif",//name0666,//modenull,//parent Dir_entry &proc_seq_fops,//file_operationsnull//data), if (NULL = = file) {PRINTK ("Count not create/proc/jif file!\n"); return -enomem;} return 0;} static void __exit my_exit (void) {Remove_proc_entry ("Jif", NULL); Kfree (str);} Module_init (My_init); Module_exit (My_exit); Module_author ("Aran"); Module_license ("GPL");
Makefile File:
obj-m:= proc_test03.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: