`
spartan1
  • 浏览: 365974 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ucore-project5: mm(2)

 
阅读更多

看内核刚进入时加载临时gdt的代码:

lgdt __gdtdesc - KERNBASE

.data
gdt:
...
__gdtdesc:
    .word 0x17
    .long gdt-KERNBASE

 

其中KERNBASE = 0xC0000000。在lgdt指令中,使用了__gdtdesc的真实物理地址,而在__gdtdesc中,使用了gdt的真实物理地址。其中lgdt指令中的__gdtdesc真实地址,应该是要经过段式处理的,而__gdtdesc中的gdt地址呢?是否也需要经过段式处理才能访问呢?

 

查看intel的文档,GDTR/IDTR中的基地址,都是线性地址,LDTR/TR/CS/DS/ES/FS/GS/SS中不可见部分保存的基地址,也都是线性地址。在intel文档中有逻辑地址、线性地址和物理地址三种地址概念,其中逻辑地址包括段选择子和偏移值,逻辑地址经过运算(就是段选择子指定的段描述符中的基地址加上偏移值),将生成一个线性地址,而在启用了分页的情况下,线性地址经过页式转换,最终才生成物理地址。所以只有逻辑地址才需要经过段式处理,而GDTR/IDTR以及一系列存放选择子的段寄存器的不可见部分中保存的是线性地址,也就是无需再次进行段式处理的地址。

 

而CR3中保存的是当前页目录表的“物理地址”,就是说,可以直接拿来用的地址,无需进行段式处理,也无视进行页式处理,直接放到外部总线上就可以访问内存了。

 

可以看出,GDTR、IDTR等寄存器中的线性地址都可以分页,但CR3中的物理地址却不可再分段。这也很好理解,在x86 cpu中,地址都是先经过分段,然后再分页的,分页处理后的地址已经是物理地址了,不能再次进行处理了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics