linux虚拟内存管理 之 内存映射

1、内存映射主要是将用户空间的MMAP区域的虚拟地址空间映射到物理内存或者设备内存和IO空间

     主要通过file_operation中的mmap来实现用户空间对设备内存的直接访问。


2、设备缓存与设备内存

      设备缓存:驱动程序分配管理的一段物理内存,是主内存RAM中的一部分。

      设备内存:是设备自带的存贮空间,是设备的一部分

      设备缓存与设备内存之间通常采用DMA方式来传输数据。


3、用户空间MMAP区域

      用户空间对MMAP区域的管理:

      进程task_struct ---->   mm_struct ----->   mmap ----->  struct vm_area_struct 双向链表。


4、struct vm_area_struct

     作用:用来管理用户空间MMAP区域的结构体。

    struct vm_area_struct {

             struct mm_struct   *vm_mm;                                        //当前vm_area_struct对象所表示的虚拟地址空间段所归属的进程虚拟地址空间

             unsigned long    vm_start;                                            //当前虚拟地址段的起始地址

             unsigned long    vm_end;                                              //当前虚拟地址段的结束地址

  

             struct vm_area_struct *vm_next , *vm_prev;               //链表,将struct vm_area_struct对象组织成双向链表


             pgprot_t vm_page_prot;                                              //在进程映射时的页保护属性,主要体现在页目录表项的映射属性中

             unsigned long     vm_flags;                                           //当前虚拟地址段的访问属性


            const struct vm_operations_struct   *vm_ops;               //当前struct vm_area_struct对象上的一组操作集

            ---------------------

}


5、用户空间虚拟地址的布局

      分为传统布局和新式布局

      传统布局的MMAP区域是向上增长的,新式布局的MMAP区域是向下增长的。


6、mmap的调用过程

     void *mmap(void *start, size_t length, int proc, int flags, int fd, off_t offset)

                    |

                    |-------->   sys_mmap_pgoff(unsigned long addr ,unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff)

                                            |

                                            |-------->do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long paoff)

                                                               |

                                                               |--------> get_unmaped_area 获得可用的MMAP区域的虚拟地址

                                                               |--------> mmap_region 将get_unmapped_area获得的地址构建一个struct vm_area_struct对象

                                                                                   |

                                                                                    | --------> file->f_op -> mmap(file, vma)

                                                                                                    int (*mmap)(struct file *, struct vm_area_struct *);

     驱动程序中的mmap所要做的工作是将内核分配的一个MMAP区域(通过struct vm_area_struct传递给mmap)通过页目录也页表操作,映射到相应的物理地址上去。


7、驱动程序中mmap的实现

     内核为了方便mmap的实现,提供了两个函数:

      a、  int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn unsigned long size, pgprot_t prot);
             addr 虚拟地址的起始地址

             size  地址空间大小

             pfn   页框号

             prot  映射时的页保护属性

             remap_pfn_range把虚拟地址映射到pfn开始的一组连续的物理页面上。

       b、io_remap_pfn_range

            一般映射的目标地址是RAM或者是MM空间,使用 remap_pfn_range.

            如果映射的目标地址是IO空间,则使用io_remap_pfn_range


8、munmap

     不用驱动程序来实现。

     munmap -----> sys_munmap ------> do_munmap


                                                                                  


 


你可能感兴趣的:(linux驱动)