下面的内容不是对0.11内核的讨论。是对更一般的linux的讨论
在保护模式中,逻辑地址由一个16位的段选择子(Segment Selector) 和一个32位的偏移量(Offset)构成,
而段寄存器(Segmentation registers)只能存储16位的段选择子(Segment Selector).
所以为了加快从逻辑地址到线性地址的转换,80x86处理器提供了额外的不可编程(nonprogrammable)寄存器,
每个不可编程寄存器(nonprogrammable register)里面都是一个8字节的段描述符(Segment Descriptor),
这8字节的段描述符是由相应段寄存器(segmentation register)中的段选择子(Segment Selector)决定的。
每次当一个段选择子(Segment Selector)被 加载到一个段寄存器(segmentation register)中时,
相应的段描述符(Segment Descriptor)就会从内存中被加载到相应的不可编程(nonprogrammable)CPU寄存器中。
之后,对段(Segment)的逻辑地址的转换工作就不需要依靠再去访问主内存中的GDT或是LDT了。
因为段描述符(Segment Descriptor)为8字节,
所以它在GDT或者LDT中的相当地址可以通过用 8 乘以 段选择子(Segment Selector)中的那13位来获得。
比如GDT的地址为0x00020000(GDT的地址存储在gdtr寄存器中)并且段选择子(Segment Selector)的那index 的13位 指定的值为2,
于是相应的段描述符的地址就是 0x00020000 + (2 * 8 ) , 结果是0x00020000。
GDT的第一个入口(first entry)永远都被设为0,这就保证了一个空的段选择子(null Segment Selector)会被认为是无效的,
并且引起 processor exception。 GDT中可以存储的最多 8191个 段描述符(Segment descriptors)因为, 2^13 -1 为 8191
[ 本帖最后由 madfrogme 于 2012-9-29 17:27 编辑 ]
在保护模式中,逻辑地址由一个16位的段选择子(Segment Selector) 和一个32位的偏移量(Offset)构成,
而段寄存器(Segmentation registers)只能存储16位的段选择子(Segment Selector).
所以为了加快从逻辑地址到线性地址的转换,80x86处理器提供了额外的不可编程(nonprogrammable)寄存器,
每个不可编程寄存器(nonprogrammable register)里面都是一个8字节的段描述符(Segment Descriptor),
这8字节的段描述符是由相应段寄存器(segmentation register)中的段选择子(Segment Selector)决定的。
每次当一个段选择子(Segment Selector)被 加载到一个段寄存器(segmentation register)中时,
相应的段描述符(Segment Descriptor)就会从内存中被加载到相应的不可编程(nonprogrammable)CPU寄存器中。
之后,对段(Segment)的逻辑地址的转换工作就不需要依靠再去访问主内存中的GDT或是LDT了。
因为段描述符(Segment Descriptor)为8字节,
所以它在GDT或者LDT中的相当地址可以通过用 8 乘以 段选择子(Segment Selector)中的那13位来获得。
比如GDT的地址为0x00020000(GDT的地址存储在gdtr寄存器中)并且段选择子(Segment Selector)的那index 的13位 指定的值为2,
于是相应的段描述符的地址就是 0x00020000 + (2 * 8 ) , 结果是0x00020000。
GDT的第一个入口(first entry)永远都被设为0,这就保证了一个空的段选择子(null Segment Selector)会被认为是无效的,
并且引起 processor exception。 GDT中可以存储的最多 8191个 段描述符(Segment descriptors)因为, 2^13 -1 为 8191
[ 本帖最后由 madfrogme 于 2012-9-29 17:27 编辑 ]
The quieter you become, the more you can hear