xv6 bootstrap 代码中如何理解下面的代码?
How to understand the following code in xv6 bootstrap code?
代码:
#define SEG(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
我知道这是一个段描述符结构。
但我不明白代码:((lim) >> 12 & 0xffff)
为什么要右移12位?
我需要帮助。
原因很陈旧。描述符在286中是8个字节,在286 16位保护模式下,limit曾经被编码成16位。当 386 出现时,描述符没有加宽——每个条目仍然是 8 个字节。但是,space 不足以使用 32 位对段基数和段限制进行编码 - 因此现在使用 20 位对限制进行编码。
对于如何解释 20 位限制有 2 个选项 - 4K 的倍数或字节 - 这称为粒度。 4K 模式是一个很好的折衷方案,与 386 的 4K 页面大小一起工作得很好——当你使用超过 1M 的限制时,你很可能也在使用虚拟内存,然后你会在边缘丢失整个页面无论如何。
给宏的限制以字节表示,除以 4096 (>> 12
) 得到页面粒度限制。
代码:
#define SEG(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
我知道这是一个段描述符结构。
但我不明白代码:((lim) >> 12 & 0xffff)
为什么要右移12位?
我需要帮助。
原因很陈旧。描述符在286中是8个字节,在286 16位保护模式下,limit曾经被编码成16位。当 386 出现时,描述符没有加宽——每个条目仍然是 8 个字节。但是,space 不足以使用 32 位对段基数和段限制进行编码 - 因此现在使用 20 位对限制进行编码。
对于如何解释 20 位限制有 2 个选项 - 4K 的倍数或字节 - 这称为粒度。 4K 模式是一个很好的折衷方案,与 386 的 4K 页面大小一起工作得很好——当你使用超过 1M 的限制时,你很可能也在使用虚拟内存,然后你会在边缘丢失整个页面无论如何。
给宏的限制以字节表示,除以 4096 (>> 12
) 得到页面粒度限制。