在Protected Mode下,一个重要的必不可少的数据结构就是gdt(Global Descriptor Table)。 为什么要有gdt?我们首先考虑一下在Real Mode下的编程模型: 在Real Mode下,我们对一个内存地址的访问是通过Segment:Offset的方式来进行的,其中Segment是一个段的Base Address,一个Segment的最大长度是64 KB,这是16-bit系统所能表示的最大长度。而Offset则是相对于此Segment Base Address的偏移量。Base Address+Offset就是一个内存绝...
在Protected Mode下,一个重要的必不可少的数据结构就是gdt(Global Descriptor Table)。 为什么要有gdt?我们首先考虑一下在Real Mode下的编程模型: 在Real Mode下,我们对一个内存地址的访问是通过Segment:Offset的方式来进行的,其中Segment是一个段的Base Address,一个Segment的最大长度是64 KB,这是16-bit系统所能表示的最大长度。而Offset则是相对于此Segment Base Address的偏移量。Base Address+Offset就是一个内存绝...
gdt记录的是gdt表的界限和首地址。
gdt表中的表项包含了代码段的首地址。实模式时可以通过这个首地址找到代码段,保护模式下,给这个首地址加了个外衣,叫选择子,也就是说可以通过选择子找到。
选择子是一个相对于gdt表的首地址的偏移。
代码段就是这样通过gdt找到的。
好久没有看kernel的启动部分代码了,今天在看tim robinson's gdt trick的时候有些吃力了,本来是想翻译来着,但是比较简单,就直接贴过来了,里面掺杂着一些我添加的注释。 //其实下面的关于地址的讨论,有些概念性的错误。 //这里应该注意几个概念:逻辑地址,线性地址,虚拟地址和物理地址。 //逻辑地址:也就是汇编代码中的段选择子+段内偏移形式的表示的地址,例如这里的0x08:highhalf //线性地址,或者是虚拟地址,是经过分...
在linux 2.6内核中,所有的用户代码段共用__usr_cs_,_usr_ds_描述符项,所有的内核区代码共用__kernel_cs_, __kernel_ds_描述符项,那么内核是如何区分各个进程的,gdt的索引又在什么时候用呢?刚看ulk,头疼
大家好,我现在在看linux0.11进程调度的copy_process()函数,有个和gdt,LDT有关的问题想不明白: linux在启动时,在setup阶段会建立gdt并设置gdtR,其中gdt在内存中的布局如下: --------------------- . . . --------------------- 数据&堆栈段描述符 --------------------- 代码段描述符 --------------------- 描述符(NULL) --------------------- ———>局部描述符标LDT0 ----...
在head.S 中加载 gdt 时:[code]cpu_gdt_descr: .word gdt_ENTRIES*8-1 .long cpu_gdt_table[/code][code]ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* 0x0b reserved */ ......[/code]lgdt cpu_gdt_descr 指令加载 gdtr 寄存器(48位),高32位为 cpu_gdt_table 地址,低16位为表大小! 但是在desc.h中:[code]extern struct desc_struct cpu_...