Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56221
  • 博文数量: 47
  • 博客积分: 2095
  • 博客等级: 大尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-01 18:42
文章分类

全部博文(47)

文章存档

2011年(1)

2008年(46)

我的朋友

分类: LINUX

2008-04-26 13:48:12

Task State Segment

The 80x86 architecture includes a specific segment type called the Task State Segment (TSS), to store hardware contexts. Although Linux doesn't use hardware context switches, it is nonetheless forced to set up a TSS for each distinct CPU in the system. This is done for two main reasons:

x86架构包含了一个特殊的段类型TSS,用来存储硬件上下文。尽管Linux没有使用硬件上下文切换,系统仍然强制为每一个CPU设置一个TSS。这是因为:

· When an 80x86 CPU switches from User Mode to Kernel Mode, it fetches the address of the Kernel Mode stack from the TSS (see the sections "Hardware Handling of Interrupts and Exceptions" in Chapter 4 and "Issuing a System Call via the sysenter Instruction" in Chapter 10).

当x86 CPU从用户态切换到内核态,它从TSS中读取内核空间栈的地址。

· When a User Mode process attempts to access an I/O port by means of an in or out instruction, the CPU may need to access an I/O Permission Bitmap stored in the TSS to verify whether the process is allowed to address the port.

当一个用户态进程试图通过in或者out指令访问I/O端口时,CPU可能需要访问存储在TSS中的I/O权限bitmap,验证该进程是否被运行寻址这个端口。

More precisely, when a process executes an in or out I/O instruction in User Mode, the control unit performs the following operations:

1. It checks the 2-bit IOPL field in the eflags register. If it is set to 3, the control unit executes the I/O instructions. Otherwise, it performs the next check.

2. It accesses the tr register to determine the current TSS, and thus the proper I/O Permission Bitmap.

3. It checks the bit of the I/O Permission Bitmap corresponding to the I/O port specified in the I/O instruction. If it is cleared, the instruction is executed; otherwise, the control unit raises a "General protection " exception.

The tss_struct structure describes the format of the TSS. As already mentioned in Chapter 2, the init_tss array stores one TSS for each CPU on the system. At each process switch, the kernel updates some fields of the TSS so that the corresponding CPU's control unit may safely retrieve the information it needs. Thus, the TSS reflects the privilege of the current process on the CPU, but there is no need to maintain TSSs for processes when they're not running.

tss_struct结构描述了TSS的格式。在每次进程切换中,内核更新TSS中的某些成员使得对应的CPU的控制单元能安全地得到需要的信息。因此,TSS反映了当前CPU进程的权限,然而没有必要为没有运行的进程维护TSS。

Each TSS has its own 8-byte Task State Segment Descriptor (TSSD). This descriptor includes a 32-bit Base field that points to the TSS starting address and a 20-bit Limit field. The S flag of a TSSD is cleared to denote the fact that the corresponding TSS is a System Segment (see the section "Segment Descriptors" in Chapter 2).

每个TSS有自己的8byteTSSD。这个描述符包括32bit基地址成员,指向TSS开始地址,和20bitLimit成员。TSSD的S标志是空的表示对应TSS是系统段。

The Type field is set to either 9 or 11 to denote that the segment is actually a TSS. In the Intel's original design, each process in the system should refer to its own TSS; the second least significant bit of the Type field is called the Busy bit; it is set to 1 if the process is being executed by a CPU, and to 0 otherwise. In Linux design, there is just one TSS for each CPU, so the Busy bit is always set to 1.

成员type设为9或11表示段确实是一个TSS。在Intel早期设计中,系统中每个进程都应该有自己的TSS;type成员的第二个bit称为“忙”bit;如果进程正被CPU执行设为1,否则设为0.在Linux设计中,每个CPU只有一个TSS,所以“忙”bit总是1.

The TSSDs created by Linux are stored in the Global Descriptor Table (GDT), whose base address is stored in the gdtr register of each CPU. The tr register of each CPU contains the TSSD Selector of the corresponding TSS. The register also includes two hidden, nonprogrammable fields: the Base and Limit fields of the TSSD. In this way, the processor can address the TSS directly without having to retrieve the TSS address from the GDT.

Linux创建的TSSD存储在GDT,它的基地址存储在每个CPU的gdtr寄存器。每个CPU的tr寄存器包含了对应TSS的TSSD选择子。这个寄存器也包括了两个隐藏、不可编程的成员:TSSD的base和limit成员。处理器可以直接寻址TSS而不用从GDT中得到TSS的地址。

The thread field

At every process switch, the hardware context of the process being replaced must be saved somewhere. It cannot be saved on the TSS, as in the original Intel design, because Linux uses a single TSS for each processor, instead of one for every process.

在每次进程切换中,被替换的进程的硬件上下文必须保存起来。不能按intel最初的设计那样,放在TSS中,因为Linux为每个处理器使用一个TSS,而不是每个进程一个。

Thus, each process descriptor includes a field called thread of type thread_struct, in which the kernel saves the hardware context whenever the process is being switched out. As we'll see later, this data structure includes fields for most of the CPU registers, except the general-purpose registers such as eax, ebx, etc., which are stored in the Kernel Mode stack.

因此,每个进程描述符包含了一个成员thread,它的类型为thread_struct,进程被切换出去时,内核将它的硬件上下文存放在这个结构中。稍后会看到,这个数据结构包含了大多数的CPU寄存器,除了通用寄存器eax、ebx等,这些存放在内核栈内。
阅读(597) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~