求助:mmap实现访问内核数据结构
需求:实现用mmap访问内核中的一个结构体。
请问怎么做?2.4内核。
内核中结构体的地址是属于内核虚拟地址?还是?
这是我模仿ldd2写的,但是没有效果:(试图访问buff)
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <asm/page.h>
#define VMA_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
static int simple_major = 0;
/*
* Forwards for our methods.
*/
int simple_open (struct inode *inode, struct file *filp);
int simple_release(struct inode *inode, struct file *filp);
int simple_nopage_mmap(struct file *filp, struct vm_area_struct *vma);
/*
* Our various sub-devices.
*/
/* Device 1 uses nopage */
struct file_operations simple_nopage_ops = {
open: simple_open,
release: simple_release,
mmap: simple_nopage_mmap,
};
#define MAX_SIMPLE_DEV 1
struct file_operations *simple_fops[MAX_SIMPLE_DEV] = {
&simple_nopage_ops,
};
/*
* Open the device; all we have to do here is to up the usage count and
* set the right fops.
*/
int simple_open (struct inode *inode, struct file *filp)
{
unsigned int dev = MINOR(inode->i_rdev);
if (dev >= MAX_SIMPLE_DEV)
return -ENODEV;
filp->f_op = simple_fops[dev];
MOD_INC_USE_COUNT;
return 0;
}
/*
* Closing is even simpler.
*/
int simple_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
/*
* Common VMA ops.
*/
void simple_vma_open(struct vm_area_struct *vma)
{ MOD_INC_USE_COUNT; }
void simple_vma_close(struct vm_area_struct *vma)
{ MOD_DEC_USE_COUNT; }
char buff[4096 * 2];
/*
* The nopage version.
*/
struct page *simple_vma_nopage(struct vm_area_struct *vma,
unsigned long address, int write_access)
{
struct page *pageptr;
printk("betwen 0x%lx pgoff 0x%lx ", address - vma->vm_start, vma->vm_pgoff);
unsigned long physaddr = (((unsigned long)buff >> PAGE_SHIFT) << PAGE_SHIFT) + address - vma->vm_start
+ (vma->vm_pgoff << PAGE_SHIFT);
printk("address: 0x%lx buff: 0x%lx physaddr: 0x%lx\n", address, buff, physaddr);
/*char *tmp = (char *)physaddr + 0x8a0;
int i = 0;
for(; i < 5; i++)
printk("mmap %c", tmp);*/
pageptr = virt_to_page(physaddr);
get_page(pageptr);
return pageptr;
}
static struct vm_operations_struct simple_nopage_vm_ops = {
open: simple_vma_open,
close: simple_vma_close,
nopage: simple_vma_nopage,
};
int simple_nopage_mmap(struct file *filp, struct vm_area_struct *vma)
{
/*unsigned long offset = VMA_OFFSET(vma);
if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC))
vma->vm_flags |= VM_IO;*/
vma->vm_flags |= VM_RESERVED;
vma->vm_ops = &simple_nopage_vm_ops;
simple_vma_open(vma);
printk("mmap\n");
return 0;
}
/*
* Module housekeeping.
*/
static int simple_init(void)
{
int result;
SET_MODULE_OWNER(&simple_nopage_ops);
result = register_chrdev(simple_major, "simple", &simple_nopage_ops);
if (result < 0)
{
printk(KERN_WARNING "simple: unable to get major %d\n", simple_major);
return result;
}
int index = 0;
for(; index < 4096 * 2; index++)
buff[index] = 'a' + index % 26;
if (simple_major == 0)
simple_major = result;
return 0;
}
static void simple_cleanup(void)
{
unregister_chrdev(simple_major, "simple");
}
module_init(simple_init);
module_exit(simple_cleanup);
[ 本帖最后由 hongchunhua 于 2009-2-13 08:58 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
你看看这篇帖子,应该有参考价值:
http://linux.chinaunix.net/bbs/thread-1044524-1-1.html
多谢。
如果我用__get_free_pages获取buff的空间,那么我上面写的模块就好用,但是我现在的目的是想映射内核固定结构体的空间,该怎么做?
你可以先get free page,让这个地址作为你的固定结构体的存储位置,不就可以了?
ps:以后编辑帖子什么的,直接附到下一贴吧
恩,可以参考这篇帖子,哈哈
目前的需求是map一个固定的内核结构体kstat,所以ls说的好像不太可行。
完全可行,只是你自己好好考虑思考一下
不一定要get free page,kmalloc一段你需要大小的内才能,然后把你的结构体放到这个地方就ok
我要映射的结构体是kstat,这个结构体是内核用于统计机器信息的,
struct kernel_stat kstat;
在内核的其他地方都用到了,而且在不停的更新数据,我写一个模块怎么把它放在一个page中?
这个完全可行的,我真不知道该怎么跟你说,内存定址了解吧?