zoukankan      html  css  js  c++  java
  • ULK --- Chap3 Processes: Process Switch

    To control the execution of process, the kernel must be able to suspend the execution of the process

    running  on the CPU and resume the execution of some other process previously suspended. This 

    activity goes variously by the names process switch, task_switch, or context switch. 

                          Hardware Context

    While each process can have its own address space, all processes have to share the CPU registers. So

    before resuming the execution of a process, the kernel must ensure that each such register is loaded

    with the value it has when the process is suspended.

    The set of data that must be loaded into the registers before the process resumes its execution on the

    CPU is called the hardware context. The hardware context is a subset of the process execution context,

    which includes all infomation needed for the process execution. In Linux, a part of the hardware context

    of a process is stored in the process descriptor, which the remaining part is saved in the Kernel Mode 

    Stack.

    In the descriptor that follows, we will assume the prev local variable refers to the process descriptor of

    the process being switched out and next refers to the one being switched in to replace it. We can thus

    define a process switch as the activity consisting of saving the hardware context of prev and replacing

    it with the hardware context of next. Because process switches occur quite often, it is important to

    minimize the time spent in svaing and loading hardware contexts.

    Old version of Linux took advantage of the hardware support offered by the 80x86 architecture and

    performed a process switch through a far jmp instruction to the selector of the Task State Segment

    Descriptor of the next process. While executing the instruction, the CPU performs a hardware context

    switch by automatically saving old hardware context and loading a new one. But Linux 2.6 uses software

    to perform a process witch for the following reasons:

    Step-by-step switching performed through a sequence of mov instruction allows better control over

    the validity of the data being loaded. In particular, it is possible to check the values of the ds and ss

    segmentation registers, which might have been forged by a malicious user. This type of checking is not

    possible when using a single far jmp instruction.

    The amount of time required by the old approach and the new approach is about the same. However,

    it is not possible to optimize a hardware context switch, while there might be room for improving the

    current switching code.

    Process swithing occurs only in Kernel Mode. The contents of all registers used by a process in User Mode

    have already been saved on the Kernel Mode Stack before performing process switch. This includes the

    contents of the ss and esp pair that specifies the User Mode stack pointer address.

                            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 reaons:

    When an 80x86 CPU switches from User Mode to Kernel Mode, it fetches the address of the Kernel Mode

    stack from the 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.

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

    the following operations:

    It checks the 2-bit IOPL field in the eflags register. If it is set to 3, the control unit executes the I/O instruction.

    Otherwise, it performs the next check.

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

    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 porcess on the CPU, but there is no need to maintain TSSs for processes

    when they are not running.

    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 Sytem Segment.

    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.

    The TSSDs creatd 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 field; 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.

                                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. Thus, each process descriptor includes a field called thead of type thread_struct, in which

    the kernel saves the hardware context whenever the process is being switched out. As we will see later, this data

    structure includes fields for most of the CPU registers, except the general-purpose register such as eax, ebx, etc.,

    which are stored in the Kernel Mode Stack.

  • 相关阅读:
    Attributes in C#
    asp.net C# 时间格式大全
    UVA 10518 How Many Calls?
    UVA 10303 How Many Trees?
    UVA 991 Safe Salutations
    UVA 10862 Connect the Cable Wires
    UVA 10417 Gift Exchanging
    UVA 10229 Modular Fibonacci
    UVA 10079 Pizza Cutting
    UVA 10334 Ray Through Glasses
  • 原文地址:https://www.cnblogs.com/miaoyong/p/4960917.html
Copyright © 2011-2022 走看看