diff --git a/study/test/Makefile b/study/proc/create_proc_entry/Makefile similarity index 93% rename from study/test/Makefile rename to study/proc/create_proc_entry/Makefile index b7e1633..22e24b3 100644 --- a/study/test/Makefile +++ b/study/proc/create_proc_entry/Makefile @@ -1,6 +1,6 @@ ifneq ($(KERNELRELEASE),) -obj-m := hello_proc.o +obj-m := jif.o else diff --git a/study/test/README.md b/study/proc/create_proc_entry/README.md similarity index 81% rename from study/test/README.md rename to study/proc/create_proc_entry/README.md index 12bb28e..15ffe6b 100644 --- a/study/test/README.md +++ b/study/proc/create_proc_entry/README.md @@ -3,3 +3,6 @@ http://blog.sina.com.cn/s/blog_8795b0970101ij5d.html echo "Hello from kernel" /proc/proc_test/hello' 读取proc文件内容,将看到屏幕上显示了我们写入的字符串:Hello from kernel cat /proc/proc_test/hello + + +http://blog.csdn.net/a_ran/article/details/37630101 diff --git a/study/test/hello_proc.c b/study/proc/create_proc_entry/hello_proc.c similarity index 79% rename from study/test/hello_proc.c rename to study/proc/create_proc_entry/hello_proc.c index 7f0b4b4..72cb25a 100644 --- a/study/test/hello_proc.c +++ b/study/proc/create_proc_entry/hello_proc.c @@ -9,6 +9,10 @@ char global_buffer[STRINGLEN]; struct proc_dir_entry *example_dir, *proc_hello_file; +int proc_read_hello(char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_write_hello(struct file *file, const char *buffer, unsigned long count, void *data); + + int proc_read_hello(char *page, char **start, off_t off, int count, int *eof, @@ -19,6 +23,7 @@ int proc_read_hello(char *page, char **start, off_t off, int count, int *eof, printk("read success : len = %d, buff = %s\n", len, global_buffer); return len; } +int proc_read_hello(struct file *file, char __user *buff, size_t size, loff_t *ppos) int proc_write_hello(struct file *file, const char *buffer, unsigned long count, void *data) @@ -43,18 +48,18 @@ int proc_write_hello(struct file *file, const char *buffer, unsigned long count, static int __init proc_test_init(void) { example_dir = proc_mkdir("proc_test", NULL); - + printk("Create /proc/proc_test success...\n"); //hello_file = create_proc_entry("hello", S_IRUGO, example_dir); //strcpy(global_buffer, "hello"); //hello_file->read_proc = proc_read_hello; //hello_file->write_proc = proc_write_hello; + static const struct file_operations pid_fops = { .owner = THIS_MODULE, .read = proc_read_hello, .write = proc_write_hello, }; - proc_hello_file = proc_create("hello", 0666, example_dir, &pid_fops); if(proc_hello_file == NULL) @@ -62,7 +67,7 @@ static int __init proc_test_init(void) printk("Can't create /proc/proc_test/hello\n"); remove_proc_entry("proc_test", NULL); } - + printk("Create /proc/proc_test/hello success...\n"); return 0; } diff --git a/study/proc/create_proc_entry/hello_proc.c.bak b/study/proc/create_proc_entry/hello_proc.c.bak new file mode 100644 index 0000000..b9c936a --- /dev/null +++ b/study/proc/create_proc_entry/hello_proc.c.bak @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include + +#define STRINGLEN 81 +char global_buffer[STRINGLEN]; + +struct proc_dir_entry *example_dir, *proc_hello_file; + +int proc_read_hello(char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_write_hello(struct file *file, const char *buffer, unsigned long count, void *data); + + + + +int proc_read_hello(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + int len; + len = sprintf(page, global_buffer); //把global_buffer的内容显示给访问者 + printk("read success : len = %d, buff = %s\n", len, global_buffer); + return len; +} +int proc_read_hello(struct file *file, char __user *buff, size_t size, loff_t *ppos) +int proc_write_hello(struct file *file, const char *buffer, unsigned long count, + void *data) +{ + int len; + + if (count = STRINGLEN) + { + len = STRINGLEN - 1; + } + else + { + len = count; + } + + copy_from_user(global_buffer, buffer, len); + global_buffer[len] = '\0'; + printk("write success : len = %d, buff = %s\n", len, global_buffer); + return len; +} + +static int __init proc_test_init(void) +{ + example_dir = proc_mkdir("proc_test", NULL); + printk("Create /proc/proc_test success...\n"); + //hello_file = create_proc_entry("hello", S_IRUGO, example_dir); + //strcpy(global_buffer, "hello"); + //hello_file->read_proc = proc_read_hello; + //hello_file->write_proc = proc_write_hello; + + static const struct file_operations pid_fops = + { + .owner = THIS_MODULE, + .read = proc_read_hello, + .write = proc_write_hello, + }; + proc_hello_file = proc_create("hello", 0666, example_dir, &pid_fops); + + if(proc_hello_file == NULL) + { + printk("Can't create /proc/proc_test/hello\n"); + remove_proc_entry("proc_test", NULL); + } + printk("Create /proc/proc_test/hello success...\n"); + return 0; +} + +static void __exit proc_test_exit(void) +{ + remove_proc_entry("hello", example_dir); + remove_proc_entry("proc_test", NULL); +} + +module_init(proc_test_init); +module_exit(proc_test_exit); diff --git a/study/proc/create_proc_entry/jif.c b/study/proc/create_proc_entry/jif.c new file mode 100644 index 0000000..509187c --- /dev/null +++ b/study/proc/create_proc_entry/jif.c @@ -0,0 +1,69 @@ +#include +#include //jiffies +#include +#include //copy_to|from_user() + +static char *str = NULL; + +//proc文件的读函数 +static int my_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int ret = 0; + ret = sprintf(page, "current kernel time is %ld\n", jiffies); + ret += sprintf(page+ret, "str is %s\n", str); + + return ret; +} + +//proc文件的写函数 +static int my_proc_write(struct file *filp, const char __user *buf, unsigned long count, void *data) +{ + //分配临时缓冲区 + char *tmp = kzalloc((count+1), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + //将用户态write的字符串拷贝到内核空间 + //copy_to|from_user(to,from,cnt) + if (copy_from_user(tmp, buf, count)) { + kfree(tmp); + return -EFAULT; + } + + //将str的旧空间释放,然后将tmp赋值给str + kfree(str); + str = tmp; + + return count; +} + + +static int __init my_init(void) +{ + struct proc_dir_entry *file; + + //创建proc文件 + file = create_proc_entry("jif", 0666, NULL); + if (!file) { + printk("Cannot create /proc/jif\n"); + return -1; + } + + //将创建好的文件和读写函数关联在一起 + file->read_proc = my_proc_read; + file->write_proc = my_proc_write; + + return 0; +} + +static void __exit my_exit(void) +{ + //删除proc文件 + remove_proc_entry("jif", NULL); + kfree(str); +} + +module_init(my_init); +module_exit(my_exit); +MODULE_AUTHOR("aran"); +MODULE_LICENSE("GPL"); diff --git a/study/test/test.c b/study/proc/create_proc_entry/test.c similarity index 100% rename from study/test/test.c rename to study/proc/create_proc_entry/test.c diff --git a/study/test/test2.c b/study/proc/create_proc_entry/test2.c similarity index 100% rename from study/test/test2.c rename to study/proc/create_proc_entry/test2.c diff --git a/study/proc/proc_create/Makefile b/study/proc/proc_create/Makefile new file mode 100644 index 0000000..22e24b3 --- /dev/null +++ b/study/proc/proc_create/Makefile @@ -0,0 +1,18 @@ +ifneq ($(KERNELRELEASE),) + +obj-m := jif.o + +else + +#KERNELDIR ?= /lib/modules/$(shell uname -r)/build +KERNELDIR ?= /home/gatieme/Work/Kernel/linux-headers-3.14-desktop/ +PWD := $(shell pwd) + +all: + make -C $(KERNELDIR) M=$(PWD) modules + gcc test.c -o test +clean: + make -C $(KERNELDIR) M=$(PWD) clean + rm -rf ./test + +endif diff --git a/study/proc/proc_create/jif.c b/study/proc/proc_create/jif.c new file mode 100644 index 0000000..ae6b9f2 --- /dev/null +++ b/study/proc/proc_create/jif.c @@ -0,0 +1,93 @@ +#include +#include +#include + +#include // for basic filesystem +#include // for the proc filesystem +#include // for sequence files +#include // for jiffies +#include // for kzalloc, kfree +#include // for copy_from_user + +#define BUF_SIZE 128 + +// global var +static char *str = NULL; + +// seq_operations -> show +static int jif_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 +} + +// file_operations -> write +static ssize_t jif_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; +} + +// seq_operations -> open +static int jif_open(struct inode *inode, struct file *file) +{ + return single_open(file, jif_show, NULL); +} + +static const struct file_operations jif_fops = +{ + .owner = THIS_MODULE, + .open = jif_open, + .read = seq_read, + .write = jif_write, + .llseek = seq_lseek, + .release = single_release, +}; + +// module init +static int __init jif_init(void) +{ + struct proc_dir_entry* jif_file; + + jif_file = proc_create("jif", 0666, NULL, &jif_fops); + if (NULL == jif_file) + { + return -ENOMEM; + } + + return 0; +} + +// module exit +static void __exit jif_exit(void) +{ + remove_proc_entry("jif", NULL); + kfree(str); +} + +module_init(jif_init); +module_exit(jif_exit); + +MODULE_AUTHOR("aran"); +MODULE_LICENSE("GPL"); diff --git a/study/proc/proc_create_data/Makefile b/study/proc/proc_create_data/Makefile new file mode 100644 index 0000000..22e24b3 --- /dev/null +++ b/study/proc/proc_create_data/Makefile @@ -0,0 +1,18 @@ +ifneq ($(KERNELRELEASE),) + +obj-m := jif.o + +else + +#KERNELDIR ?= /lib/modules/$(shell uname -r)/build +KERNELDIR ?= /home/gatieme/Work/Kernel/linux-headers-3.14-desktop/ +PWD := $(shell pwd) + +all: + make -C $(KERNELDIR) M=$(PWD) modules + gcc test.c -o test +clean: + make -C $(KERNELDIR) M=$(PWD) clean + rm -rf ./test + +endif diff --git a/study/proc/proc_create_data/jif.c b/study/proc/proc_create_data/jif.c new file mode 100644 index 0000000..17f4c87 --- /dev/null +++ b/study/proc/proc_create_data/jif.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include + +// 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) +{ + seq_printf(m, "current kernel time is %llu\n", (unsigned long long) get_jiffies_64()); + seq_printf(m, "str is %s\n", str); + + 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");