查看“Task State Segment”的源代码
←
Task State Segment
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
'''任务状态段''' ('''TSS-Task State Segment''') 是特定于[[IA32_Architecture_Family|IA-32]]和[[X86-64|X86-64]]体系结构的二进制数据结构。 它保存有关任务的信息。 在 '''[[Protected Mode|保护模式]]''' 中,'''TTS'''; 主要适用于 '''[[Context Switching#硬件上下文切换|硬件任务切换]]''',其中每个单独的 '''任务''' 都有自己的 '''TSS'''。 在[[Context Switching#软件上下文切换|软件多任务]]中使用时,通常也会使用一两个,因为它们允许在中断后进入“Ring 0”代码。 在'''[[Long Mode|长模式]]'''中,'''TSS'''具有独立的结构,用于在中断或权限级别更改后更改'''堆栈指针(Stack Pointer)'''。 你必须自己在多任务处理功能中更新 '''TTS''',因为它显然不会自动保存寄存器。 ==保护模式== 对于在硬件任务切换中的使用,'''TSS'''包含程序的状态,包括'''[[CPU Registers x86#通用寄存器|通用寄存器]]'''、'''[[Segment Selector|段选择器]]'''、'''[[CPU Registers x86#通用指针寄存器|指令指针]]'''、'''[[CPU Registers x86#EFLAGS寄存器|EFLAGS寄存器]]'''、'''[[CPU Registers x86#EFLAGS寄存器|EFLAGS寄存器]]'''、'''[[CPU Registers x86#通用寄存器|指令指针]]'''、'''[[CPU Registers x86#EFLAGS寄存器|EFLAGS寄存器]]''' 它包含下面描述的某些其他字段。 {|class="wikitable" |- !style="width: 20%;"| 0x3 !style="width: 20%;"| 0x2 !style="width: 20%;"| 0x1 !style="width: 20%;"| 0x0 !style="width: 20%;"| Offset |- |colspan=4 style="text-align: center;"| '''SSP''' !0x68 |- |colspan=2 style="text-align: center;"| '''IOPB''' |colspan=2 style="text-align: center;"| Reserved !0x64 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''LDTR''' !0x60 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''GS''' !0x5C |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''FS''' !0x58 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''DS''' !0x54 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''SS''' !0x50 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''CS''' !0x4C |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''ES''' !0x48 |- |colspan=4 style="text-align: center;"| '''EDI''' !0x44 |- |colspan=4 style="text-align: center;"| '''ESI''' !0x40 |- |colspan=4 style="text-align: center;"| '''EBP''' !0x3C |- |colspan=4 style="text-align: center;"| '''ESP''' !0x38 |- |colspan=4 style="text-align: center;"| '''EBX''' !0x34 |- |colspan=4 style="text-align: center;"| '''EDX''' !0x30 |- |colspan=4 style="text-align: center;"| '''ECX''' !0x2C |- |colspan=4 style="text-align: center;"| '''EAX''' !0x28 |- |colspan=4 style="text-align: center;"| '''EFLAGS''' !0x24 |- |colspan=4 style="text-align: center;"| '''EIP''' !0x20 |- |colspan=4 style="text-align: center;"| '''CR3''' !0x1C |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''SS2''' !0x18 |- |colspan=4 style="text-align: center;"| '''ESP2''' !0x14 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''SS1''' !0x10 |- |colspan=4 style="text-align: center;"| '''ESP1''' !0x0C |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''SS0''' !0x08 |- |colspan=4 style="text-align: center;"| '''ESP0''' !0x04 |- |colspan=2 style="text-align: center;"| Reserved |colspan=2 style="text-align: center;"| '''LINK''' !0x00 |} * '''LINK:''' 上一个任务链接字段。 包含前一任务的'''TSS'''的'''Segment Selector'''。 * '''SS0, SS1, SS2:''' 当权限级别从较低权限级别更改为较高权限级别时,用于加载堆栈的'''Segment Selectors'''。 * '''ESP0, ESP1, ESP2:''' '''Stack Pointers'''用于在权限级别从较低的权限级别更改为较高的权限级别时加载堆栈。 * '''IOPB:''' I/O映射基址字段。 包含从 '''TSS''' 的基地址到'''I/O Permission Bit Map'''的16位偏移量。 * '''SSP:''' Shadow Stack Pointer. ==长模式== 在 '''[[Long Mode|长模式]]'''中,'''TSS'''不存储有关任务执行状态的信息,而是用于存储'''中断堆栈表(Interrupt Stack Table)'''。 {|class="wikitable" |- !style="width: 20%;"| 0x3 !style="width: 20%;"| 0x2 !style="width: 20%;"| 0x1 !style="width: 20%;"| 0x0 !style="width: 20%;"| Offset |- |colspan=2 style="text-align: center;"| '''IOPB''' |colspan=2 style="text-align: center;"| Reserved !0x64 |- |colspan=4 style="text-align: center;"| Reserved !0x60 |- |colspan=4 style="text-align: center;"| Reserved !0x5C |- |colspan=4 style="text-align: center;"| '''IST7''' (High) !0x58 |- |colspan=4 style="text-align: center;"| '''IST7''' (Low) !0x54 |- |colspan=4 style="text-align: center;"| '''IST6''' (High) !0x50 |- |colspan=4 style="text-align: center;"| '''IST6''' (Low) !0x4C |- |colspan=4 style="text-align: center;"| '''IST5''' (High) !0x48 |- |colspan=4 style="text-align: center;"| '''IST5''' (Low) !0x44 |- |colspan=4 style="text-align: center;"| '''IST4''' (High) !0x40 |- |colspan=4 style="text-align: center;"| '''IST4''' (Low) !0x3C |- |colspan=4 style="text-align: center;"| '''IST3''' (High) !0x38 |- |colspan=4 style="text-align: center;"| '''IST3''' (Low) !0x34 |- |colspan=4 style="text-align: center;"| '''IST2''' (High) !0x30 |- |colspan=4 style="text-align: center;"| '''IST2''' (Low) !0x2C |- |colspan=4 style="text-align: center;"| '''IST1''' (High) !0x28 |- |colspan=4 style="text-align: center;"| '''IST1''' (Low) !0x24 |- |colspan=4 style="text-align: center;"| Reserved !0x20 |- |colspan=4 style="text-align: center;"| Reserved !0x1C |- |colspan=4 style="text-align: center;"| '''RSP2''' (High) !0x18 |- |colspan=4 style="text-align: center;"| '''RSP2''' (Low) !0x14 |- |colspan=4 style="text-align: center;"| '''RSP1''' (High) !0x10 |- |colspan=4 style="text-align: center;"| '''RSP1''' (Low) !0x0C |- |colspan=4 style="text-align: center;"| '''RSP0''' (High) !0x08 |- |colspan=4 style="text-align: center;"| '''RSP0''' (Low) !0x04 |- |colspan=4 style="text-align: center;"| Reserved !0x00 |} * '''RSP0, RSP1, RSP2:''' 当特权级别从较低的特权级别更改为较高的特权级别时,用于加载堆栈的'''Stack Pointers(栈指针)'''。 * '''IST#:''' 中断堆栈表(Interrupt Stack Table)。 “[[Interrupt Descriptor Table#Long Mode|中断描述符表-Interrupt Descriptor Table]]”中的一个条目的'''IST'''值不是0时,用于加载堆栈的'''Stack Pointers'''。 * '''IOPB:''' I/O映射基址字段。 包含从'''TSS'''的基地址到'''I/O Permission Bit Map'''的16位偏移量。 == 软件多任务中的TSS == 对于执行可能想要通过中断进行系统调用的进程的每个CPU,需要一个TSS。 唯一有趣的字段是SS0和esp0。 每当发生系统调用时,CPU都会在其TSS中获取SS0和ESP0值,并将堆栈指针分配给它。 因此,需要为执行系统调用的进程设置一个或多个内核堆栈。 请注意,线程/进程的时间片可能在系统调用期间结束,将控制权传递给另一个线程/进程,该线程/进程也可以执行系统调用,最终在同一堆栈中。 解决方案是为每个线程/进程创建一个私有内核堆栈,并在任何任务切换时重新分配esp0,或者在系统调用期间禁用调度(另请参见[[Kernel Multitasking|内核多任务])。 设置TSS很简单。 需要 [[Global Descriptor Table|全局描述符表]] 中的条目 (另请参阅 [[GDT_Tutorial#Flat_Setup|GDT教程]]),将TSS的地址指定为 “base”,TSS的大小指定为 “limit”,0x89 (Present|Executable|Accessed) 作为 “access byte”,0x40 (Size-bit) 作为 “flags”。 在TSS本身中,要设置成员“SS0”、“ESP0”和“IOPB偏移量”: * SS0获取内核数据段描述符(例如,如果GDT中的第三个条目描述了内核数据,则为0x10) * ESP0获取堆栈指针在系统调用时应获得的值 * 如果你不打算进一步使用此io-bitmap,IOPB可能会获得 sizeof(TSS)值(即104)(根据mystran http://forum.osdev.org/viewtopic.php?t=13678) TSS的实际加载必须在保护模式下进行,并且必须在GDT加载之后进行。 加载过程很简单,如下所示: <source lang="asm"> mov ax, 0x?? ;GDT中TSS的描述符(例如,如果GDT中的第六个条目描述了你的TSS,则为0x28) ltr ax ;实际加载 </source> ==另见== === 文章 === *[[GDT_Tutorial#Flat_Setup| GDT教程]] *[[System Calls|系统调用]] *[[Getting to Ring 3]] ===论坛主题=== *[[Topic:13678|Do I need a TSS?]] ===外部链接=== *[[wikipedia:Task State Segment|Task State Segment]] on Wikipedia [[Category:X86 CPU]] [[de:Task State Segment]]
返回至“
Task State Segment
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息