趣谈 Linux 操作系统
刘超
前网易杭州研究院云计算技术部首席架构师
85458 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 72 讲
趣谈 Linux 操作系统
15
15
1.0x
00:00/00:00
登录|注册

25 | 用户态内存映射:如何找到正确的会议室?

文件映射
匿名映射
缺页异常处理
用户态的页表结构
用户态内存映射函数mmap
课堂练习
TLB(Translation Lookaside Buffer)
用户态内存映射机制

该思维导图由 AI 生成,仅供参考

前面几节,我们既看了虚拟内存空间如何组织的,也看了物理页面如何管理的。现在我们需要一些数据结构,将二者关联起来。

mmap 的原理

在虚拟地址空间那一节,我们知道,每一个进程都有一个列表 vm_area_struct,指向虚拟地址空间的不同的内存块,这个变量的名字叫 mmap
struct mm_struct {
struct vm_area_struct *mmap; /* list of VMAs */
......
}
struct vm_area_struct {
/*
* For areas with an address space and backing store,
* linkage into the address_space->i_mmap interval tree.
*/
struct {
struct rb_node rb;
unsigned long rb_subtree_last;
} 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_chain; /* Serialized by mmap_sem &
* page_table_lock */
struct anon_vma *anon_vma; /* Serialized by page_table_lock */
/* Function pointers to deal with this struct. */
const struct vm_operations_struct *vm_ops;
/* Information about our backing store: */
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
units */
struct file * vm_file; /* File we map to (can be NULL). */
void * vm_private_data; /* was vm_pte (shared mem) */
其实内存映射不仅仅是物理内存和虚拟内存之间的映射,还包括将文件中的内容映射到虚拟内存空间。这个时候,访问内存空间就能够访问到文件里面的数据。而仅有物理内存和虚拟内存的映射,是一种特殊情况。
前面咱们讲堆的时候讲过,如果我们要申请小块内存,就用 brk。brk 函数之前已经解析过了,这里就不多说了。如果申请一大块内存,就要用 mmap。对于堆的申请来讲,mmap 是映射内存空间到物理内存。
另外,如果一个进程想映射一个文件到自己的虚拟内存空间,也要通过 mmap 系统调用。这个时候 mmap 是映射内存空间到物理内存再到文件。可见 mmap 这个系统调用是核心,我们现在来看 mmap 这个系统调用。
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, off)
{
......
error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
......
}
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, pgoff)
{
struct file *file = NULL;
......
file = fget(fd);
......
retval = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff);
return retval;
}
如果要映射到文件,fd 会传进来一个文件描述符,并且 mmap_pgoff 里面通过 fget 函数,根据文件描述符获得 struct file。struct file 表示打开的一个文件。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了虚拟内存空间和物理页面管理的关联,重点介绍了mmap系统调用的实现过程以及用户态缺页异常的处理流程。首先解释了mmap的原理,强调了内存映射不仅涉及虚拟内存和物理内存的映射,还包括将文件内容映射到虚拟内存空间。详细解析了mmap系统调用的实现过程,包括get_unmapped_area函数的作用以及mmap_region函数的内部实现。介绍了用户态缺页异常的处理流程,包括在用户空间中找到访问地址所在的区域vm_area_struct,并调用handle_mm_fault来映射该区域。进一步分析了页表的创建过程,以及对于匿名页和映射到文件的处理方式。通过深入的技术细节和实现原理,为读者提供了对虚拟内存空间和物理页面管理关联的全面理解。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《趣谈 Linux 操作系统》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(43)

  • 最新
  • 精选
  • 活的潇洒
    比起《深入浅出计算机组成原理》和《Linux性能优化实战》的篇幅 本节花了三天,每天不少于2小时,才把笔记做完,估计老师也花费不少时间 day25笔记:https://www.cnblogs.com/luoahong/p/10916458.html

    作者回复: 是啊是啊,理解万岁

    2019-05-29
    3
    23
  • zzuse
    我感觉学得很吃力,调用链太长了

    作者回复: 忽略调用链,记住重点节点,调用链就是为了证明的确这样过去的

    2019-05-24
    2
    18
  • LDxy
    请问老师,内核里面这些复杂的机制的实现,在当初软件开发开始前有详细的设计文档的吗?分布在全球各地的开发者是如何能达成这种复杂设计的共识的呢?这些内核里的函数相互依赖又和底层硬件相关,是如何进行单元测试的呢?

    作者回复: 可以参考一下开源软件的运作模式,要写设计,大牛review,通过后写代码,大牛组成委员会,看够不够资格合并进去,要合并进去就要有相应的测试用例,覆盖率等,有邮件列表,实时对话工具

    2019-05-26
    2
    8
  • 啦啦啦
    这篇看了四五遍,都是看了一半就没看了,这是第一次全部看完这篇文章,发现后半部分比前面好理解

    作者回复: 还是要坚持,一遍不行,再来一遍

    2019-07-21
    5
  • mooneal
    难道堆中数据也是通过匿名映射来获取具体的物理地址?

    作者回复: 对的

    2020-05-21
    2
    2
  • 玉剑冰锋
    分配全局页目录项,赋值给mm_struct的pdg成员变量。这里应该是pgd吧老师?

    作者回复: Page Global Directory,PGD,是的,老是倒

    2019-05-28
    1
  • 一笔一画
    请教下老师,内核线程的task struct上的mm为什么为空?另外看代码还有个active_mm,这个设计上有什么考虑吗?

    作者回复: 内核线程没有用户地址空间。 如果是用户进程,则两者一样。如果是内核线程,没有mm,active_mm指向此时用户态的地址空间。

    2019-05-24
    2
    1
  • youyui
    mmap可以将文件映射到内核态的虚拟内存空间吗?(据说NIO直接内存就是这么实现的)

    作者回复: 内核就不是mmap了

    2019-06-21
  • skye
    请问老师,malloc调用的也是mmap 吗?

    作者回复: 大内存是的

    2019-06-21
  • Geek_49fbe5
    老师,我们平时说的pss应该是指已经分配给进程的物理页面大小的总和吧?那如果运行中有部分页面被swap到了硬盘,此时的pss还把这部分大小算进去吗?

    作者回复: 算进去了。

    2019-06-01
收起评论
显示
设置
留言
43
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部