# HG changeset patch # User Eleni Maria Stea # Date 1494411091 -10800 # Node ID dbbd63da261fcd4f10c5d39a80a8db3e8c04583f helloworld kernel module and program that reads the /dev/ktest diff -r 000000000000 -r dbbd63da261f .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Wed May 10 13:11:31 2017 +0300 @@ -0,0 +1,9 @@ +syntax:glob +*.swp +*.o +*.cmd +*.ko +*.symvers +*.order +*.mod +*.mod.c diff -r 000000000000 -r dbbd63da261f ktestmodule/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ktestmodule/Makefile Wed May 10 13:11:31 2017 +0300 @@ -0,0 +1,9 @@ +obj-m += ktest.o + +.PHONY: all +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +.PHONY: clean +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff -r 000000000000 -r dbbd63da261f ktestmodule/ktest.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ktestmodule/ktest.c Wed May 10 13:11:31 2017 +0300 @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include + +#define DEV_NAME "ktest" + +static int ktest_init(void); +static void ktest_fini(void); + +static int ktest_open(struct inode *inode, struct file *file); +static int ktest_release(struct inode *inode, struct file *file); +static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size, + loff_t *offset); + +static int dev_num; +static struct file_operations ops = { + .open = ktest_open, + .release = ktest_release, + .read = ktest_read +}; +static int hello_counter; + +/* macros */ + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("hikiko"); +MODULE_DESCRIPTION("my kernel helloworld"); + +module_init(ktest_init); +module_exit(ktest_fini); + +static int ktest_init(void) +{ + hello_counter = 0; + + /* register character device */ + if((dev_num = register_chrdev(0, DEV_NAME, &ops)) < 0) { + printk(KERN_ALERT "Failed to register character device.\n"); + return -1; + } + printk(KERN_INFO "Registered character device. Name: %s number: %d.\n", DEV_NAME, dev_num); + return 0; +} + +static void ktest_fini(void) +{ + unregister_chrdev(dev_num, DEV_NAME); + printk(KERN_INFO "Unregistered character device. Name: %s number: %d.\n", DEV_NAME, dev_num); +} + +static int ktest_open(struct inode *inode, struct file *file) +{ + /* 1 device file only => we ignore the params ^ */ + try_module_get(THIS_MODULE); + return 0; +} + +static int ktest_release(struct inode *inode, struct file *file) +{ + module_put(THIS_MODULE); + return 0; +} + +static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size, + loff_t *offset) +{ + /* buf = userspace buffer, + * kbuf = kernel buffer */ + + char *kbuf; + int bytes; + + if(!(kbuf = kmalloc(buf_size, GFP_KERNEL))) { + printk(KERN_ALERT "Failed to allocate memory.\n"); + return -ENOMEM; + } + + /* fill kbuf and copy to userspace buf */ + bytes = snprintf(kbuf, buf_size, "Hello world, num: %d.\n", ++hello_counter); + + if(copy_to_user(buf, kbuf, bytes)) + { + kfree(kbuf); + return -EFAULT; + } + + kfree(kbuf); + return bytes; +} diff -r 000000000000 -r dbbd63da261f ktestprogram/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ktestprogram/Makefile Wed May 10 13:11:31 2017 +0300 @@ -0,0 +1,9 @@ +obj = kprog.o +CFLAGS = -pedantic -Wall -g + +kprog: $(obj) + $(CC) -o $@ $^ $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) kprog diff -r 000000000000 -r dbbd63da261f ktestprogram/kprog.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ktestprogram/kprog.c Wed May 10 13:11:31 2017 +0300 @@ -0,0 +1,28 @@ +#include +#include +#include + +int main(void) +{ + char buf[512]; + size_t size; + int fd; + + if((fd = open("/dev/ktest", O_RDONLY)) == -1) { + fprintf(stderr, "Failed to open device ktest.\n"); + return 1; + } + + if((size = read(fd, buf, sizeof buf)) == -1) { + fprintf(stderr, "Failed to read from device ktest.\n"); + + close(fd); + return 1; + } + printf("num char: %d\n", (int)size); + + buf[size] = 0; + printf("quoting kernel: %s", buf); + close(fd); + return 0; +}