| 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
最新推荐文章于 2021-09-24 10:58:23 发布
本文详细介绍了操作系统内核中异常处理的标准结构,包括三个主要步骤:保存寄存器内容、通过高级C函数处理异常以及退出异常处理程序。文章还具体展示了如何在i386架构下实现这些步骤,并给出了具体的代码示例。
1882

被折叠的 条评论
为什么被折叠?



