• brk() 和 mmap() 内存映射


    参考博文:http://www.cnblogs.com/huxiao-tee/p/4660352.html

    • x86平台下linux进程虚拟地址空间分布(2.6.7以前版本)

        mmap区域与栈区域相对增长,只有1GB连续的虚拟地址空间可用。

    • x86平台下linux进程虚拟地址空间分布(2.6.7以后版本)

    Random stack offset:由于之前栈的地址是固定的,容易被人利用栈溢出进行攻击,这里栈每次有一个偏移量。

    RLIMIT_STACK:向栈中压入数据容量超过栈的容量时,会触发page fault,异常会检测到最近的虚拟地址空间,发现产生异常的地址与栈相邻,会扩大栈的大小(一般是8M)。如果栈被加长,栈针回退时不会再收缩,如果stack overflow则会导致segment fault。

    Memory Mapping Segment:内存映射的位置,一种高效I/O,后面会细说。

    • 对heap的操作函数  brk() 和 sbrk()  

          int brk(void *addr);

        void sbrk(intptr_t increment);

        内核数据结构mm_struct中 start_brk是进程动态分配的起始地址(heap的起始地址),brk 是堆当前最后的地址。      

        首先program break就是当前brk的位置,所以他是数据段初始化结束后heap的第一个位置,而不是heap的尾部。

        sbrk()是库函数,brk()是系统调用,相对于库函数来说一般系统调用会提供相对简单的工作。都是改变brk的值来扩展收缩堆(increment 为负数时收缩)。

    • mmap 映射区函数

       1.基础概念

        mmap 是一种内存映射方法,将一个文件或其他对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址一一对应的关系。内核空间对这块区域的改变也直接反应到用户空间,实现不同进程的文件共享。

        linux内核使用vm_area_struct结构表示一个独立的虚拟内存区域,一个进程使用多个vm_area_struct来分别表示不同类型的虚拟内存区域.

        当vm_area_struct数目较少时,按照升序以单恋表的形式组织结构,在数目较多时使用AVL树来实现。

    v

    mmap函数是创建一个新的vm_area_struct结构,并将其与物理地址相连

       2.  mmap内存映射原理

        分为三个阶段

      • 进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域  

           1>进程在用户空间调用mmap。

           原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

           2>在当前进程的虚拟地址空间中,寻找一段空间满足要求的连续的虚拟地址。

           3>为此虚拟区分配一个vm_area_struct 结构,接着对这个结构的各个域进行初始化

           4>将新建的虚拟结构(vm_area_struct)插入到进程的虚拟地址区的链表或数种。

      • 调用内核空间的系统调用函数mmap(不同于用户空间)实现文件物理地址和进程虚拟地址的一一映射关系 

           5>为映射分配了新的虚拟地址区域后,通过待映射的文件指针,在文件描述符表中找到对应的文件描述符,加入到struct file中 

           6>linux中的file_operation结构中定义了不同事件对应的设备驱动函数,其中有  int mmap(struct file *filp, struct vm_area_struct *vma),其实这个函数就是将用户空间与设备内存相连,也就是对虚拟地址的访问转化为对设备的访问

           7>通过inode模块找到对应的文件,也就是磁盘的物理地址

           8>建立页表,实现文件地址和虚拟地址区域的映射关系。这里只建立了映射关系,主存中没有对应物理地址的数据。

      • 进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到主存的拷贝

           9>进程的读写,通过查询页表发现这一段地址不再物理页面上,引发缺页异常

           10>进行缺页异常判断,申请调页

           11>先判断swap cache中没有没需要访问的内存页,如果没有调用nopage把所缺德页从磁盘装入主存

           12>之后可以进行读写,会有一段时间延迟,调用msync()立即更新。

       3. mmap优点总结

             1>对文件的读取操作跨过了页缓存,减少了数据的拷贝次数,使用内存读取代了I/O操作,提高了文件读取效率。

        2>实现了用户空间和内核空间的高效交互方式

        3>提供进程间共享内存及相互通信方式

        4>实现高效的大规模数据传输

    还有内核的高端内存映射:https://www.cnblogs.com/wuchanming/p/4360277.html

  • 相关阅读:
    Python中如何取字典中的键值
    Python中random模块的用法案例
    Python中模块import的使用案例
    Python中模块的定义及案例
    Python中from … import …语句
    Python中模块调用说明
    Python中模块、类、函数、实例调用案例
    Python中读写文件三部曲
    Python中特殊函数__str__()
    Python--网络编程-----基于UDP协议的套接字不会发生粘包
  • 原文地址:https://www.cnblogs.com/zhangtiezi/p/8431091.html
Copyright © 2020-2023  润新知