X86寻址.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
X86的寻址机制: 逻辑地址(段+偏移)-线性地址-物理地址 但是在linux中,已经不再使用分段机制,所以第一步由逻辑地址到线性地址转化为直接转化,即逻辑地址和线性地址是一致的,即逻辑地址的偏移量字段的值与相应的线性地址的值总是一致的。 逻辑地址: 这个是针对X86烦人的分段机制使用的,因为在linux中不再使用分段,但是为了与X86硬件的一致,还必须不能绕开这个机制。 逻辑地址:16(index+TI) + 32(offset) 因为我们要求逻辑地址的偏移量字段与线性地址一致,为了达到这个要求,在gdt中各段的起始地址都是0,大小都为4G即可以满足,通过这种方法我们就可以避免使用X86的分段机制。 上图就是用户代码段、用户数据段、内核代码段、内核数据段的段描述符中的内容,关于gdt,每一个CPU有一个。经过上述方案,linux就将逻辑地址的偏移量offset直接变成了32位的线性地址。 Gdt表的三次初始化动作 i386/boot/herder.S--i386/boot/main.c:main() --arch/x86/boot/pm.c:go_to_protected_mode--setup_gdt中 GDT表中的内容 GDT表基址的装载(此时还没有切换到保护模式 切换到保护模式之后,(代码、数据)段寄存器的装载__boot_cs、__boot_ds 注意,其中只是填充了2、3、4项,设置了gdt(以及idt)之后,立刻进入保护模式,并且跳到kernel的入口 )在i386/kernel/head_32.S中 这样整体上设置的与1中设置的效果是一样的,其中__BOOT_DS为3*8所以,gdt段界限,描述符数目*8-1,BOOT_DS=3*8,等于31=0x1F,所以还是四个描述符 3)在i386/kernel/head_32.S中是在开启了页面寻址之后 在我们自己定义的gdt表的初始化过程中,只是需要两次就可以了,比如针对代码段寄存器CS,一次是更新为__boot_cs,另一次是更新为__kernel_cs 线性地址 分页单元把线性地址转化为物理地址,其中关键的任务就是把所请求的访问类型与线性地址的访问权限相比较,如果这次内存访问是无效的,就产生一个缺页异常。 开启分页通过CR0寄存器的PG标志启用。(进入保护模式是CRO的PE位) 注意:CR3存放当前进程页全局目录的地址,当产生缺页时,将地址存放在CR2中,并产生一个缺页异常。 32位的线性地址被分成三个域。 DIRECTORY TABLE OFFSET 每个进程必须有一个分配给它的页目录,所以在进行进程切换的时候,必须切换页目录,将页目录加载到CR3,CR3保存在进程的描述符中。 每个进程都有它自己的页全局目录和自己的页表集合,当进程切换发生时,linux把CR3寄存器的值保存在跟进程相关的一个数据结构中,然后用另外一个进程相应的值填充CR3寄存器。因此,当新进程恢复在CPU上执行时,分页单元将使用一组与新进程对应的页表 内核代码和静态数据结构存放在一组保留的页框中。这些页框所含的页从来不会被动态的分配或者交换到磁盘上 观察0~1MB的使用情况 0x0~0x1000:BIOS使用 0x000a0000~0x000fffff:BIOS例程、VRAM等等 假设内核大小不超过1M,上图就可以代表通常情况下2M的内存空间分布,从上图可以看出实模式代码区是可以用的,但是内核代码(保护模式)是固定的不会被换出。 从链接脚本中可以看到,pg0也就是第0页是存放在bss段之后的。 Page_pde_offset的含义是指的字节偏移大小,所以是__PAGE_OFFSET22 * 4,最后通过CR0的PG位开启分页机制。 我们知道cache缓存了内存中的数据以行为单位,但是并没有反映到线性地址与物理地址上,所以X86还提供了TLB(转换后援缓冲器),这是用来加快线性地址的转换,当该线性地址第一次被使用时,通过转换计算出对应的物理地址,同时,物理地址将存放在TLB entry中,以便以后同一个线性地址的应用可以快速得到转换后的结果。(龙芯中支持)当cpu的CR3(保存了每个进程的gdt地址)改变时(发生进程切换),将主动使本地TLB中的所有项都无效。 注意:对于cache的控制是通过CR0寄存器CD标志位用来启用或禁用高速缓存电路,这个寄存器的NW标志指明高速缓存是使用通写还是回写策略。Linux对于所有的页框都启用高速缓存,对于写操作总是采用回写策略。 物理内存布局 用户态线性地址与实际内存物理地址转换就是通过缺页异常,然后由内存管理分配物理页,将对应关系填充到进程自己的页表中,并没有简单的对应关系。 内核线性地址与实际内存物理地址的转换比较

文档评论(0)

80092355km + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档