目录
假设不考虑libc的因素,malloc分配100Byte,那么实际上内核是为其分配100Byte吗?
假设使用printf打印指针bufA和bufB指向的地址是一样的,那么在内核中这两块虚拟内存是否“打架”了呢?
pages_min、pages_high、pages_low
链接
-
链接可以认为是一个目录项,其中除了指向文件名的指针,并不存在其他数据。
-
目标文件删除时,符号链接仍然继续保存。
-
对每个符号链接都使用了一个独立的inode。相应inode的数据段包含了一个字符串,给出了链接目标的路径。
文件系统各组件的关系
处理器查询页表的过程
-
处理器根据页表基地址控制寄存器TTBCR和虚拟地址来判断使用哪个页表基地址寄存器,是TTBR0还是TTBR1。页表基地址寄存器中存放着一级页表的 基地址。
-
处理器根据虚拟地址的bit[31:20]作为索引值,在一级页表中找到页表项,一级页表一共有4096个页表项。
-
第一级页表的表项中存放有二级页表的物理基地址。处理器根据虛拟地址的bit[19:12]作为索引值,在二级页表中找到相应的页表项,二级页表有256个页表项。
-
二级页表的页表项里存放有4KB页的物理基地址,因此处理器就完成了页表的查询和翻译工作。
cache的一致性
MESI协议。
总线监听协议依赖于这样的事实,即所有的总线传输事务对于系统内所有的其他单元是可见的,因为总线是一个基于广播通信的介质,因而可以由每个处理器的 cache来进行监听。
内存管理大致流程
-
当了解物理内存和物理页面时,会接触到struct pg_ data_ t、struct zone和struct page等数据结构,这3个数据结构描述了系统中物理内存的组织架构。struct page数据结构除了描述一个4KB大小(或者其他大小)的物理页面外,还包含很多复杂而有趣的成员。
-
当了解怎么分配物理页面时,会接触到伙伴系统机制和页面分配器(pageallocator),页面分配器是内存管理中最复杂的代码之一。
-
有了物理内存,那怎么和虚拟内存建立映射关系呢?在Linux内核中,描述进程的虚拟内存用struct vm_area_struct 数据结构。虚拟内存和物理内存采用建立页表的方法来完成建立映射关系。为什么和进程地址空间建立映射的页面有的叫匿名页面,而有的叫pagecache页面呢?
-
当了解malloc()怎么分配出物理内存时,会接触到缺页中断,缺页中断也是内存管理中最复杂的代码之一。
-
这时,虚拟内存和物理内存已经建立了映射关系,这是以页为基础的,可是有时内核需要小于一个页面大小的内存,那么slab机制就诞生了。
-
上面已经建立起虚拟内存和物理内存的基本框图,但是如果用户持续分配和使用内存导致物理内存不足了怎么办?此时页面回收机制和反向映射机制就应运而生了。
-
虚拟内存和物理内存的映射关系经常是建立后又被解除了,时间长了,系统物理页面布局变得凌乱不堪,碎片化严重,这时内核如果需要分配大块连续内存就会变得很困难,那么内存规整机制(Memory Compaction)就诞生了。
如果采用页表映射的方式,段映射表就变成一级映射表(在Linux内核中称为PGD),其表项提供的不再是物理段地址,而是二级页表的基地址。32位虚拟地址的高12位(bit[31:20])作为访问一级页表的索引值,找到相应的表项,每个表项指向一个二级页表。以虚拟地址的次8位(bit[19:12])作为访问二级页表的索引值,得到相应的页表项,从这个页表项中找到20位的物理页面地址。最后将这20位物理页面地址和虚拟地址的低12位拼凑在一起,得到最终的32位物理地址。