int.s
来自「COS 0.0.1.rar Cos操作系统源代码」· S 代码 · 共 253 行
S
253 行
; int.s - low-level interrupt routines; ; Author: Paul Barker; Part of: COS; Created: 15/04/04; Last Modified: 04/10/04;; Copyright (C) 2004 Paul Barker; ; This program is free software; you can redistribute it and/or modify; it under the terms of the GNU General Public License as published by; the Free Software Foundation; either version 2 of the License, or; (at your option) any later version.;; This program is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License; along with this program; if not, write to the Free Software; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.;; (See file "Copying"); See "COPYING-GEEKOS" about the code here that is taken from GeekOS[BITS 32]; include this for KERNEL_CS%include "defs.inc"GLOBAL lgdtrGLOBAL lidtr; Sizes of interrupt handler entry points for interrupts with; and without error codes. The code in idt.c uses this; information to infer the layout of the table of interrupt; handler entry points, without needing a separate linker; symbol for each one (which is quite tedious to type :-)GLOBAL g_handlerSizeNoErrGLOBAL g_handlerSizeErr; Beginning and end of the table of interrupt entry points.GLOBAL g_entryPointTableStartGLOBAL g_entryPointTableEnd; get interrupts tbl from sysinfo->interruptsEXTERN sysinfo; fake return address to setup a threadGLOBAL FakeReturnAddr; ----------------------------------------------------------------------; Interrupt Definitions; - We are using the GeekOS way of handling interrupts,; most of this code is taken from GeekOS; ----------------------------------------------------------------------; This is the size of the Interrupt_State struct in int.hINTERRUPT_STATE_SIZE equ 64; Save registers prior to calling a handler function.; This must be kept up to date with:; - Interrupt_State struct in int.h%macro Save_Registers 0 push eax push ebx push ecx push edx push esi push edi push ebp push ds push es push fs push gs%endmacro; Restore registers and clean up the stack after calling a handler function; (i.e., just before we return from the interrupt via an iret instruction).%macro Restore_Registers 0 pop gs pop fs pop es pop ds pop ebp pop edi pop esi pop edx pop ecx pop ebx pop eax add esp, 8 ; skip int num and error code%endmacro; Number of bytes between the top of the stack and; the interrupt number after the general-purpose and segment; registers have been saved.REG_SKIP equ (11*4); Template for entry point code for interrupts that have; an explicit processor-generated error code.; The argument is the interrupt number.%macro Int_With_Err 1align 8 push dword %1 ; push interrupt number jmp Handle_Interrupt ; jump to common handler%endmacro; Template for entry point code for interrupts that do not; generate an explicit error code. We push a dummy error; code on the stack, so the stack layout is the same; for all interrupts.%macro Int_No_Err 1align 8 push dword 0 ; fake error code push dword %1 ; push interrupt number jmp Handle_Interrupt ; jump to common handler%endmacro; ----------------------------------------------------------------------; Code; ----------------------------------------------------------------------[SECTION .text]; Load IDTR with 6-byte pointer whose address is passed as; the parameter. Taken from GeekOS, like so much else...align 8lidtr: mov eax, [esp+4] lidt [eax] ret; Load GDTR with 6-byte pointer whose address is passed as; the parameter. This really belongs somewhere else, but for; now it is here.align 8lgdtr: mov eax, [esp+4] lgdt [eax] mov ax, KERNEL_DS mov ds, ax mov es, ax mov fs, ax mov gs, ax ; now do a far jump to reload everything jmp KERNEL_CS:.here.here: ret; Common interrupt handling code.; Save registers, call C handler function,; possibly choose a new thread to run, restore; registers, return from the interrupt.align 8Handle_Interrupt: ; Save registers (general purpose and segment) Save_Registers ; Ensure that we're using the kernel data segment mov ax, KERNEL_DS mov ds, ax mov es, ax ; Get the address of the C handler function from the ; table of handler functions. mov eax, [sysinfo] ; sysinfo mov eax, [eax] ; sysinfo->interrupts add eax, 2048 ; interrupts is first entry of sysinfo, ; and handler table is 2k into interrupts mov esi, [esp+REG_SKIP] ; get interrupt number mov ebx, [eax+esi*4] ; get address of handler function ; Call the handler. ; The argument passed is a pointer to an Interrupt_State struct, ; which describes the stack layout for all interrupts. push esp call ebxFakeReturnAddr: add esp, 4 ; clear 1 argument ; Restore registers Restore_Registers ; Return from the interrupt. iret; ----------------------------------------------------------------------; Generate interrupt-specific entry points for all interrupts.; We also define symbols to indicate the extend of the table; of entry points, and the size of individual entry points.; ----------------------------------------------------------------------align 8g_entryPointTableStart:; Handlers for processor-generated exceptions, as defined by; Intel 486 manual.Int_No_Err 0align 8Before_No_Err:Int_No_Err 1align 8After_No_Err:Int_No_Err 2 ; Described in my Intel manual as NMI ; an int 2 instruction does not do a 'real' NMIInt_No_Err 3Int_No_Err 4Int_No_Err 5Int_No_Err 6Int_No_Err 7align 8Before_Err:Int_With_Err 8align 8After_Err:Int_No_Err 9 ; Described as Coprocessor segment overrun. Apparantly ; recent IA-32 processors should NOT generate this exceptionInt_With_Err 10Int_With_Err 11Int_With_Err 12Int_With_Err 13Int_With_Err 14Int_No_Err 15 ; RESERVEDInt_No_Err 16Int_With_Err 17; The remaining interrupts (18 - 255) do not have error codes.; We can generate them all in one go with nasm's %rep construct.%assign intNum 18%rep (256 - 18)Int_No_Err intNum%assign intNum intNum+1%endrepalign 8g_entryPointTableEnd:[SECTION .rodata]; Exported symbols defining the size of handler entry points; (both with and without error codes).align 4g_handlerSizeNoErr: dd (After_No_Err - Before_No_Err)align 4g_handlerSizeErr: dd (After_Err - Before_Err)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?