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)
Run Code Online (Sandbox Code Playgroud)
这四个符号表示段描述符.这些描述符的两个最低有效位包含与它们相关联的权限级别,第三个最低有效位包含描述符表类型(GDT或LDT).通过稍后发生的代码可以更清楚地看到这一点:
/* 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
Run Code Online (Sandbox Code Playgroud)
为实现此目的,将描述符表条目乘以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)
Run Code Online (Sandbox Code Playgroud)