T9的空间

You will never walk alone!

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  69 随笔 :: 0 文章 :: 28 评论 :: 0 Trackbacks
From Unix某论坛,忘记名字了...但这段文字从宏观上讲清楚了Linux Memory的构架。
1.
内核初始化:

    *
内核建立好内核页目录页表数据库,假设物理内存大小为len,则建立了[3G--3G+len]::[0--len]这样的虚地址vaddr和物理地址paddr的线性对应关系;
    *
内核建立一个page数组,page数组和物理页面系列完全是线性对应,page用来管理该物理页面状态,每个物理页面的虚地址保存在page->virtual中;
    *
内核建立好一个free_list,将没有使用的物理页面对应的page放入其中,已经使用的就不用放入了;

2.
内核模块申请内存vaddr = get_free_pages(mask,order)

    *
内存管理模块从free_list找到一个page,将page->virtual作为返回值,该返回值就是对应物理页面的虚地址;
    *
pagefree_list中脱离;
    *
模块使用该虚拟地址操作对应的物理内存;

3.
内核模块使用vaddr,例如执行指令mov(eax, vaddr)

    * CPU
获得vaddr这个虚地址,利用建立好的页目录页表数据库,找到其对应的物理内存地址;
    *
eax的内容写入vaddr对应的物理内存地址内;

4.
内核模块释放内存free_pages(vaddr,order)

    *
依据vaddr找到对应的page
    *
将该page加入到free_list中;

5.
用户进程申请内存vaddr = malloc(size)

    *
内存管理模块从用户进程内存空间(0--3G)中找到一块还没使用的空间vm_area_struct(start--end)
    *
随后将其插入到task->mm->mmap链表中;

6.
用户进程写入vaddr(0-3G),例如执行指令mov(eax, vaddr)

    * CPU
获得vaddr这个虚地址,该虚地址应该已经由glibc库设置好了,一定在3G一下的某个区域,根据CR3寄存器指向的current->pgd查当前进程的页目录页表数据库,发现该vaddr对应的页目录表项为0,故产生异常;
    *
在异常处理中,发现该vaddr对应的vm_area_struct已经存在,为vaddr对应的页目录表项分配一个页表;
    *
随后从free_list找到一个page,将该page对应的物理页面物理首地址赋给vaddr对应的页表表项,很明显,此时的vaddrpaddr不是线性对应关系了;
    *
pagefree_list中脱离;
    *
异常处理返回;
    * CPU
重新执行刚刚发生异常的指令mov(eax, vaddr)
    * CPU
获得vaddr这个虚地址,根据CR3寄存器指向的current->pgd,利用建立好的页目录页表数据库,找到其对应的物理内存地址;
    *
eax的内容写入vaddr对应的物理内存地址内;  

7.
用户进程释放内存vaddrfree(vaddr)

    *
找到该vaddr所在的vm_area_struct
    *
找到vm_area_struct:start--end对应的所有页目录页表项,清空对应的所有页表项;
    *
释放这些页表项指向物理页面所对应的page,并将这些page加入到free_list队列中;
    *
有必要还会清空一些页目录表项,并释放这些页目录表项指向的页表;
    *
task->mm->mmap链中删除该vm_area_struct并释放掉;

综合说明:

    *
可用物理内存就是free_list中各page对应的物理内存;
    *
页目录页表数据库的主要目的是为CPU访问物理内存时转换vaddr-->paddr使用,分配以及释放内存时不会用到,但是需要内核内存管理系统在合适时机为CPU建立好该库;
    *
对于用户进程在6中获得的物理页面,有两个页表项对应,一个就是内核页目录页表数据库的某个pte[i ],一个就是当前进程内核页目录页表数据库的某个 pte[j],但是只有一个page和其对应。如果此时调度到其他进程,其他进程申请并访问某个内存,则不会涉及到该物理页面,因为其分配时首先要从 free_list中找一个page,而该物理页面对应的page已经从free_list中脱离出来了,因此不存在该物理页面被其他进程改写操作的情况。内核中通过get_free_pages等方式获取内存时,也不会涉及到该物理页面,原理同前所述。
posted on 2013-12-09 17:42 Torres 阅读(406) 评论(0)  编辑 收藏 引用 所属分类: Useful information

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理