From 8fdd43b49af70fd8712116b31010c032301a96b4 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Tue, 22 Jan 2013 21:24:28 -0600 Subject: place a simple /proc, support debug build with Makefile --- Makefile | 24 ++++++++++++++++++------ debug.c | 19 +++++++++++++++++++ debug.h | 1 + main.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index a4b3494..aced26e 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,20 @@ -# causes weird file size, smaller than stripped? -ifeq ($(DEBUG),) - ccflags-y += -g -endif - # Makfile assignments: # := value at right is expanded and assigned at declaration time # = value at right is expanded only when it is used, hence it is a reference # ?= value at right is assigned only if the variable doesn't have a value # -# + +# run following to compile with debug options +# $ DEBUG=1 make +ifneq ($(DEBUG),) + DEBUG_FLAGS = -O0 -g -DHELLO_DEBUG +endif + +# see Documentation/kbuild/makefiles.txt +EXTRA_CFLAGS += $(DEBUG_FLAGS) + +ifneq ($(KERNELRELEASE),) +# call from kernel build system # objects that are part of hello module (hello.o) #hello-objs += main.o debug.o @@ -17,14 +23,20 @@ hello-y += main.o debug.o # .ko module to be created obj-m := hello.o +# normal makefile, not kbuild +else + KERNELDIR ?= /lib/modules/$(shell uname -r)/build # '-C' changes the dir # '-M' causes the the kernel's toplevel Makefile to move back into this dir # before trying to build 'modules' target +# and it informs kbuild that an external module is being built all: make -C $(KERNELDIR) KCPPFLAGS="-I$(CURDIR)" M=$(PWD) modules +endif + kclean: make -C $(KERNELDIR) M=$(PWD) clean diff --git a/debug.c b/debug.c index ab0add8..c1d4529 100644 --- a/debug.c +++ b/debug.c @@ -105,3 +105,22 @@ int hello_debugfs_destroy(struct dentry *dir, struct dentry *file) return 0; } +/* + * Function implementing a read on /proc/hellomem, here we print few fields + * from internal data structure + */ +int hello_read_procmem(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + + struct hello_dev *dev = (struct hello_dev *) data; + + len = sprintf(page, "hello module internal buffer is at: %p, with index of: %lu, " + "buffer starts with: %c\n", dev->hello_buffer, dev->buff_index, + dev->hello_buffer[0]); + + *eof = 1; /* signify that we're done with dumping our internal structure */ + + return len; +} + diff --git a/debug.h b/debug.h index b82662a..69c7830 100644 --- a/debug.h +++ b/debug.h @@ -5,6 +5,7 @@ struct dentry; int hello_debugfs_init(struct dentry **, struct dentry **); int hello_debugfs_destroy(struct dentry *, struct dentry *); +int hello_read_procmem(char *, char **, off_t, int, int *, void *); #endif diff --git a/main.c b/main.c index fcd5732..0ea47c8 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,5 @@ -/* main.c +/* + * main.c * * r/w /dev/helloc0 character device * @@ -16,6 +17,10 @@ * - ssize_t is an int, size_t is unsigned int, be careful * - compile kernel with frame pointers to get better stack readout in case of an oops * + * coding standars: + * - kernel official doc calls for tabs of width of 8, I'm using 4 spaced tab + * - ToDo: run Lindent + * */ #include @@ -27,6 +32,7 @@ #include #include #include /* copy_*_user */ +#include #include #include @@ -42,6 +48,34 @@ struct dentry *debugfs_file = NULL; struct hello_dev *hello_device; +/* + * Use proc filesystem only when we are debugging, since it is discouraged in + * favor of sys filesystem + */ +#ifdef HELLO_DEBUG + +/* + * The proc filesystem is there to allow us to tap into driver's internal data + * structure within a kernel, in our case it will be struct hello_buffer + */ +static void hello_create_proc(void) +{ + /* below function returns a proc_dir_entry that we will ignore, it's ok + * proc_root in fs/proc/root.c:249 is a static variable that will have a + * link to our raed entry + */ + create_proc_read_entry("hellomem", 0 /* default mode */, NULL /* parent dir */, + hello_read_procmem /* function ptr to our read method */, + hello_device /* our dev struct that kernel will pass for us that we will access */); +} + +static void hello_remove_proc(void) +{ + remove_proc_entry("hellomem", NULL); +} + +#endif + static int hello_create_debugfs(void) { int ret = 0; @@ -54,6 +88,8 @@ static int hello_create_debugfs(void) return ret; } + + static ssize_t hello_read(struct file *filp, char __user *buff, size_t count, loff_t *f_pos) { struct hello_dev *dev = filp->private_data; @@ -185,6 +221,9 @@ static int __init hello_init(void) } hello_create_debugfs(); +#ifdef HELLO_DEBUG + hello_create_proc(); +#endif return 0; @@ -197,6 +236,9 @@ static void __exit hello_exit(void) { unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1); hello_debugfs_destroy(debugfs_dir, debugfs_file); +#ifdef HELLO_DEBUG + hello_remove_proc(); +#endif printk(KERN_INFO "[hello] module removed\n"); } -- cgit v1.2.3