Exception handlers have a standard structure consisting of three steps: | |||||||||
1. Save the contents of most registers in the Kernel Mode stack (this part is coded in assembly language). | |||||||||
2. Handle the exception by means of a high-level C function. | |||||||||
3. Exit from the handler by means of the ret_from_exception( ) function. | |||||||||
trap_init( ) | //i386/kernel/traps.c | ||||||||
doublefault_fn() | //i386/kernel/doublefault.c | ||||||||
Saving the Registers for the Exception Handler | |||||||||
handler_name: | |||||||||
pushl $0 /* only for some exceptions */ | |||||||||
pushl $do_handler_name | |||||||||
jmp error_code | |||||||||
error_code: | |||||||||
1. Saves the registers that might be used by the high-level C function on the stack. | |||||||||
2. Issues a cld instruction to clear the direction flag DF of eflags , | |||||||||
thus making sure that autoincreases on the edi and esi registers will be used with string instructions | |||||||||
3. Copies the hardware error code saved in the stack at location esp+36 in edx. | |||||||||
Stores the value -1 in the same stack location | |||||||||
this value is used to separate 0x80 exceptions from other exceptions. | |||||||||
4. Loads edi with the address of the high-level do_handler_name( ) C function | |||||||||
saved in the stack at location esp+32; writes the contents of es in that stack location | |||||||||
5. Loads in the eax register the current top location of the Kernel Mode stack. | |||||||||
This address identifies the memory cell containing the last register value saved in step 1 | |||||||||
6. Loads the user data Segment Selector into the ds and es registers. | |||||||||
7. Invokes the high-level C function whose address is now stored in edi | |||||||||
Entering and Leaving the Exception Handler | |||||||||
do_trap() | |||||||||
store the hardware error code and the exception vector in the process descriptor of current, | |||||||||
and then send a suitable signal to that process: | |||||||||
current->thread.error_code = error_code; | |||||||||
current->thread.trap_no = vector; | |||||||||
force_sig(sig_number, current); | |||||||||
ret_from_exception() | |||||||||
most exceptions are handled simply by sending a Unix signal to the process that caused the exception. | |||||||||
The action to be taken is thus deferred until the process receives the signal; as a result, | |||||||||
the kernel is able to process the exception quickly | |||||||||
Understanding the linux kernel-ch4-Exception Handling
最新推荐文章于 2009-11-28 21:40:00 发布