#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/printk.h>
#include <linux/mm.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include "fops.h"
#ifdef KBUILD_MODNAME
MODULE_LICENSE("GPL");
#endif
static int major;
static int minor = 0;
static char* raminspect_classname = "raminspect_backend";
static char* raminspect_devname = "raminspect";
static struct class* raminspect_class;
static int perms_uevent(const struct device *dev, struct kobj_uevent_env *env) {
add_uevent_var(env, "DEVMODE=%#o", 0604);
return 0;
}
int raminspect_init(void) {
mutex_init(&modified_addr_list_lock);
mutex_init(&finish_sig_buf_lock);
mutex_init(&saved_regs_buf_lock);
major = register_chrdev(0, raminspect_devname, &raminspect_fops);
if(major < 0) pr_alert("Registering device file failed with code: %d", major);
raminspect_class = class_create(raminspect_classname);
raminspect_class -> dev_uevent = perms_uevent;
device_create(raminspect_class, NULL, MKDEV(major, minor), NULL, raminspect_devname);
return 0;
}
void raminspect_exit(void) {
device_destroy(raminspect_class, MKDEV(major, minor));
class_destroy(raminspect_class);
unregister_chrdev(major, raminspect_devname);
mutex_destroy(&finish_sig_buf_lock);
mutex_destroy(&saved_regs_buf_lock);
mutex_destroy(&modified_addr_list_lock);
if(finish_sig_buf.buffer != NULL) {
kfree(finish_sig_buf.buffer);
}
if(modified_addr_list.buffer != NULL) {
kfree(modified_addr_list.buffer);
}
if(saved_regs_buf.buffer != NULL) {
uintptr_t i;
for(i = 0; i < saved_regs_buf.length; i++) {
kfree((void*)(saved_regs_buf.buffer[i]));
}
kfree(saved_regs_buf.buffer);
}
}
module_init(raminspect_init);
module_exit(raminspect_exit);