用于堆栈切换的 TSS 条目
TSS entries for stack switching
我读到 TSS 包含有关寄存器等的信息。现在,我正在尝试实现从内核模式到用户模式并返回的切换。我已阅读英特尔 80386 手册,并正在查看此资源:http://www.brokenthorn.com/Resources/OSDev23.html 了解一般工作流程。他们这样做:
void install_tss (uint32_t idx, uint16_t kernelSS, uint16_t kernelESP) {
//! install TSS descriptor
uint32_t base = (uint32_t) &TSS;
gdt_set_descriptor (idx, base, base + sizeof (tss_entry),
I86_GDT_DESC_ACCESS|I86_GDT_DESC_EXEC_CODE|I86_GDT_DESC_DPL|I86_GDT_DESC_MEMORY,
0);
//! initialize TSS
memset ((void*) &TSS, 0, sizeof (tss_entry));
TSS.ss0 = kernelSS;
TSS.esp0 = kernelESP;
TSS.cs=0x0b;
TSS.ss = 0x13;
TSS.es = 0x13;
TSS.ds = 0x13;
TSS.fs = 0x13;
TSS.gs = 0x13;
//! flush tss
flush_tss (idx * sizeof (gdt_descriptor));
}
我很困惑为什么 RPL = 3
在我的例子中,当我处于用户模式并且我想使用陷阱门进入内核模式时,陷阱门中的 cs 段将具有 RPL 0(16 位段的最后 2 位) 和对应于 cs 段的 GDT 条目也将具有 DPL 0。而且我读到一个层间特权开关开关堆栈(仅??)查看 TSS。我猜上面的代码必须有一个 TSS.ss = 0x10.
注意:我们假设经典的 0x08 = 内核代码,0x10 = 内核数据,....此处的 GDT 结构
TSS 结构有很多字段用于硬件任务切换(例如 TSS.ss
,如果硬件任务,ss
寄存器的内容将是 saved/loaded切换发生了),加上一些用于将任务切换到更高权限级别的字段((例如 (e.g.
TSS.ss0` 用于切换到 CPL=0)。
您正在查看用于硬件任务切换的字段(通常不值得费心,因为软件任务切换速度更快);我猜想有人在其中添加了一些 "hardware task switch compatible" 值(即使它们未被使用)以避免未初始化的值。
相反,您想查看 TSS 的 TSS.esp0
和 TSS.ss0
字段,这是 TSS 中仅有的两个对切换到 CPL=0 很重要的字段(并且可能是您使用过的 TSS 的唯一 2 个字段)。
我读到 TSS 包含有关寄存器等的信息。现在,我正在尝试实现从内核模式到用户模式并返回的切换。我已阅读英特尔 80386 手册,并正在查看此资源:http://www.brokenthorn.com/Resources/OSDev23.html 了解一般工作流程。他们这样做:
void install_tss (uint32_t idx, uint16_t kernelSS, uint16_t kernelESP) {
//! install TSS descriptor
uint32_t base = (uint32_t) &TSS;
gdt_set_descriptor (idx, base, base + sizeof (tss_entry),
I86_GDT_DESC_ACCESS|I86_GDT_DESC_EXEC_CODE|I86_GDT_DESC_DPL|I86_GDT_DESC_MEMORY,
0);
//! initialize TSS
memset ((void*) &TSS, 0, sizeof (tss_entry));
TSS.ss0 = kernelSS;
TSS.esp0 = kernelESP;
TSS.cs=0x0b;
TSS.ss = 0x13;
TSS.es = 0x13;
TSS.ds = 0x13;
TSS.fs = 0x13;
TSS.gs = 0x13;
//! flush tss
flush_tss (idx * sizeof (gdt_descriptor));
}
我很困惑为什么 RPL = 3
在我的例子中,当我处于用户模式并且我想使用陷阱门进入内核模式时,陷阱门中的 cs 段将具有 RPL 0(16 位段的最后 2 位) 和对应于 cs 段的 GDT 条目也将具有 DPL 0。而且我读到一个层间特权开关开关堆栈(仅??)查看 TSS。我猜上面的代码必须有一个 TSS.ss = 0x10.
注意:我们假设经典的 0x08 = 内核代码,0x10 = 内核数据,....此处的 GDT 结构
TSS 结构有很多字段用于硬件任务切换(例如 TSS.ss
,如果硬件任务,ss
寄存器的内容将是 saved/loaded切换发生了),加上一些用于将任务切换到更高权限级别的字段((例如 (e.g.
TSS.ss0` 用于切换到 CPL=0)。
您正在查看用于硬件任务切换的字段(通常不值得费心,因为软件任务切换速度更快);我猜想有人在其中添加了一些 "hardware task switch compatible" 值(即使它们未被使用)以避免未初始化的值。
相反,您想查看 TSS 的 TSS.esp0
和 TSS.ss0
字段,这是 TSS 中仅有的两个对切换到 CPL=0 很重要的字段(并且可能是您使用过的 TSS 的唯一 2 个字段)。