5

Linux 3.4.6 在 arch/x86/include/asm/segment.h 中定义了以下宏。任何人都可以解释为什么 __USER 宏将 3 添加到定义的常量以及为什么不为 __KERNEL 宏执行此操作?

#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
#define __USER_DS   (GDT_ENTRY_DEFAULT_USER_DS*8+3)
#define __USER_CS   (GDT_ENTRY_DEFAULT_USER_CS*8+3)
4

1 回答 1

6

这四个符号代表段描述符。这些描述符的两个最低有效位包含与它们相关的特权级别,第三个最低有效位包含描述符表类型(GDTLDT)。稍后发生的代码更清楚地说明了这一点:

/* User mode is privilege level 3 */
#define USER_RPL                0x3
/* LDT segment has TI set, GDT has it cleared */
#define SEGMENT_LDT             0x4
#define SEGMENT_GDT             0x0

/* Bottom two bits of selector give the ring privilege level */
#define SEGMENT_RPL_MASK        0x3
/* Bit 2 is table indicator (LDT/GDT) */
#define SEGMENT_TI_MASK         0x4

为此,描述符表条目乘以8,将其向左移动三位,然后OR与表类型和特权级别(使用加法)一起编辑:

/* GDT, ring 0 (kernel mode) */
#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)

/* GDT, ring 3 (user mode) */
#define __USER_CS   (GDT_ENTRY_DEFAULT_USER_CS*8+3)
于 2012-07-31T08:20:01.260 回答