JOS虚拟内存布局

lab通关记录

MIT-6.828实验通关记录

如何在 JOS 中使用分页(和段)

  • 仅使用段来将权限级别切换到/切换出内核
  • 使用分页来构建进程地址空间
  • 使用分页来限制进程内存访问它自己的地址空间
  • 下面是 JOS 虚拟内存映射
  • 为什么同时映射内核和当前进程?为什么不是每个 4GB?这与 xv6 相比如何?
  • 为什么内核在顶部?
  • 为什么将所有物理内存映射到顶部?即为什么多重映射?
  • (稍后将讨论 UVPT…)
  • 我们如何为不同的进程切换映射?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
   4 Gig -------->  +------------------------------+
| | RW/--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: . :
: . :
: . :
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
| | RW/--
| Remapped Physical Memory | RW/--
| | RW/--
KERNBASE, ----> +------------------------------+ 0xf0000000 --+
KSTACKTOP | CPU0's Kernel Stack | RW/-- KSTKSIZE |
| - - - - - - - - - - - - - - -| |
| Invalid Memory (*) | --/-- KSTKGAP |
+------------------------------+ |
| CPU1's Kernel Stack | RW/-- KSTKSIZE |
| - - - - - - - - - - - - - - -| PTSIZE
| Invalid Memory (*) | --/-- KSTKGAP |
+------------------------------+ |
: . : |
: . : |
MMIOLIM ------> +------------------------------+ 0xefc00000 --+
| Memory-mapped I/O | RW/-- PTSIZE
ULIM, MMIOBASE --> +------------------------------+ 0xef800000
| Cur. Page Table (User R-) | R-/R- PTSIZE
UVPT ----> +------------------------------+ 0xef400000
| RO PAGES | R-/R- PTSIZE
UPAGES ----> +------------------------------+ 0xef000000
| RO ENVS | R-/R- PTSIZE
UTOP,UENVS ------> +------------------------------+ 0xeec00000
UXSTACKTOP -/ | User Exception Stack | RW/RW PGSIZE
+------------------------------+ 0xeebff000
| Empty Memory (*) | --/-- PGSIZE
USTACKTOP ---> +------------------------------+ 0xeebfe000
| Normal User Stack | RW/RW PGSIZE
+------------------------------+ 0xeebfd000
| |
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
. .
. .
. .
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
| Program Data & Heap |
UTEXT --------> +------------------------------+ 0x00800000
PFTEMP -------> | Empty Memory (*) | PTSIZE
| |
UTEMP --------> +------------------------------+ 0x00400000 --+
| Empty Memory (*) | |
| - - - - - - - - - - - - - - -| |
| User STAB Data (optional) | PTSIZE
USTABDATA ----> +------------------------------+ 0x00200000 |
| 空内存 (*) | |
0 ------------> +------------------------------+ --+

UVPT和UVPD

我们有一个很好的页表概念模型,它是一个 2^20 条目的数组,我们可以用物理页号索引。x86 2 级分页方案打破了这一点,将巨型页表分成许多页表和一个页目录。我们想以某种方式取回巨大的概念页表——JOS 中的进程将查看它以弄清楚它们的地址空间中发生了什么。但是具体怎么做呢?

幸运的是,分页硬件非常适合这一点——将一组碎片页面放在一个连续的地址空间中。事实证明,我们已经有一个表,其中包含指向所有碎片页表的指针:就是页目录!

因此,我们可以使用页目录作为页 ,在虚拟地址空间中某个连续的 2^22 字节范围内映射我们概念上的巨型 2^22 字节页表(由 1024 个页面表示)。我们可以通过将 PDE 条目标记为只读来确保用户进程不能修改他们的页表。

问题:我们是否也需要创建单独的 UVPD 映射?


更详细的理解这个设计:

记住 X86 如何将虚拟地址转换为物理地址:

img

CR3 指向页目录。地址的 PDX 部分索引到页目录中,为您提供一个页表。PTX 部分索引到页表中为您提供一个页面,然后您添加低位。

但是处理器没有页目录、页表和页不是普通内存的概念。所以没有什么说内存中的特定页面不能同时用作其中的两个或三个。处理器只跟随指针: 页目录 = lcr3(); 页表 =* (pd+4*PDX); 页 = *(pt+4 * PTX); //注:10位有1024个entry,每个entry4B,每页4KB大小

从图表上看,它从 CR3 开始,沿着三个箭头,然后停止。

如果我们将一个指针放入页面目录中,该指针指向索引 V 处的自身,如

img

然后当我们尝试转换一个 PDX 和 PTX 等于 V 的虚拟地址时,跟随三个箭头将我们留在页目录。这样虚拟页面就会转换为保存页面目录的物理页面。在Jos中,V是0x3BD,所以UVPD的虚拟地址是(0x3BD<<22)|(0x3BD<<12)。

现在,如果我们尝试使用 PDX = V 但任意 PTX != V 来转换虚拟地址,那么跟随来自 CR3 的三个箭头结束比通常早一个级别(而不是最后一种情况中的两个),也就是说页表。因此,PDX=V 的一组虚拟页面形成了一个 4MB 的区域,其页面内容,就处理器而言,就是页表本身。在 Jos 中,V 是 0x3BD,因此 UVPT 的虚拟地址是 (0x3BD<<22)。

因此,由于我们巧妙地插入了页目录中的“无操作”箭头,我们已将用作页目录和页表(通常实际上是不可见的)的页映射到虚拟地址空间中。

注:简单介绍一下这个机制:看页目录那个“回头”的箭头。你会发现“页目录”的中间部分才是真正的页目录,剩下的部分根据第一个页目录entry跳转到头,也是第一个页表的位置。实验中虚拟布局总共整个”页表“大小约定为4MB,你将会在实验代码中看到第一个页目录entry的设置。

然后我们再看偏移。JOS采用了偏移的方式进行找到页目录和页表的物理地址。

这里的0x3BD<<12就是”页目录“,也就是第一个页表的物理地址,(0x3BD<<12)|(0x3BD)是页目录的物理地址。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2020-2024 环烷烃
  • Visitors: | Views:

我很可爱,请我喝一瓶怡宝吧~

支付宝
微信