summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle K <kylek389@gmail.com>2013-01-22 21:24:28 -0600
committerKyle Kaminski <kyle@kkaminsk.com>2013-01-22 21:24:28 -0600
commit8fdd43b49af70fd8712116b31010c032301a96b4 (patch)
tree0c26a12a33b77ca6ff79ca64b99e3ebb42c62b6b
parent9618a5e3d3104dc92223f7a51283e603cce31628 (diff)
downloadkernelhello-8fdd43b49af70fd8712116b31010c032301a96b4.tar.gz
kernelhello-8fdd43b49af70fd8712116b31010c032301a96b4.tar.bz2
kernelhello-8fdd43b49af70fd8712116b31010c032301a96b4.zip
place a simple /proc, support debug build with Makefile
-rw-r--r--Makefile24
-rw-r--r--debug.c19
-rw-r--r--debug.h1
-rw-r--r--main.c44
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 <linux/module.h>
@@ -27,6 +32,7 @@
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h> /* copy_*_user */
+#include <linux/proc_fs.h>
#include <main.h>
#include <debug.h>
@@ -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");
}