Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3520171
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类: LINUX

2014-12-09 10:26:49

vm_area_struct结构在设备驱动中对mmp的实现中会用到。为了优化查找方法,内核维护了
VMA的链表和树型结构,vm_area-struct中很多成员函数都是用来维护这个结构的。因此在驱动程序中不能随意 创建VMA,或者打破这种组织结构。
VMA的作用是用于管理进程地址空间中不同区域的数据结构
下面是这个结构体,红色部分标识了与驱动程序相关的部分,现在只能先做一个感性理解了,作为驱动工程师,应该是个实用主义者。

/*
 * This struct defines a memory VMM memory area. There is one of these
 * per VM-area/task.  A VM area is any part of the process virtual memory
 * space that has a special rule for the page-fault handlers (ie a shared
 * library, the executable area etc).
 */
struct vm_area_struct {
    struct mm_struct * vm_mm;    /* The address space we belong to. */
    unsigned long vm_start;        /* Our start address within vm_mm. */
    unsigned long vm_end;        /* The first byte after our end address
                       within vm_mm. */

    /* linked list of VM areas per task, sorted by address */
    struct vm_area_struct *vm_next;

    pgprot_t vm_page_prot;        /* Access permissions of this VMA. */
    unsigned long vm_flags;        /* Flags, listed below. */
    描述该区域的一段标志,驱动程序最感兴趣的是VM—IO和VM—RESERVED。前者将VMA设置为一个内存映射的I/O区域。后者告诉内存管理系统不要将VMA交换出去,大多数设备映射都设置该标志

    struct rb_node vm_rb;

    /*
     * For areas with an address space and backing store,
     * linkage into the address_space->i_mmap prio tree, or
     * linkage to the list of like vmas hanging off its node, or
     * linkage of vma in the address_space->i_mmap_nonlinear list.
     */
    union {
        struct {
            struct list_head list;
            void *parent;    /* aligns with prio_tree_node parent */
            struct vm_area_struct *head;
        } vm_set;

        struct raw_prio_tree_node prio_tree_node;
    } shared;

    /*
     * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
     * list, after a COW of one of the file pages.  A MAP_SHARED vma
     * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack
     * or brk vma (with NULL file) can only be in an anon_vma list.
     */
    struct list_head anon_vma_node;    /* Serialized by anon_vma->lock */
    struct anon_vma *anon_vma;    /* Serialized by page_table_lock */

    /* Function pointers to deal with this struct. */
    struct vm_operations_struct * vm_ops;

    /* Information about our backing store: */
    unsigned long vm_pgoff;        /* Offset (within vm_file) in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */
    struct file * vm_file;        /* File we map to (can be NULL). */
    void * vm_private_data;        /* was vm_pte (shared mem) */
    驱动程序用来保存自身信息的成员
    unsigned long vm_truncate_count;/* truncate_count or restart_addr */

#ifndef CONFIG_MMU
    atomic_t vm_usage;        /* refcount (VMAs shared if !MMU) */
#endif
#ifdef CONFIG_NUMA
    struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
#endif
};
其中
struct vm_operations_struct * vm_ops;这些操作用来处理进程的需求
定义于下:
/*
 * These are the virtual MM functions - opening of an area, closing and
 * unmapping it (needed to keep files on disk up-to-date etc), pointer
 * to the functions called when a no-page or a wp-page exception occurs. 
 */
struct vm_operations_struct {
    void (*open)(struct vm_area_struct * area);
用来实现VMA的子系统初始化该区域,每次对VMA产生一个新的引用则调用此函数,唯一的例外是发生在MMAP第一次创建VMA时
    void (*close)(struct vm_area_struct * area);//销毁一个VMA
   
 struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type);当进程要访问一个合法的VMA页时,如果该页不在内存中,调用函数
    unsigned long (*nopfn)(struct vm_area_struct * area, unsigned long address);
    int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);

    /* notification that a previously read-only page is about to become
     * writable, if an error is returned it will cause a SIGBUS */
    int (*page_mkwrite)(struct vm_area_struct *vma, struct page *structpage);
#ifdef CONFIG_NUMA
    int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);
    struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
                    unsigned long addr);
    int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
        const nodemask_t *to, unsigned long flags);
#endif
};
阅读(986) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~