1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/gfp.h>
#define DEVICE_NAME "ltdevice" #define DEVICE_PATH "/dev/ltdevice" #define CLASS_NAME "ltmodule"
static int major_num; static struct class *module_class = NULL; static struct device *module_device = NULL; struct inode *__inode = NULL; static void *buffer[0x20];
static long ltfall_ioctl(struct file *__file, unsigned int cmd, unsigned long param); static int ltfall_open(struct inode *, struct file *); static int ltfall_release(struct inode *, struct file *); static ssize_t ltfall_read(struct file *__file, char __user *user_buf, size_t size, loff_t *loff); static ssize_t ltfall_write(struct file *__file, const char __user *user_buf, size_t size, loff_t *loff);
static struct file_operations lt_module_fo = { .owner = THIS_MODULE, .unlocked_ioctl = ltfall_ioctl, .open = ltfall_open, .read = ltfall_read, .write = ltfall_write, .release = ltfall_release, };
static int __init kernel_module_init(void) { printk(KERN_ALERT "[ltfall] Module Loaded, Start to Register device...\n");
major_num = register_chrdev(0, DEVICE_NAME, <_module_fo);
if (major_num < 0) { printk(KERN_ALERT "[ltfall] Failed to register a major number.\n"); return major_num; } printk(KERN_ALERT "[ltfall] Register complete, major number : %d.\n", major_num);
module_class = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(module_class)) { unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_ALERT "[ltfall] Failed to register class device!\n"); return PTR_ERR(module_class); } printk(KERN_ALERT "[ltfall] Class device register complete.\n");
module_device = device_create(module_class, NULL, MKDEV(major_num, 0), NULL, DEVICE_NAME); if (IS_ERR(module_device)) { class_destroy(module_class); unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_ALERT "[ltfall] Failed to create the device!\n"); return PTR_ERR(module_device); } printk(KERN_ALERT "[ltfall] Module register complete.\n");
return 0; }
static void __exit kernel_module_exit(void) { printk(KERN_ALERT "[ltfall] Start to clean up the module.\n"); device_destroy(module_class, MKDEV(major_num, 0)); class_destroy(module_class); unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_ALERT "[ltfall] Module clean up complete.\n"); }
static int ltfall_open(struct inode *node, struct file *__file) { printk(KERN_ALERT "[ltfall] Open device successfully!\n"); return 0; }
static int ltfall_release(struct inode *node, struct file *__file) { printk(KERN_ALERT "[ltfall] Release device successfully!\n");
return 0; }
typedef struct { int index; int flag; int size; size_t addr; char *content; } alloc;
static long ltfall_ioctl(struct file *__file, unsigned int cmd, unsigned long param) { alloc *chunk = (alloc *)param; size_t value = 0;
printk(KERN_ALERT "[ltfall] Your choice number is %d.\n", cmd);
if (cmd == 0x10000) { buffer[chunk->index] = kmalloc(chunk->size, chunk->flag); printk(KERN_ALERT "[ltfall] The address of alloc obj is 0x%px.\n", buffer[chunk->index]); value = copy_to_user((char*)&chunk->addr, &buffer[chunk->index], 8); } else if (cmd == 0x10001) { kfree(buffer[chunk->index]); printk(KERN_ALERT "[ltfall] Kfree %d down.\n", chunk->index); } else if (cmd == 0x10002) { size_t address = *(size_t *)chunk->addr; printk(KERN_ALERT "[ltfall] The value of your requiered address 0x%lx is 0x%lx, as %s.\n", chunk->addr, address, (char*)chunk->addr); value = copy_to_user((char*)&(chunk->addr), (char *)&address, 8); } else if (cmd == 0x10003) { value = copy_from_user(buffer[chunk->index], chunk->content, chunk->size); printk(KERN_ALERT "[ltfall] Read Successfully.\n"); } else if (cmd == 0x10004) { value = copy_to_user(chunk->content, buffer[chunk->index], chunk->size); printk(KERN_ALERT "[ltfall] Write Successfully.\n"); }
return 0; }
static ssize_t ltfall_read(struct file *__file, char __user *user_buf, size_t size, loff_t *loff) { return 0; }
static ssize_t ltfall_write(struct file *__file, const char __user *user_buf, size_t size, loff_t *loff) {
return 0; }
module_init(kernel_module_init); module_exit(kernel_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("ltfall");
|