求助:mmap实现访问内核数据结构

发布于 2022-09-23 15:16:51 字数 5952 浏览 17 评论 0

需求:实现用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

脸赞 2022-09-30 15:16:51

你看看这篇帖子,应该有参考价值:
http://linux.chinaunix.net/bbs/thread-1044524-1-1.html

坏尐絯℡ 2022-09-30 15:16:51

多谢。
如果我用__get_free_pages获取buff的空间,那么我上面写的模块就好用,但是我现在的目的是想映射内核固定结构体的空间,该怎么做?

浸婚纱 2022-09-30 15:16:51

你可以先get free page,让这个地址作为你的固定结构体的存储位置,不就可以了?

ps:以后编辑帖子什么的,直接附到下一贴吧

情话难免假 2022-09-30 15:16:51

原帖由 dreamice 于 2009-2-13 08:54 发表
你看看这篇帖子,应该有参考价值:
http://linux.chinaunix.net/bbs/thread-1044524-1-1.html

恩,可以参考这篇帖子,哈哈

做个少女永远怀春 2022-09-30 15:16:51

目前的需求是map一个固定的内核结构体kstat,所以ls说的好像不太可行。

梅倚清风 2022-09-30 15:16:51

完全可行,只是你自己好好考虑思考一下

め七分饶幸 2022-09-30 15:16:51

不一定要get free page,kmalloc一段你需要大小的内才能,然后把你的结构体放到这个地方就ok

我很坚强 2022-09-30 15:16:51

我要映射的结构体是kstat,这个结构体是内核用于统计机器信息的,
struct kernel_stat kstat;
在内核的其他地方都用到了,而且在不停的更新数据,我写一个模块怎么把它放在一个page中?

疑心病 2022-09-30 15:16:51

这个完全可行的,我真不知道该怎么跟你说,内存定址了解吧?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文