kernel-helloworld-test
diff ktestmodule/ktest.c @ 0:dbbd63da261f
helloworld kernel module and program that reads the /dev/ktest
author | Eleni Maria Stea <eleni@mutantstargoat.com> |
---|---|
date | Wed, 10 May 2017 13:11:31 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ktestmodule/ktest.c Wed May 10 13:11:31 2017 +0300 1.3 @@ -0,0 +1,91 @@ 1.4 +#include <asm/uaccess.h> 1.5 +#include <linux/fs.h> 1.6 +#include <linux/kernel.h> 1.7 +#include <linux/module.h> 1.8 +#include <linux/slab.h> 1.9 + 1.10 +#define DEV_NAME "ktest" 1.11 + 1.12 +static int ktest_init(void); 1.13 +static void ktest_fini(void); 1.14 + 1.15 +static int ktest_open(struct inode *inode, struct file *file); 1.16 +static int ktest_release(struct inode *inode, struct file *file); 1.17 +static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size, 1.18 + loff_t *offset); 1.19 + 1.20 +static int dev_num; 1.21 +static struct file_operations ops = { 1.22 + .open = ktest_open, 1.23 + .release = ktest_release, 1.24 + .read = ktest_read 1.25 +}; 1.26 +static int hello_counter; 1.27 + 1.28 +/* macros */ 1.29 + 1.30 +MODULE_LICENSE("GPL"); 1.31 +MODULE_AUTHOR("hikiko"); 1.32 +MODULE_DESCRIPTION("my kernel helloworld"); 1.33 + 1.34 +module_init(ktest_init); 1.35 +module_exit(ktest_fini); 1.36 + 1.37 +static int ktest_init(void) 1.38 +{ 1.39 + hello_counter = 0; 1.40 + 1.41 + /* register character device */ 1.42 + if((dev_num = register_chrdev(0, DEV_NAME, &ops)) < 0) { 1.43 + printk(KERN_ALERT "Failed to register character device.\n"); 1.44 + return -1; 1.45 + } 1.46 + printk(KERN_INFO "Registered character device. Name: %s number: %d.\n", DEV_NAME, dev_num); 1.47 + return 0; 1.48 +} 1.49 + 1.50 +static void ktest_fini(void) 1.51 +{ 1.52 + unregister_chrdev(dev_num, DEV_NAME); 1.53 + printk(KERN_INFO "Unregistered character device. Name: %s number: %d.\n", DEV_NAME, dev_num); 1.54 +} 1.55 + 1.56 +static int ktest_open(struct inode *inode, struct file *file) 1.57 +{ 1.58 + /* 1 device file only => we ignore the params ^ */ 1.59 + try_module_get(THIS_MODULE); 1.60 + return 0; 1.61 +} 1.62 + 1.63 +static int ktest_release(struct inode *inode, struct file *file) 1.64 +{ 1.65 + module_put(THIS_MODULE); 1.66 + return 0; 1.67 +} 1.68 + 1.69 +static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size, 1.70 + loff_t *offset) 1.71 +{ 1.72 + /* buf = userspace buffer, 1.73 + * kbuf = kernel buffer */ 1.74 + 1.75 + char *kbuf; 1.76 + int bytes; 1.77 + 1.78 + if(!(kbuf = kmalloc(buf_size, GFP_KERNEL))) { 1.79 + printk(KERN_ALERT "Failed to allocate memory.\n"); 1.80 + return -ENOMEM; 1.81 + } 1.82 + 1.83 + /* fill kbuf and copy to userspace buf */ 1.84 + bytes = snprintf(kbuf, buf_size, "Hello world, num: %d.\n", ++hello_counter); 1.85 + 1.86 + if(copy_to_user(buf, kbuf, bytes)) 1.87 + { 1.88 + kfree(kbuf); 1.89 + return -EFAULT; 1.90 + } 1.91 + 1.92 + kfree(kbuf); 1.93 + return bytes; 1.94 +}