環境: kernel 3.13
test.c
#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 var static 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 next 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) { char buf[BUF_SIZE]; int ret = 0; ret = sprintf(buf, "current kernel time is %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 will show nothing T.T } // global var static 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 *, 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 __user *buffer, size_t count, loff_t *f_pos) { //分配临时缓冲区 char *tmp = kzalloc((count+1), GFP_KERNEL); if (!tmp) return -ENOMEM; //将用户态write的字符串拷贝到内核空间 //copy_to|from_user(to,from,cnt) if (copy_from_user(tmp, buffer, count)) { kfree(tmp); return -EFAULT; } //将str的旧空间释放,然后将tmp赋值给str kfree(str); str = tmp; return count; } // global var static 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" file file = proc_create_data( "jif", // name 0666, // mode NULL, // parent dir_entry &proc_seq_fops, // file_operations NULL // 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
CONFIG_MODULE_SIG=n PWD := $(shell pwd) KVERSION := $(shell uname -r) KERNEL_DIR = /usr/src/linux-headers-$(KVERSION)/ MODULE_NAME = test obj-m := $(MODULE_NAME).o all: make -C $(KERNEL_DIR) M=$(PWD) modules clean: make -C $(KERNEL_DIR) M=$(PWD) cleanref : Here
沒有留言:
張貼留言