in the in Linux0.11, process switching is based on the TSS mechanism provided by Intel , to switch from one process to another, that is to switch the TSS this structure. However, such switching is inefficient, so Linux and Windows later changed to use kernel-based stacks to switch this way. Because the TSS mechanism is relatively simple, most of the effort is devoted to the kernel-based stack mechanism.
the following kernel-based stack method is modified by the Linux0.11 is based on the TSS approach.
TSS mechanism
The following is found on the Internet flowchart of TSS mechanism switching:
to explain this picture, The TR(Task Register) is a TSS descriptor used to index the current task in the GDT , a selector, If you switch tasks, you need to change the TR as well.
first, before switching tasks, we need to save the environment of the current task (i.e. The value of the register in the CPU is saved to thecorresponding location of "current TSS" eax to eax,ebx the ebx this).
then we find "target TSS" and restore it (that is, set the value of the register in the CPU to "target TSS saved in the ".
after the environment is restored, it is necessary to TR is set as the "target TSS" selector.
among them, a more detailed list of the GDT is as follows:
of each process The LDT selector is stored in the corresponding TSS . Since this mechanism takes a lot of time to save and assign, and these two operations are inefficient, the mechanism is not used in Linux and Windows .
kernel stack mechanism
To talk about switching, let's start with the structure of a process.
The creation of a process is created by a call to the system by its parent process.
each time you use fork () to create a process, you will request one page of space (4kb) and a low address space base to hold the PCB of the process , while base+page_size is the bottom of the stack that is the kernel of the process.
This stack is used to hold the various register values of the parent process, after all fork The child process comes out exactly the same as the parent process (unless you call exec class functions, etc.). The Register of the child process is basically assigned a value with the corresponding register of the parent process ( eax fork 0 ).
The parent process makes its own ss esp , eflags , cs , eip pressed into the stack, for calling copy_process copy_process (int nr, long ebp, long edi, long esi, long gs, long none,long EB X, long ecx, long Edx,long FS, long es, long Ds,long EIP, long cs, long eflags, long ESP, long ss) function gets all the required parameters (the register of the parent process).
the Cs:eip points to the address of the next instruction of the fork function, so the child process is called, and the first instruction is called fork The first instruction after the function is finished. As if (fork () = = 0), here the so-called "first instruction" is to use The return value of the fork function compared with 0 .
Then there isSwitch_toThe function is used to switch processes, which pass two parameters: the child process'sPCBaddress and itsLdtthe index of the descriptor. The function is composed of assembly code, the first is to save the parent process a series of registers to the parent process kernel stack, and saveESPin their ownPCBThe corresponding field, the kernel stack pointer of the process is written to the globalTSSinesp0field, and then the core stack pointer to the processPCBwritten to the presentESPregister so that you can use theSs:espto stack and stack up. Then it's switching .LDT, the UseLldtinstructions are all right. Then setFSRegister, which holds a local descriptor that points to the user's data space (0x17 = 0001 0111b). The last is a sequential out of the stack instructions, the previous creation of the child process to save to the child process kernel stack of the stack to the appropriate register (the kernel stack has been switched to the child process).
Here, the switch is complete.
You are welcome to find that the mistake, I must promptly correct and extend my most sincere thanks!
"Learning & Understanding" process switching based on TSS and kernel-stack mechanisms