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) 得到页面粒度限制。