gpt4 book ai didi

linux - 为什么Linux有4层 "page tables"以及它到底是如何工作的

转载 作者:太空宇宙 更新时间:2023-11-04 05:41:00 25 4
gpt4 key购买 nike

我正在尝试理解page layouts according to these notes刚刚开始学习操作系统,所以这有点超出我的理解范围。具体来说是这样的:

In linux there are 4 'levels' of page tables. A table consists of an array of entries of type pXX_t, wrapping a pXXval_t:

  1. Page Global Directory (PGD) - pgd_t/pgdval_t.
  2. Page Upper Directory (PUD) - pud_t/pudval_t.
  3. Page Middle Directory (PMD) - pmd_t/pmdval_t.
  4. Page Table Entry directory (PTE) - pte_t/pteval_t.

These types are simply typedef'd wrappers around fundamental architecture-dependent types, gathering all the x86-64 types together...

然后他们画了这个:

    6         5         4         3         2         1
4321098765432109876543210987654321098765432109876543210987654321
0000000000000000000000000000000000000000101100010111000000010000
[ RESERVED ][ PGD ][ PUD ][ PMD ][ PTE ][ OFFSET ]
| | | |-PAGE_SHIFT
| | |-----------PMD_SHIFT
| |--------------------PUD_SHIFT
|---------------------------PGDIR_SHIFT

这仍然超出了我的理解范围,尤其是所有缩写词之类的。

能用稍微温和一点的语言解释一下我们这里到底有什么吗?我想在 JS 操作系统中实现虚拟内存分页,以模拟真实的操作系统。我想知道正在使用哪些结构以及它们在内存本身中的实际外观(或者如果通过汇编完成,则更容易使用解释/教学)。

所以现在我正在尝试弄清楚如何(在 JavaScript 中)使用 1 数组 来管理多个进程的所有内存。没有作弊和使用其他 JavaScript 数组或对象或其他任何东西,只有 1 个数组,然后是整数。我一直试图弄清楚如何在内存中创建一个数组(一段内存),而不使用数组哈哈。然后,为了让它变得更复杂,我需要在这个 1 数组中创建页面,这些页面映射到每个进程允许的内存部分。我正在尝试详细弄清楚如何做到这一点,这些注释是我所见过的最接近现实的注释,但它们有点太详细了。想知道是否可以帮助简化一点解释,并帮助描绘如何在单个数组中创建页面/进程映射的图片。解释这个 Linux 系统将有助于形象化这一点。

最佳答案

<强> This is virtual memory.

具体来说,Linux 在 ISA 上运行时,使用 x86-64 硬件页表布局将一个进程的虚拟地址空间以页粒度映射到物理内存。 Why in 64bit the virtual address are 4 bits short (48bit long) compared with the physical address (52 bit long)?有图表。

它是一个基数树,将地址分成 9 位 block ,具有 12 个页面偏移位。 (12 + 4*9 = 48 位虚拟地址,需要正确符号扩展为 64 位)。 32 位 x86 页表使用 2 级,每级 10 位(12 + 2*10 = 32 位虚拟地址)。

在 TLB 未命中时,硬件会遍历此表以到达 PTE(页表条目),或“无效”条目,在这种情况下会引发 #PF 异常。

<小时/>

从您的其他问题来看,您应该在了解堆栈工作原理等基础知识后,将其放在您的 TODO 列表中很久

只是模拟一个进程,而不是整个系统,所以你只需要考虑它的私有(private)地址空间。在真实的操作系统下,进程的地址空间是虚拟的,直接对应于一个大的JS数组。因此,每个进程都有一个 JS 数组,保存其内存(并单独注册,或作为该数组的一部分)。

这基本上是将虚拟内存留给 JS 实现,因为你是在 JS 上运行,而不是在真实硬件上运行。

除非您正在为某些实际硬件 ISA 编写完整的模拟器,否则这应该就足够了。

CPU 使用专用硬件(TLB)来缓存翻译。在 JS 中,您需要通过映射函数来间接访问每个内存,这会让您的源代码变得非常痛苦。您可以通过使用映射/字典数据结构而不是实际的页面表来使用 TLB 的 JS 版本。

不知道您是否可以使用 try{}catch 执行任何操作来对应页面错误。

也许还可以考虑 TypedArray 来获取同一底层缓冲区的不同“ View ”?我不知道这如何帮助模拟有漏洞的非连续虚拟内存。我认为在 JS 中,你会希望你的“进程”保持其虚拟内存使用相当密集/连续,否则你可能会浪费大量内存(并且不会检测对“未映射”页面的访问)。

关于linux - 为什么Linux有4层 "page tables"以及它到底是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59123308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com