kernel-helloworld-test

annotate 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
rev   line source
eleni@0 1 #include <asm/uaccess.h>
eleni@0 2 #include <linux/fs.h>
eleni@0 3 #include <linux/kernel.h>
eleni@0 4 #include <linux/module.h>
eleni@0 5 #include <linux/slab.h>
eleni@0 6
eleni@0 7 #define DEV_NAME "ktest"
eleni@0 8
eleni@0 9 static int ktest_init(void);
eleni@0 10 static void ktest_fini(void);
eleni@0 11
eleni@0 12 static int ktest_open(struct inode *inode, struct file *file);
eleni@0 13 static int ktest_release(struct inode *inode, struct file *file);
eleni@0 14 static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size,
eleni@0 15 loff_t *offset);
eleni@0 16
eleni@0 17 static int dev_num;
eleni@0 18 static struct file_operations ops = {
eleni@0 19 .open = ktest_open,
eleni@0 20 .release = ktest_release,
eleni@0 21 .read = ktest_read
eleni@0 22 };
eleni@0 23 static int hello_counter;
eleni@0 24
eleni@0 25 /* macros */
eleni@0 26
eleni@0 27 MODULE_LICENSE("GPL");
eleni@0 28 MODULE_AUTHOR("hikiko");
eleni@0 29 MODULE_DESCRIPTION("my kernel helloworld");
eleni@0 30
eleni@0 31 module_init(ktest_init);
eleni@0 32 module_exit(ktest_fini);
eleni@0 33
eleni@0 34 static int ktest_init(void)
eleni@0 35 {
eleni@0 36 hello_counter = 0;
eleni@0 37
eleni@0 38 /* register character device */
eleni@0 39 if((dev_num = register_chrdev(0, DEV_NAME, &ops)) < 0) {
eleni@0 40 printk(KERN_ALERT "Failed to register character device.\n");
eleni@0 41 return -1;
eleni@0 42 }
eleni@0 43 printk(KERN_INFO "Registered character device. Name: %s number: %d.\n", DEV_NAME, dev_num);
eleni@0 44 return 0;
eleni@0 45 }
eleni@0 46
eleni@0 47 static void ktest_fini(void)
eleni@0 48 {
eleni@0 49 unregister_chrdev(dev_num, DEV_NAME);
eleni@0 50 printk(KERN_INFO "Unregistered character device. Name: %s number: %d.\n", DEV_NAME, dev_num);
eleni@0 51 }
eleni@0 52
eleni@0 53 static int ktest_open(struct inode *inode, struct file *file)
eleni@0 54 {
eleni@0 55 /* 1 device file only => we ignore the params ^ */
eleni@0 56 try_module_get(THIS_MODULE);
eleni@0 57 return 0;
eleni@0 58 }
eleni@0 59
eleni@0 60 static int ktest_release(struct inode *inode, struct file *file)
eleni@0 61 {
eleni@0 62 module_put(THIS_MODULE);
eleni@0 63 return 0;
eleni@0 64 }
eleni@0 65
eleni@0 66 static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size,
eleni@0 67 loff_t *offset)
eleni@0 68 {
eleni@0 69 /* buf = userspace buffer,
eleni@0 70 * kbuf = kernel buffer */
eleni@0 71
eleni@0 72 char *kbuf;
eleni@0 73 int bytes;
eleni@0 74
eleni@0 75 if(!(kbuf = kmalloc(buf_size, GFP_KERNEL))) {
eleni@0 76 printk(KERN_ALERT "Failed to allocate memory.\n");
eleni@0 77 return -ENOMEM;
eleni@0 78 }
eleni@0 79
eleni@0 80 /* fill kbuf and copy to userspace buf */
eleni@0 81 bytes = snprintf(kbuf, buf_size, "Hello world, num: %d.\n", ++hello_counter);
eleni@0 82
eleni@0 83 if(copy_to_user(buf, kbuf, bytes))
eleni@0 84 {
eleni@0 85 kfree(kbuf);
eleni@0 86 return -EFAULT;
eleni@0 87 }
eleni@0 88
eleni@0 89 kfree(kbuf);
eleni@0 90 return bytes;
eleni@0 91 }