免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4816 | 回复: 13
打印 上一主题 下一主题

求助:mmap实现访问内核数据结构 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-13 08:17 |只看该作者 |倒序浏览
需求:实现用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 编辑 ]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2009-02-13 08:54 |只看该作者

回复 #1 hongchunhua 的帖子

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

论坛徽章:
0
3 [报告]
发表于 2009-02-13 09:18 |只看该作者
多谢。
如果我用__get_free_pages获取buff的空间,那么我上面写的模块就好用,但是我现在的目的是想映射内核固定结构体的空间,该怎么做?

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
4 [报告]
发表于 2009-02-13 09:32 |只看该作者

回复 #3 hongchunhua 的帖子

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

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

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
5 [报告]
发表于 2009-02-13 09:51 |只看该作者
原帖由 dreamice 于 2009-2-13 08:54 发表
你看看这篇帖子,应该有参考价值:
http://linux.chinaunix.net/bbs/thread-1044524-1-1.html


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

论坛徽章:
0
6 [报告]
发表于 2009-02-13 09:52 |只看该作者
目前的需求是map一个固定的内核结构体kstat,所以ls说的好像不太可行。

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
7 [报告]
发表于 2009-02-13 10:04 |只看该作者

回复 #6 hongchunhua 的帖子

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

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
8 [报告]
发表于 2009-02-13 10:05 |只看该作者
不一定要get free page,kmalloc一段你需要大小的内才能,然后把你的结构体放到这个地方就ok

论坛徽章:
0
9 [报告]
发表于 2009-02-13 10:11 |只看该作者

回复 #8 dreamice 的帖子

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

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
10 [报告]
发表于 2009-02-13 11:01 |只看该作者

回复 #9 hongchunhua 的帖子

这个完全可行的,我真不知道该怎么跟你说,内存定址了解吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP