kernel_addr = (unsigned long)page_address(page);
kernel_addr += (addr&~PAGE_MASK);
printk("write 0x%lx to address 0x%lx\n", val, kernel_addr);
*(unsigned long *)kernel_addr = val;
put_page(page);
} else {
printk("no vma found for %lx\n", addr);
}
out:
up_read(&mm->mmap_sem);
}
static ssize_t
mtest_write(struct file *file, const char __user * buffer,
size_t count, loff_t * data)
{
printk("mtest_write....\n");
char buf[128];
unsigned long val, val2;
if (count > sizeof(buf))
return -EINVAL;
if (copy_from_user(buf, buffer, count))
return -EINVAL;
if (memcmp(buf, "listvma", 7) == 0)
mtest_dump_vma_list();
else if (memcmp(buf, "findvma", 7) == 0) {
if (sscanf(buf + 7, "%lx", &val) == 1) {
mtest_find_vma(val);
}
}
else if (memcmp(buf, "findpage", 8) == 0) {
if (sscanf(buf + 8, "%lx", &val) == 1) {
mtest_find_page(val);
//my_follow_page(vma, addr);
}
}
else if (memcmp(buf, "writeval", 8) == 0) {
if (sscanf(buf + 8, "%lx %lx", &val, &val2) == 2) {
mtest_write_val(val, val2);
}
}
return count;
}
static struct
file_operations proc_mtest_operations = {
.write = mtest_write
};
static struct proc_dir_entry *mtest_proc_entry;
//整个操作我们以模块的形式实现,因此,模块的初始化和退出函数如下:
static int __init
mtest_init(void)
{
mtest_proc_entry = create_proc_entry("mtest", 0777, NULL);
if (mtest_proc_entry == NULL) {
printk("Error creating proc entry\n");
return -1;
}
printk("create the filename mtest mtest_init sucess \n");
mtest_proc_entry->proc_fops = &proc_mtest_operations;
mtest_dump_vma_list();
return 0;
}
static void
__exit mtest_exit(void)
{
printk("exit the module mtest_exit\n");
remove_proc_entry("mtest", NULL);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("mtest");
MODULE_AUTHOR("Zou Nan hai");
module_init(mtest_init);
module_exit(mtest_exit);