Linux0.11 kernel source - switching kernel mode process improvement

Since the kernel mode process Linux0.11 switching mode is used to jump the TSS ljmp, less efficient, and therefore considered for optimization, instead of using the kernel stack later version stack switch

You need to do the task

  1. rewriting schedule, switch_to function

  2. The modified function together

  3. Modify the fork function

Currently working in schedule Linux 0.11 () function is to first find an array location next to the next process, and this is the next in the GDT n, so this next segment descriptor is used to find the target after switching TSS segment, once the next value of the direct call analysis above that the switch_to macro expansion (next); TSS switching can be done as shown in FIG switched.

Now, we do not have to switch TSS, instead of using the kernel stack switches to complete the process of switching, so the new switch_to will use PCB PCB, the target process of the current process, the core kernel stack, the target process of the current process stack and other information. Since the kernel stack Linux 0.11 process and the process of PCB on the same page of memory (one of 4KB memory), in which PCB is located on this page memory low addresses, stack situated this page memory high addresses; Further, since the current process PCB is a global variable current point, so just tell new switch_to () function is a pointer to the target process PCB on it. But also it will also pass into the next, although TSS (next) is no longer needed, but LDT (next) is still needed, that is to say, each process now do not have their own TSS, as it has not adopted the process of TSS switching, but each process needs its own LDT, address or addresses must be separated, and the switching process must involve switching the LDT.

Switch_to corresponding source code modifications should:

if ((*p)->state == TASK_RUNNING && (*p)->counter > c) 
    c = (*p)->counter, next = i; 

//......

switch_to(next);

Changed

if ((*p)->state == TASK_RUNNING && (*p)->counter > c) 
    c = (*p)->counter, next = i, pnext = *p;

//.......

switch_to(pnext, LDT(next)); 

 

Then modify the function switch_to

the switch_to:
     ! processing stack frame 
    the pushl % ebp 
    Movl % ESP,% ebp
    
     ! register push processing 
    the pushl % ECX 
    the pushl % EBX 
    the pushl % EAX
    
     EBX, Current points to the next PCB:! . 8 (% ebp) indicates the two grid ebp: because there are two parameters pNext switch_to and LDT (next), so that two cells up exactly pNext 
    Movl . 8 (EBP%),% EBX 
    CMPL % EBX, Current 
    
    JE 1F
 ! handover the PCB
     ! ...
 ! kernel stack pointer of the TSS rewrite
     ! ...
 ! handover kernel stack
    ! ...
 ! Handover LDT
     ! ... 
    movl $ 0x17 ,% ECX 
    mov % CX,% FS
 ! And behind clts to deal with the co-processor, and not because the theme of the relationship, not discussed here 
    CMPL % eax , last_task_used_math 
    JNE 1F 
    CLTS 

. 1 : popl% EAX 
    popl % EBX 
    popl % ECX 
    popl % EBP 
RET

Guess you like

Origin www.cnblogs.com/zsben991126/p/12038747.html