#include #include #include #include #include #include #include #include #define DEVICE_NAME "lkm" #define CLASS_NAME "lkmclass" static int lkm_major; static struct class *lkm_class; static struct device *lkm_device; static int lkm_init(void); static void lkm_exit(void); int lkm_open(struct inode *, struct file *); int lkm_release(struct inode *, struct file *); long lkm_ioctl(struct file *, unsigned int, long unsigned int); static struct file_operations lkm_fops = { .owner = THIS_MODULE, .open = lkm_open, .release = lkm_release, .unlocked_ioctl = lkm_ioctl, }; void is2mb(size_t addr) { unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT; pgd_t *pgd; p4d_t *p4d; pud_t *pud; pmd_t *pmd; pte_t *pte; if (above != 0 && above != -1UL) return 0; pgd = pgd_offset_pgd(_init_top_pgt, addr); if (pgd_none(*pgd)) return 0; p4d = p4d_offset(pgd, addr); if (!p4d_present(*p4d)) return 0; pud = pud_offset(p4d, addr); if (!pud_present(*pud)) return 0; if (pud_large(*pud)) return 0; pmd = pmd_offset(pud, addr); if (!pmd_present(*pmd)) return 0; if (pmd_large(*pmd)) return 1; pte = pte_offset_kernel(pmd, addr); if (pte_none(*pte)) return 0; return 0; } static int lkm_init(void) { printk(KERN_INFO "lkm: init: start\n"); int ret; ret = register_chrdev(0, DEVICE_NAME, &lkm_fops); if (ret < 0) { printk(KERN_ERR "lkm: init: register chrdev failed\n"); return ret; } lkm_major = ret; lkm_class = class_create(CLASS_NAME); if (IS_ERR(lkm_class)) { ret = PTR_ERR(lkm_device); printk(KERN_ERR "lkm: init: create class failed\n"); unregister_chrdev(lkm_major, CLASS_NAME); return ret; } lkm_device = device_create(lkm_class, 0, MKDEV(lkm_major, 0), 0, DEVICE_NAME); if (IS_ERR(lkm_device)) { ret = PTR_ERR(lkm_device); printk(KERN_ERR "lkm: init: create device failed\n"); class_unregister(lkm_class); class_destroy(lkm_class); unregister_chrdev(lkm_major, CLASS_NAME); return ret; } printk(KERN_INFO "lkm: device driver created\n"); printk(KERN_INFO "lkm: init: done\n"); return 0; } static void lkm_exit(void) { printk(KERN_INFO "lkm: exit: start\n"); device_destroy(lkm_class, MKDEV(lkm_major, 0)); class_unregister(lkm_class); unregister_chrdev(lkm_major, DEVICE_NAME); printk(KERN_INFO "lkm: exit: done\n"); } int lkm_open(struct inode *inode, struct file *fp) { printk(KERN_INFO "lkm: open: start\n"); try_module_get(THIS_MODULE); printk(KERN_INFO "lkm: open: done\n"); return 0; } int lkm_release(struct inode *inode, struct file *fp) { printk(KERN_INFO "lkm: release: start\n"); module_put(THIS_MODULE); printk(KERN_INFO "lkm: release: done\n"); return 0; } long lkm_ioctl(struct file *fp, unsigned num, long unsigned int param) { printk(KERN_INFO "lkm: release: start\n"); printk(KERN_INFO "lkm: release: done\n"); return 0; } MODULE_AUTHOR("Mira Chacku Purakal"); MODULE_DESCRIPTION("Generic Module"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); module_init(lkm_init); module_exit(lkm_exit);