# Day 17 Physical Memory Model (二)

文件

SPARSEMEM
=========

SPARSEMEM 是 Linux 中最万用的记忆体模型,它也是唯一支援多种进阶功能的记忆体模型,
例如:实体记忆体的热插拔、非挥发性储存装置的替代记忆体映射、和大型系统的延迟初始化记忆体映射。

SPARSEMEM 模型用区段(section)的集合来表示实体记忆体。
一个区段用 struct mem_section 来表示,
而 struct mem_section 中包含 `section_mem_map`,
`section_mem_map` 逻辑上是一个指向 struct page 阵列的指标。
而它还含有一些其他的"魔术"来协助区段管理。
区段的大小和区段的最大数量是由 `SECTION_SIZE_BITS` 和 `MAX_PHYSMEM_BITS` 常数所标示,
这两个常数则是由有支援 SPARSEMEM 模型的架构来各自定义。
`MAX_PHYSMEM_BITS` 是架构所支援的实际实体记忆体宽度,而 `SECTION_SIZE_BITS` 是一个任意值。

区段的最大数量表示为 “NR_MEM_SECTIONS” 和被定义为
.. math::

   NR\_MEM\_SECTIONS = 2 ^ {(MAX\_PHYSMEM\_BITS - SECTION\_SIZE\_BITS)}

`mem_section` 物件是由一个二维阵列称为 `mem_sections` 来管理。
这个阵列的大小和位置取决於在 `CONFIG_SPARSEMEM_EXTREME` 和区段的最大可能数量:

* 当 `CONFIG_SPARSEMEM_EXTREME` 被禁用(disabled)时,
  `mem_sections` 阵列是静态的(static),有 “NR_MEM_SECTIONS” 列(row)。
  每一列存有一个 `mem_section` 物件。

* 当启用 `CONFIG_SPARSEMEM_EXTREME` 时,
  `mem_sections` 阵列是动态分配的。
  每列一包含 PAGE_SIZE 这麽多的 `mem_section` 物件,
  而列的数量则是刚好对应所有的记忆体区段。

架构设置程序码需要呼叫 sparse_init() 来初始化记忆体区段部分和记忆体映射。

SPARSEMEM 中,有两种方法可以将 PFN 转换为相应的`struct page` 
- “classic sparse” 和 “sparse vmemmap”。
使用哪种方法是在编译时进行的,它由 `CONFIG_SPARSEMEM_VMEMMAP` 的值来决定。

classic sparse 将分页的区段号码编码在 page->flags 中,
并使用 PFN 的高位元来存取映射该分页框的区段。
在区段内,PFN 是分页阵列的索引。

sparse vmemmap 使用虚拟的记忆体映射来优化 pfn_to_page 和 page_to_pfn。
有一个全域的 `struct page *vmemmap` 指标指向一个连续的 `struct page` 物件阵列,
PFN 是该阵列的索引,而 `vmemmap` 到 `struct page` 的偏移量是该分页的 PFN。

要使用 vmemmap,支援的架构必须保留一个范围的虚拟位址,
这段虚拟位址会映射含有记忆体映射的实体分页,并且确保 `vmemmap` 指向该范围。
此外,该架构需要实做 :c:func:`vmemmap_populate`,
它将分配实体记忆体并为虚拟记忆体映射创造分页表。
如果架构没有任何特殊的 vmemmap 映射需求,
可以使用通用记忆体管理提供的 :c:func:`vmemmap_populate_basepages`。

虚拟映射的记忆体映射允许在非挥发性储存装置上的域先分配记忆体中储存 `struct page` 物件。
该储存用 struct vmem_altmap 表示且最终通过一长串的函数呼叫传递给 vmemmap_populate()。 vmemmap_populate() 的实作可以使用 `vmem_altmap` 以及 :c:func:`vmemmap_alloc_block_buf`
来帮助程序在非挥发性储存装置上分配记忆体映射。

我的理解

  • Each row contains PAGE_SIZE worth of "mem_section" objects 指的是,mem_section 物件数量有 PAGE_SIZE/sizeof(mem_section) 这麽多个。
  • 内文中有提到很多次 virtually mapped memory mapmemory mapphysical pages containing the memory map,还不是太清楚这里的 memory map 指的是什麽~

後记

今天是文件第二部分的翻译,提到 SPARSEMEM、SPARSEMEM 的部分实作要求,以及实作的撇步。
第三部分以及内容整理,我们就留待明日了!感谢各位!


<<:  [Day 21] 使用 Coroutine SendChannel 处理非同步工作

>>:  DAY26 - [React] 登入登出 router

第8天~

上偏加入字串空的 String all =""; 这里多了餐选的,饮料选的,全部...

CSS微动画 - 善加利用伪元素可以做出更多变化

Q: 别人网站上看到的动态效果变化很多,还是引写好的套件(库)进专案吧? A: 只引进一个套件(库...

Day18:亚季军

注意:List.of() 出现在JDK9.0以後,JDK8.0的广大用户是用不到的。 不知道看过这...

Day13【Web】网路攻击:DDoS 之 DNS 递回查询攻击

递回查询 Recursive Query 『递回查询』(Recursive Query)是指 当某个...

Day02:咦?啊产品已经上线了,真的要翻新吗

软件开发有个情境或许大家都不陌生: 团队可能接手外包所开发的程序,或是接手团队其他成员所写的程序继续...