设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

探索 Linux 内存模型--转(4)

发布时间:2021-01-23 22:10 所属栏目:118 来源:网络整理
导读:pgd 表中的每一条目都指向一个页框,其中中包含了一组 pmd 条目;pdm 表中的每个条目又指向一个页框,其中包含一组 pte 条目;pde 表中的每个条目再指向一个页框,其中包含的是用户数据。如果正在查找的页已转出,

pgd 表中的每一条目都指向一个页框,其中中包含了一组 pmd 条目;pdm 表中的每个条目又指向一个页框,其中包含一组 pte 条目;pde 表中的每个条目再指向一个页框,其中包含的是用户数据。如果正在查找的页已转出,那么就会在 pte 表中存储一个交换条目,(在缺页的情况下)以定位将哪个页框重新加载到内存中。

图 8 说明我们连续为各级页表添加偏移量来映射对应的页框条目。我们通过进入作为分段单元输出的线性地址,再划分该地址来获得偏移量。要将线性地址划分成对应的每个页表元素,需要在内核中使用不同的宏。本文不详细介绍这些宏,下面我们通过图 8 来简单看一下线性地址的划分方式。

具有不同地址长度的线性地址

Linux 为内核代码和数据结构预留了几个页框。这些页永远不会?被转出到磁盘上。从 0x0 到 0xc0000000 (PAGE_OFFSET) 的线性地址可由用户代码和内核代码进行引用。从?PAGE_OFFSET?到 0xffffffff 的线性地址只能由内核代码进行访问。

这意味着在 4 GB 的内存空间中,只有 3 GB 可以用于用户应用程序。

Linux 进程使用的分页机制包括两个阶段:

    在启动时,系统为 8 MB 的物理内存设置页表。
  • 然后,第二个阶段完成对其余物理地址的映射。

在启动阶段,startup_32()?调用负责对分页机制进行初始化。这是在 arch/i386/kernel/head.S 文件中实现的。这 8 MB 的映射发生在PAGE_OFFSET?之上的地址中。这种初始化是通过一个静态定义的编译时数组 (swapper_pg_dir) 开始的。在编译时它被放到一个特定的地址(0x00101000)。

这种操作为在代码中静态定义的两个页 ——?pg0?和?pg1?—— 建立页表。这些页框的大小默认为 4 KB,除非我们设置了页大小扩展位(有关 PSE 的更多内容,请参阅??一节)。这个全局数组所指向的数据地址存储在?cr3?寄存器中,我认为这是为 Linux 进程设置分页单元的第一阶段。其余的页项是在第二阶段中完成的。

第二阶段由方法调用?paging_init()?来完成。

在 32 位的 x86 架构上,RAM 映射到?PAGE_OFFSET?和由 4GB 上限 (0xFFFFFFFF) 表示的地址之间。这意味着大约有 1 GB 的 RAM 可以在 Linux 启动时进行映射,这种操作是默认进行的。然而,如果有人设置了?HIGHMEM_CONFIG,那么就可以将超过 1 GB 的内存映射到内核上 —— 切记这是一种临时的安排。可以通过调用?kmap()?实现。

我已经向您展示了(32 位架构上的) Linux 内核按照 3:1 的比率来划分虚拟内存:3 GB 的虚拟内存用于用户空间,1 GB 的内存用于内核空间。内核代码及其数据结构都必须位于这 1 GB 的地址空间中,但是对于此地址空间而言,更大的消费者是物理地址的虚拟映射。

之所以出现这种问题,是因为若一段内存没有映射到自己的地址空间中,那么内核就不能操作这段内存。因此,内核可以处理的最大内存总量就是可以映射到内核的虚拟地址空间减去需要映射到内核代码本身上的空间。结果,一个基于 x86 的 Linux 系统最大可以使用略低于 1 GB 的物理内存。

为了迎合大量用户的需要,支持更多内存、提高性能,并建立一种独立于架构的内存描述方法,Linux 内存模型就必须进行改进。为了实现这些目标,新模型将内存划分成分配给每个 CPU 的空间。每个空间都称为一个?节点;每个节点都被划分成一些?区域。区域(表示内存中的范围)可以进一步划分为以下类型:

    ZONE_DMA(0-16 MB):包含 ISA/PCI 设备需要的低端物理内存区域中的内存范围。
  • ZONE_NORMAL(16-896 MB):由内核直接映射到高端范围的物理内存的内存范围。所有的内核操作都只能使用这个内存区域来进行,因此这是对性能至关重要的区域。
  • ZONE_HIGHMEM(896 MB 以及更高的内存):系统中内核不能映像到的其他可用内存。

节点的概念在内核中是使用?struct pglist_data?结构来实现的。区域是使用?struct zone_struct?结构来描述的。物理页框是使用?struct Page?结构来表示的,所有这些?Struct?都保存在全局结构数组?struct mem_map?中,这个数组存储在?NORMAL_ZONE?的开头。节点、区域和页框之间的基本关系如图 9 所示。

节点、区域和页框之间的关系

当实现了对 Pentium II 的虚拟内存扩展的支持(在 32 位系统上使用 PAE —— Physical Address Extension —— 可以访问 64 GB 的内存)和对 4 GB 的物理内存(同样是在 32 位系统上)的支持时,高端内存区域就会出现在内核内存管理中了。这是在 x86 和 SPARC 平台上引用的一个概念。通常这 4 GB 的内存可以通过使用?kmap()?将?ZONE_HIGHMEM?映射到?ZONE_NORMAL?来进行访问。请注意在 32 位的架构上使用超过 16 GB 的内存是不明智的,即使启用了 PAE 也是如此。

(PAE 是 Intel 提供的内存地址扩展机制,它通过在宿主操作系统中使用 Address Windowing Extensions API 为应用程序提供支持,从而让处理器将可以用来寻址物理内存的位数从 32 位扩展为 36 位。)

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读