Reprint please mark: http://blog.csdn.net/zgh1988/article/details/7389329
I'll take the example of C and D, respectively, to tell the interrupt handlers under single-process switching and multi-process switching.
1, single process environment of the interrupt processing program
2. Interrupt handler in multi-process environment I. Interrupt processing program in a single process environment
Here we only consider the use of clock interrupts for process switching.
We know that the process is running in a ring1 environment, and the interrupt handler is running in the RING0 environment, let's imagine the process switching situation. A process is working diligently, this time the clock interrupt occurs, the privilege level jumps from ring1 to RING0, starts to execute the clock interrupt handler, the interrupt handler then calls the process Dispatch module, specifies the next application to run the process, when the interrupt handler ends, The next process is ready and running, and the privilege level jumps back to ring1 from RING0.
Let's consider what we need to pay attention to in the process switching process from two aspects. (assuming process A is running at this point) 1. Save and restore on-site
After entering the interrupt handler, the first task is to save the state information for process a so that it can be used in the future when process a is resumed. In this program, process A's state information contains only the register contents. Because it is an interrupt in a single-process environment, before leaving the interrupt handler, the state information of process A is restored, and after the interrupt handler is left, it is returned to process a.
hwint00: ...
; Save the contents of the original register
Pushad
push ds push es push
fs
push GS ...
; Restore the contents of the original Register
pop GS
pop fs pop
es
pop ds
popad
...
Iretd
2, the stack switch
The interrupt occurred, the privilege level changed, from RING1 (process a)-----RING0 (Interrupt handler)-----ring1 (Process a).
First consider the ring1----RING0, jump from the low privilege level (RING1) to the High privilege level (RING0) and need to get es0 and esp0 from the TSS. After entering the RING0 (interrupt handler), we need to save the state information of process A to the PCB (Process Control block), so we point the TSS esp0 to the process table before the interrupt handler occurs. So in the restart function, we see:
Restart:
mov ESP, [P_proc_ready] ; Assigns the first address of the process table to ESP
Lldt [esp + p_ldt_sel] ; Loads the LDT in the PCB
Lea EAX, [esp + p_stacktop] ; eax points to the EAX address in the PCB.
mov DWORD [TSS + tss3_s_sp0], eax ; Point the esp0 in the TSS to the address of the EAX in the PCB, at which point the
esp points to the first address of the process table, successively out of the stack, and in turn pops up GS, FS, es, DS, EDI,
esi, EBP, ESP, EBX, edx, ECX, eax.
pop gs
pop fs
pop es
pop ds
popad
; now esp points to EIP
add ESP, 4
iretd
Combine graphs to analyze programs.
We know that we point esp0 to the eax of stack_frame in the data structure process, so after the clock breaks, the interrupt handler is first saved, that is, the process state information, which is done by a bunch of push instructions, is saved to the PCB of the process. Which is the process structure.
hwint00: ; Interrupt routine for IRQ 0 (the clock).
Sub ESP, 4
; Save the contents of the original register
Pushad
push ds push
es
push fs
push GS
MOV dx, ss
mov ds, DX
mov es, dx
; Change the screen No. 0, No. 0 column character
; Inc byte[gs:0]
; make the main 8259 accept interrupts
mov al, EOI out
Int_m_ctl, Al
Inc Dword[k_reenter]
CMP Dword[k_reenter], 0
jne. re_enter
; switch to kernel stack
mov esp, stacktop
; open interrupt
STI
; call the DISP_STR function to display "^"
push clock_int_msg
call Disp_str
add ESP, 4
; invoke the delay function, Implement interrupt nesting
;p ush 1
; call delay
; add esp, 4
; Turn off interrupt
CLI
; leave kernel stack
mov esp, [p_proc_ready]
lea EAX, [ESP + p_stacktop]
mov dword[tss + tss3_s_sp0], eax
. Re_enter:
Dec dword[k_reenter]
Restore the contents of the original Register
pop GS
pop fs pop
es
pop ds
popad
add ESP, 4
iretd
In RING0, we need to call the process dispatch module, or display some characters, need to use the stack, at this point the ESP is pointing to the process table, so if the operation of ESP, it is equivalent to change the contents of the process table. So we need to save the ESP at this point and then point it to another stack (the kernel stack):
mov esp, stacktop.
After executing the dispatch module, or displaying some characters, we need to leave the kernel stack, so where do we need to point the ESP? We know that we need to restore the status information of process A before we leave the interrupt handler, so we're going to do it through a bunch of pop instructions. So we have to assign ESP to the starting address of the process table. IE: mov esp, [p_proc_ready]
At this point, we also need to consider a problem, that is, before we leave the interrupt handler, we should also complete a task, is to assign value in the TSS esp0. So we use
mov esp, [p_proc_ready]
Lea EAX, [ESP + p_stack_top]
mov dword[tss + tss3_s_sp0], eax
This code is exactly the same as the value Esp0 in restart.
At this point we completed the RING0---ring1 jump. The interrupt handler in multi -process environment requires multiple processes to switch, so every time after an interrupt handler occurs, we need to remove the next waiting process from the process table and then execute the process. Therefore, the interrupt handler in a multi-process environment is only one more task than before, which is to take out a waiting process before leaving the interrupt handler. Here is the program code:
hwint00: ; Interrupt routine for IRQ 0 (the clock).
Sub ESP, 4
; Save the contents of the original register
Pushad
push ds push
es
push fs
push GS
MOV dx, ss
mov ds, DX
mov es, dx
; enable master 8259 to accept interrupts
mov al, EOI out
Int_m_ctl, al
Inc Dword[k_reenter]
CMP dword[k_reenter ], 0
jne. re_enter
; switch to kernel stack
mov esp, stacktop
; turn on interrupt
STI
; call Clock_handler function by adjusting P_proc _ready points to proc_table
; The different processes in the array.
Push 0 Call
Clock_handler
add ESP, 4
; Turn off interrupt
CLI
; leave kernel stack
mov esp, [p_proc_ready]
Lldt [esp + p_ldt_sel]
lea EAX, [ESP + p_stacktop]
mov dword[tss + tss3_s_sp0], eax
. Re_enter:
Dec dword[k_reenter]
; restore the contents of the original Register
pop GS
pop fs pop
es
pop ds
popad
add ESP, 4
Iretd
We use the dispatch module to complete the scheduling of the process, which is simple, which is to run each process in the process table sequentially. We can look at the Clock_handler function. It is done in this way:
public void Clock_handler (int IRQ)
{
disp_str ("#");
p_proc_ready++;
if (p_proc_ready >= proc_table + nr_tasks)
{
p_proc_ready = proc_table;
}
}
After that, we have finished switching between the different processes.
comprehensive analysis of "self-written operating system," the sixth chapter-process http://blog.csdn.net/zgh1988/article/details/7371754
comprehensive analysis of "self-written operating system" fifth chapter--makefile http://blog.csdn.net/zgh1988/article/details/7338380
comprehensive analysis of "self-written operating system" fifth chapter---load the kernel kernel.bin http://blog.csdn.net/zgh1988/article/details/7329941
comprehensive analysis of the "self-written operating system," chapter fifth---Red Hat 9.0 installation process http://blog.csdn.net/zgh1988/article/details/7315676
comprehensive analysis of "self-written operating system" fourth Chapter---FAT12 file system http://blog.csdn.net/zgh1988/article/details/7284834
comprehensive analysis of "self-written operating system" fourth Chapter---load Loader.bin http://blog.csdn.net/zgh1988/article/details/7291909
comprehensive analysis of "self-written operating system" Chapter III---Enter the protection mode http://blog.csdn.net/zgh1988/article/details/7098981
comprehensive analysis of "self-written operating system" chapter three---"Real mode-protection mode-Real mode" http://blog.csdn.net/zgh1988/article/details/7255804
A comprehensive analysis of "self-written operating system" Chapter III---How stack segments work http://blog.csdn.net/zgh1988/article/details/7256254
comprehensive analysis of "self-written operating system" Chapter III---privilege level and different privileged level code snippets between the jump http://blog.csdn.net/zgh1988/article/details/7262901
comprehensive analysis of "self-written operating system" Chapter III---paging mechanism http://blog.csdn.net/zgh1988/article/details/7270748
comprehensive analysis of "self-written operating system" Chapter III---interrupt mechanism http://blog.csdn.net/zgh1988/article/details/7276259
comprehensive analysis of "self-written operating system" chapter II http://blog.csdn.net/zgh1988/article/details/7062065
comprehensive analysis of "self-written operating system" chapter http://blog.csdn.net/zgh1988/article/details/7060032
"Write your own operating system" http://blog.csdn.net/zgh1988/article/details/7059936