proc_demo
Makefile
12345678910 KVERS = $(shell uname -r)# Kernel modulesobj-m += proc.o# Specify flags for the module compilation.#EXTRA_CFLAGS=-g -O0build: kernel_moduleskernel_modules: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modulesclean: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
1 2 3 4 5 6 7 8 9 10 | KVERS = $(shell uname -r)# Kernel modulesobj-m += proc.o# Specify flags for the module compilation.#EXTRA_CFLAGS=-g -O0build: kernel_moduleskernel_modules: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modulesclean: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean |
proc.c
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 #include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/version.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <asm/uaccess.h>static unsigned int variable;static struct proc_dir_entry *test_dir, *test_entry;#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)static int test_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data){ unsigned int *ptr_var = data; return sprintf(buf, "test_rw = %u\n", *ptr_var);}static int test_proc_write(struct file *file, const char *buffer, unsigned long count, void *data){ unsigned int *ptr_var = data; *ptr_var = simple_strtoul(buffer, NULL, 10); return count;}#elsestatic int test_proc_show(struct seq_file *seq, void *v){ unsigned int *ptr_var = seq->private; seq_printf(seq, "%u\n", *ptr_var); return 0;}static ssize_t test_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos){ struct seq_file *seq = file->private_data; unsigned int *ptr_var = seq->private; int err; char *kbuffer; if (!buffer || count > PAGE_SIZE - 1) return -EINVAL; kbuffer = (char *)__get_free_page(GFP_KERNEL); if (!kbuffer) return -ENOMEM; err = -EFAULT; if (copy_from_user(kbuffer, buffer, count)) goto out; kbuffer[count] = '\0'; *ptr_var = simple_strtoul(kbuffer, NULL, 10); return count;out: free_page((unsigned long)buffer); return err;}static int test_proc_open(struct inode *inode, struct file *file){ return single_open(file, test_proc_show, PDE_DATA(inode));}static const struct file_operations test_proc_fops ={ .owner = THIS_MODULE, .open = test_proc_open, .read = seq_read, .write = test_proc_write, .llseek = seq_lseek, .release = single_release,};#endifstatic __init int test_proc_init(void){ test_dir = proc_mkdir("test_dir", NULL); if (test_dir) {#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) test_entry = create_proc_entry("test_rw", 0666, test_dir); if (test_entry) { test_entry->nlink = 1; test_entry->data = &variable; test_entry->read_proc = test_proc_read; test_entry->write_proc = test_proc_write; return 0; }#else test_entry = proc_create_data("test_rw",0666, test_dir, &test_proc_fops, &variable); if (test_entry) return 0;#endif } return -ENOMEM;}module_init(test_proc_init);static __exit void test_proc_cleanup(void){ remove_proc_entry("test_rw", test_dir); remove_proc_entry("test_dir", NULL);}module_exit(test_proc_cleanup);MODULE_AUTHOR("Barry Song <baohua@kernel.org>");MODULE_DESCRIPTION("proc exmaple");MODULE_LICENSE("GPL v2");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/version.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <asm/uaccess.h>static unsigned int variable;static struct proc_dir_entry *test_dir, *test_entry;#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)static int test_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data){ unsigned int *ptr_var = data; return sprintf(buf, "test_rw = %u\n", *ptr_var);}static int test_proc_write(struct file *file, const char *buffer, unsigned long count, void *data){ unsigned int *ptr_var = data; *ptr_var = simple_strtoul(buffer, NULL, 10); return count;}#elsestatic int test_proc_show(struct seq_file *seq, void *v){ unsigned int *ptr_var = seq->private; seq_printf(seq, "%u\n", *ptr_var); return 0;}static ssize_t test_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos){ struct seq_file *seq = file->private_data; unsigned int *ptr_var = seq->private; int err; char *kbuffer; if (!buffer || count > PAGE_SIZE - 1) return -EINVAL; kbuffer = (char *)__get_free_page(GFP_KERNEL); if (!kbuffer) return -ENOMEM; err = -EFAULT; if (copy_from_user(kbuffer, buffer, count)) goto out; kbuffer[count] = '\0'; *ptr_var = simple_strtoul(kbuffer, NULL, 10); return count;out: free_page((unsigned long)buffer); return err;}static int test_proc_open(struct inode *inode, struct file *file){ return single_open(file, test_proc_show, PDE_DATA(inode));}static const struct file_operations test_proc_fops ={ .owner = THIS_MODULE, .open = test_proc_open, .read = seq_read, .write = test_proc_write, .llseek = seq_lseek, .release = single_release,};#endifstatic __init int test_proc_init(void){ test_dir = proc_mkdir("test_dir", NULL); if (test_dir) {#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) test_entry = create_proc_entry("test_rw", 0666, test_dir); if (test_entry) { test_entry->nlink = 1; test_entry->data = &variable; test_entry->read_proc = test_proc_read; test_entry->write_proc = test_proc_write; return 0; }#else test_entry = proc_create_data("test_rw",0666, test_dir, &test_proc_fops, &variable); if (test_entry) return 0;#endif } return -ENOMEM;}module_init(test_proc_init);static __exit void test_proc_cleanup(void){ remove_proc_entry("test_rw", test_dir); remove_proc_entry("test_dir", NULL);}module_exit(test_proc_cleanup);MODULE_AUTHOR("Barry Song <baohua@kernel.org>");MODULE_DESCRIPTION("proc exmaple");MODULE_LICENSE("GPL v2"); |
```
浙公网安备 33010602011771号