Chinaunix首页 | 论坛 | 博客
  • 博客访问: 376182
  • 博文数量: 109
  • 博客积分: 5045
  • 博客等级: 大校
  • 技术积分: 1199
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-08 14:47
文章分类

全部博文(109)

文章存档

2017年(1)

2012年(5)

2011年(10)

2010年(1)

2009年(13)

2008年(29)

2007年(6)

2006年(44)

我的朋友

分类:

2006-05-08 15:16:08

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的运行模式转换 X86-64上的Suse Linux 8.0运行于长模式下的64位模式,这种模式的特征是: 通用寄存器扩展为64位,同时增加了8个通用寄存器R8-R15; 增加了8个128位的SSE(streaming SIMD extension)寄存器; 虚地址变为64位(实际实现只有48位),RIP(取指令寄存器)扩展为64位。 3 X86-64的虚实地址转换 64位模式下的虚实地址转换有两种方式,一种是采用4K大小页面的普通模式,另外一种是采用2M大小页面super page方式。分别见图2和图3所示。可以看到,64位的X86增加了一级映射 - PML4。 图2:4K页面地址转换 图3:2M 页面地址转换 一个页面的大小是由CR4寄存器中的的PAE,PSE位以及地址转换表项中PDE的PS位进行控制,具体的对应关系如表1所示。在64位模式下,PAE总是打开的,因而只用4K/2M两种大小的页面。 表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位的好处,同时开发的工作量也不至于太大。 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的运行模式转换 X86-64上的Suse Linux 8.0运行于长模式下的64位模式,这种模式的特征是: 通用寄存器扩展为64位,同时增加了8个通用寄存器R8-R15; 增加了8个128位的SSE(streaming SIMD extension)寄存器; 虚地址变为64位(实际实现只有48位),RIP(取指令寄存器)扩展为64位。 3 X86-64的虚实地址转换 64位模式下的虚实地址转换有两种方式,一种是采用4K大小页面的普通模式,另外一种是采用2M大小页面super page方式。分别见图2和图3所示。可以看到,64位的X86增加了一级映射 - PML4。 图2:4K页面地址转换 图3:2M 页面地址转换 一个页面的大小是由CR4寄存器中的的PAE,PSE位以及地址转换表项中PDE的PS位进行控制,具体的对应关系如表1所示。在64位模式下,PAE总是打开的,因而只用4K/2M两种大小的页面。 表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位的好处,同时开发的工作量也不至于太大。 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的运行模式转换 X86-64上的Suse Linux 8.0运行于长模式下的64位模式,这种模式的特征是: 通用寄存器扩展为64位,同时增加了8个通用寄存器R8-R15; 增加了8个128位的SSE(streaming SIMD extension)寄存器; 虚地址变为64位(实际实现只有48位),RIP(取指令寄存器)扩展为64位。 3 X86-64的虚实地址转换 64位模式下的虚实地址转换有两种方式,一种是采用4K大小页面的普通模式,另外一种是采用2M大小页面super page方式。分别见图2和图3所示。可以看到,64位的X86增加了一级映射 - PML4。 图2:4K页面地址转换 图3:2M 页面地址转换 一个页面的大小是由CR4寄存器中的的PAE,PSE位以及地址转换表项中PDE的PS位进行控制,具体的对应关系如表1所示。在64位模式下,PAE总是打开的,因而只用4K/2M两种大小的页面。 表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位的好处,同时开发的工作量也不至于太大。
阅读(1231) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~