X86-64上的Linux VM管理系统

本文探讨了X86-64架构下Linux操作系统如何管理虚拟内存,包括运行模式、地址转换机制、进程地址空间布局及切换等关键技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 前言

X86 指令集是IT业内久经考验并获得最广泛支持的指令集。但传统的32位x86系列产品限制了可用的物理内存总量以及单个进程的地址空间,虽然可用 PAE(page address extension)机制进行扩展,但这只是一种补救措施,并不是一个完美的方案。AMD率先推出的64位x86处理器系列可以支持需要占用较大物理及虚拟存储地址的应用方案,如高性能服务器、数据库管理系统及计算机辅助设计工具等。同时AMD的x86-64与32位的计算架构完全兼容,这使得一方面能确保用户可以改用高性能的64位计算机系统,另一方面又可以保障业界在32位软件方面高达数十乃至数百亿美元的投资。

下面我们就来分析运行于X86-64上的Linux操作系统的虚拟内存管理系统。


2 X86-64的运行模式

X86-64 可以运行在两种模式下,一种是遗传模式,包括传统32位x86系统的四种模式:实模式,保护模式,虚拟8086模式和系统管理模式;另一种是新增的长模式,包括兼容模式和64位模式。各种状态之间的转换通过CR0,CR4控制寄存器(Control Registers),RFLAGS系统标志寄存器(System-flag Registers,遗传模式下对应的是EFLAGS)和EXER扩展功能使能寄存器(Extended-Feature-Enable Register)的某些位进行控制,如图1所示。


图1:x86-64的运行模式转换
图1:x86-64的运行模式转换

X86-64上的Suse Linux 8.0运行于长模式下的64位模式,这种模式的特征是:

  • 通用寄存器扩展为64位,同时增加了8个通用寄存器R8-R15;
  • 增加了8个128位的SSE(streaming SIMD extension)寄存器;
  • 虚地

3 X86-64的虚实地址转换

64位模式下的虚实地址转换有两种方式,一种是采用4K大小页面的普通模式,另外一种是采用2M大小页面super page方式。分别见图2和图3所示。可以看到,64位的X86增加了一级映射 - PML4。


图2:4K页面地址转换
图2:4K页面地址转换

图3:2M 页面地址转换
图3:2M 页面地址转换

一个页面的大小是由CR4寄存器中的的PAE,PSE位以及地址转换表项中PDE的PS位进行控制,具体的对应关系如表1所示。在64位模式下,PAE总是打开的,因而只用4K/2M两种大小的页面。


表1在CR0.PG=1时页面大小
表1在CR0.PG=1时页面大小

4 X86-64的进程地址空间

X86-64 的PML4中的每一项对应着512G地址空间,512项对应256TB地址空间。其地址空间的分布如下: PML4的第1项512GB空间对应着应用程序的用户地址空间;第2项未映射;第3项到第508项是直接映射的区间,即物理地址与虚地址相差一个固定值;第510项是一些IO映射区域;第511项是vmalloc和ioremap对应的区间;最后一项是内核代码以及模块和修复代码的地址空间。由此可见,除去4项之外,内核总共可见的物理地址有508*512G=254TB。新的PAGE_OFFSET现在是0x10000000000。

事实上,512G的用户空间目前来看是十分充足的,而且这使得虚地址空间的管理效率较高,可以想象一下,如果每个进程需要管理254TB虚拟地址空间,想要做到高效管理的难度会有多大。

此外,在Linux的实现中,内核地址空间采用2M页面转换,而用户空间则采用4K页面转换。其初始化的映射表填写代码如下(arch/x86_64/mm/init.c中函数phys_pgd_init):

				for (j = 0; j < PTRS_PER_PMD; pmd++, j++ , paddr += PMD_SIZE) {
unsigned long pe;
if (paddr >= end) {
for (; j < PTRS_PER_PMD; j++, pmd++)
set_pmd(pmd, __pmd(0));
break;
}
pe = _PAGE_PSE | _KERNPG_TABLE | _PAGE_NX | _PAGE_GLOBAL | paddr;
pe &= __supported_pte_mask;
set_pmd(pmd, __pmd(pe));
}

这个函数的调用路径是start_kernel(init/main.c)-> setup_arch(arch/x86_64/kernel/setup.c)-> init_memory_mapping(arch/x86_64/mm/init.c)。



5 地址空间切换

在 32位X86上的进程切换时,需要将PGD的地址装入CR3寄存器以实现地址空间的切换。而从上一节的描述可以看到在64位环境下,PML4中只有第一项是独立于进程自身的,考虑到这一点,Linux在进程切换时只是更新PML4中第一项的值并刷新TLB。其代码在include/asm-x86_64 /mmu_context.h中:

				*read_pda(level4_pgt) = __pa(next->pgd) | _PAGE_TABLE;
__flush_tlb();

这样做有几个好处:

  • 整个系统中所有进程共用一个PML4表,从而节省内存;
  • PML4第一项的值完全等同与32位上PGD的地址,这样,系统中其他部分的代码就可以完全不用考虑地址空间映射的变化,从而实现了最大程度的向后兼容。

6 小结

Linux在X86-64体系结构上VM管理系统的设计是充满技巧的,它考虑到了可用物理以及虚地址空间的限制,效率以及向后兼容性。使得最终既能获得64位的好处,同时开发的工作量也不至于太大。

<think>嗯,用户的问题是关于在Linux环境下为Oracle RAC 11.2.0.4寻找合适的OPatch、DB PSU、JavaVM PSU和GRID PSU补丁包。他们提到了具体的补丁号,比如p6880880、p31537677、p31668908和p31718723。我需要先确认这些补丁是否适用于他们的版本。 首先,OPatch工具p6880880的版本是否正确?根据引用[1],用户之前可能安装过p6880880_112000_Linux-x86-64.zip,但Oracle 11.2.0.4需要OPatch版本至少12.2.0.1.36。这可能意味着他们需要检查当前OPatch版本是否需要升级。如果用户已经安装了旧版本,可能需要先升级OPatch,否则补丁安装会失败。 接下来是DB PSU补丁p31537677_112040_Linux-x86-64。引用[3]中提到了类似的补丁p29255947,但用户提供的补丁号不同,需要确认p31537677是否适用于11.2.0.4。通常,补丁的112040表示适用于11.2.0.4,所以这个应该没问题。但需要用户检查Oracle官方文档或补丁说明中的适用版本。 JavaVM PSU补丁p31668908_112040_Linux-x86-64。同样,这里的112040应该对应11.2.0.4,但需要确认这个补丁是否包含Java虚拟机相关的更新,是否与其他补丁有依赖关系,比如是否需要先安装某个PSU才能应用这个补丁。 GRID PSU补丁p31718723_112040_Linux-x86-64,引用[4]提到GRID PSU需要使用opatch auto方式安装,并且需要ocm.rsp文件。用户需要注意补丁的安装方法是否正确,特别是对于RAC环境,可能需要同时更新所有节点,确保集群的一致性。 另外,用户提供的补丁列表中,OPatch的补丁号是p6880880_1120334,这里可能存在笔误,正确的应该是p6880880_112000,因为引用[1]中提到的版本是112000。需要提醒用户核对补丁号是否正确,避免下载错误的文件。 用户可能还需要按照正确的安装顺序来应用这些补丁。通常,OPatch需要先升级到最新版本,然后按照DB PSU、JavaVM PSU、GRID PSU的顺序安装。每个补丁安装后都需要验证,比如使用opatch lsinventory查看是否成功,或者查询registry$history表(如引用[2]所示)。 此外,用户需要注意补丁之间的兼容性。某些PSU可能已经包含了其他补丁的内容,或者需要特定的补丁作为前置条件。例如,DB PSU可能已经包含了JavaVM的更新,或者需要先应用某个中间补丁。需要建议用户查阅每个补丁的README文件,了解依赖关系和安装步骤。 对于RAC环境,补丁安装可能需要滚动应用,即逐个节点进行,避免服务中断。尤其是GRID PSU的安装,可能需要使用opatch auto命令,如引用[4]所述,并且确保所有节点的配置一致。 最后,用户需要验证补丁安装后的结果,可以通过opatch version检查OPatch版本,通过opatch lsinventory查看已安装的补丁,以及查询数据库的registry$history表(如引用[2]中的示例),确认所有补丁都已正确应用。 总结来说,用户需要确保所有补丁的版本正确,安装顺序正确,遵循Oracle的官方指南,并在安装前后进行充分的验证和备份,以避免系统出现问题。</think>### Oracle RAC 11.2.0.4 补丁包下载与验证步骤 根据您提供的补丁包编号,以下是关键信息整理和操作指导: #### 1. **OPatch 工具更新 (p6880880_1120334_Linux-x86-64)** - **用途**:OPatch 是 Oracle 的补丁管理工具,需先更新至兼容版本。 - **操作步骤**: ```bash unzip /tmp/orasoft/p6880880_1120334_Linux-x86-64.zip -d $ORACLE_HOME $ORACLE_HOME/OPatch/opatch version # 验证版本是否≥12.2.0.1.36[^1] ``` #### 2. **数据库 PSU 补丁 (p31537677_112040_Linux-x86-64)** - **用途**:修复数据库层面的安全漏洞和功能缺陷。 - **安装命令**: ```bash cd /u01/app/31537677 opatch apply # 需设置环境变量 PATH=$ORACLE_HOME/OPatch:$PATH[^3] ``` #### 3. **JavaVM PSU 补丁 (p31668908_112040_Linux-x86-64)** - **用途**:更新 JVM 组件,解决 Java 相关漏洞。 - **依赖关系**:需先安装 DB PSU,避免组件版本冲突[^4]。 #### 4. **GRID PSU 补丁 (p31718723_112040_Linux-x86-64)** - **用途**:修复 Grid Infrastructure 的集群管理问题。 - **特殊要求**: - 需使用 `opatch auto` 模式安装。 - 准备 `ocm.rsp` 响应文件并确保权限正确(属组为 `grid:oinstall`)。 #### 5. **补丁安装后验证** - **数据库层面**: ```sql SELECT ACTION_TIME, COMMENTS FROM registry$history; # 检查补丁时间戳和版本号[^2] ``` - **集群层面**: ```bash crsctl query crs activeversion # 确认 GRID 版本是否更新 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值