📄 entry.s
字号:
;/*
; * ExpOS
; *
; *
; *
; * Copyright 2002
; * hyl
; */
SEG_NOT_VECTOR EQU 11 ; segment not present
STACK_FAULT_VECTOR EQU 12 ; stack exception
PROTECTION_VECTOR EQU 13 ; general protection
PAGE_FAULT_VECTOR EQU 14
COPROC_ERR_VECTOR EQU 16 ; coprocessor error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;GATE STRUC ;门结构类型定义
; OFFSETL DW 0 ;32位偏移的低16位
; SELECTOR DW 0 ;选择子
; Reserve DB 0
; GTYPE DB 0 ;类型
; OFFSETH DW 0 ;32位偏移的高16位
; GATE ENDS
;
[bits 32]
section .data
global _idt,__lidt, _nop_handler
_idt: times 256*2 dd 0 ; idt is uninitialized
; idt 操作函数在arch.c 中
align 2
dw 0
idt_descr: ;装载idt 的伪描述符
dw 256*8-1 ; idt contains 256 entries
dd _idt
section .text
__lidt:
lidt [idt_descr] ; reload idt with kernel idt
ret
;;;;;;;;;;;;
;空中断处理
extern _live
_nop_handler:
push edx
push eax
;push ds
call _live ;_kbdledoff
mov al, 0x20; //clear 8259 int
out 0x20,al
;pop ds
pop eax
pop edx
iret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 描述符分类
; Gate Descripters:
; Task Gate 不使用
; Call Gate 不使用
; Interrupt Gate (IG) 发生后自动清除IF.
; Trap Gate 发生后不清除中断使能位(IF). (Minix 的Gate 都是IG )
;//doc at tail
; 来自cup之外的叫中断(Interrupt):
; *可屏蔽中断(IRQs)
; *不可屏蔽中断(NMI)
; 可屏蔽中断(IRQs) 可以由cli/sti 指令控制.
; 两者都可以被cpu外的硬件所屏蔽.
; 来自cup内部的叫异常(Exceptions):
; **CUP 侦测到的异常:
; *故障(Fault): 在当前指令执行前发生. 如除0, 非法操作码,page fault.
; *陷阱(Trap): 在执行当前指令后发生. 程序指令int 产生的异常都是陷阱.
; *Abort: 异常位置不可确定.如 double fault, coprocessor segment overrun.
; **程序主动产生的异常 :
; INT instruction
; INT3 instruction
; INTO instruction
; BOUND instruction
;*************************************
;Intel 保留的32 个中断/异常:
;|Number | interrupt/exception| err code | notes
;+-----+----------------------+---+------+-------------------------------------
;| 0 | F divide error | N |could be overflow as well as zero denominator
;+-----+----------------------+---+--------------------------------------------
;| 1 | F/T debug exception | N |
;+-----+----------------------+-------------------------------------------------
;| 2 | I NMI | N |
;+-----+----------------------+-------------------------------------------------
;| 3 | T INT3 instruction | N |debugger breakpoint
;+-----+----------------------+-------------------------------------------------
;| 4 | T INTO instruction | N |detected overflow
;+-----+----------------------+-------------------------------------------------
;| 5 | F BOUND instruction | N |detected overrange
;+-----+----------------------+-------------------------------------------------
;| 6 | invalid instruction | N |
;+-----+ opcode + |------------------------------------------------
;| | F | |
;+-----+----------------------+-------------------------------------------------
;| 7 | F no coprocessor | N |ESC, WAIT instructions
;+-----+----------------------+-------------------------------------------------
;| 8 | A double fault | Y | possible for 386+ in real mode
;| | |(0)| if INT vector exceeds IDT limit
;+-----+----------------------+---+---------------------------------------------
;| 9 | coprocessor segment | N |not in real mode
;| | F overrun | |
;+-----+----------------------+---+---------------------------------------------
;| 10 | F invalid task state | Y | not in real mode
;| | segment (TSS) | |
;+-----+----------------------+-------------------------------------------------
;| 11 |F segment not present | Y | not in real mode
;+-----+----------------------+-------------------------------------------------
;| 12 | F stack fault | Y | possible in real mode if stack access
;| | | | straddles offset 0 or FFFFh
;+-----+----------------------+-------------------------------------------------
;| 13 | F general protection | |possible in real mode if non-stack memory access straddles
;| | fault (GPF) | Y |0 or FFFFh, or if instruction is longer than 15 bytes,
;| | | |or if a 32-bit address greater than FFFFh is used
;+-----+----------------------+-------------------------------------------------
;| 14 | F page fault | Y |not in real mode
;+-----+----------------------+-------------------------------------------------
;| 15 | (reserved) | N
;+-----+----------------------+-------------------------------------------------
;| 16 | F coprocessor error | N | ESC, WAIT instructions
;+-----+----------------------+-------------------------------------------------
;| 17 | F alignment check | Y(0) | not in real mode; 486+ only
;+-----+----------------------+-------------------------------------------------
;| 18 | A machine check | N | Pentium+ only
;+-----+----------------------+-------------------------------------------------
;| 19 |F SIMD float point err | N | SSE and SSE2 floating-point instructions
;+-----+----------------------+-------------------------------------------------
;|20-31| (reserved) |
;+-----+----------------------+------------------------------------------------
;*****************************************
; interrupt/exception 发生后CPU 的动作
; 1. 如果伴随 pmode 特权级切换, CPU 从当前的TSS 中加载 SS (E)SP .
; 2. 如果伴随 pmode 特权级切换, 原来的 SS 和 (E)SP 入新堆栈.
; 3. CS, (E)IP, (E)FLAGS 入新栈. 一些异常可能还把一个错误码入新栈.
; 4. 如果通过一个中断门,CPU 清 IF .
; 5. CPU 做一个 far jump; 从门中加载 CS and (E)IP .
;
; 中断/异常发生后可能形成10 种栈布局. 3 个16-bit 保护模式; 2个virtual 8086 模式.
; 还有一个16 bit 实模式. 对我们比较有意义的4个32位保护模式下的栈格式是:
;+--------------------------------+----------------------------------+
;| 无特权级切换 | 伴随特权级切换 |
;+----------------+---------------+-----------------+----------------+
;| <- 32 bits -> | <- 32 bits -> | <- 32 bits -> |<- 32 bits -> |
;| ... ... | ... ... | ... ... | ... ... |
;| ... ... | ... ... | ... ... | ... user SS |
;| ... ... | ... ... | ... user SS | user ESP |
;| ... ... | EFLAGS | user ESP | EFLAGS |
;| EFLAGS | ... CS | EFLAGS | ... CS |
;| ... CS | EIP | ... CS | EIP |
;| EIP | error code | EIP | error code |
;+----------------+---------------+-----------------+----------------+
;| 无错误码 | 有错误码 | 无错误码 | 有错误码 |
;+----------------+---------------+-----------------+----------------+
;*===========================================================================*
;* exception handlers *
;*===========================================================================*
_divide_error:
push dword 0 ;Divide error vector
jmp exception
_single_step_exception:
push dword 1 ;Debug (single step )
jmp exception
_nmi:
push dword 2 ;NMI
jmp exception
_breakpoint_exception:
push dword 3 ;Breakpoint vector
jmp exception
_overflow:
push dword 4 ;into ,overflow exception vector
jmp exception
_bounds_check:
push dword 5 ;Detected bounds error
jmp exception
_inval_opcode:
push dword 6 ;Invalid opcode vector
jmp exception
_copr_not_available:
push dword 7 ;Coprocessor not avalible
jmp exception
_double_fault:
push dword 8 ;Double Fault vector
jmp errexception
_copr_seg_overrun:
push dword 9 ;Coprocessor segment overrun
jmp exception
_inval_tss:
push dword 10 ;Invalid tss vector
jmp errexception
_segment_not_present:
push dword 11 ; segment not present vector
jmp errexception
_stack_exception:
push dword 12 ; Stack exception
jmp errexception
_general_protection:
push dword 13 ;General protection vector
jmp errexception
_page_fault:
push dword 14 ;Page falt
jmp errexception
_res15_:
push dword 15 ;Reserve vectro 15
jmp exception
_copr_error:
push dword 16 ;Coprocessor error
jmp exception
_align_check:
push dword 17 ; | Y(0) | not in real mode; 486+ only
jmp errexception
_machine_check:
push dword 18 ;machine check Pentium+ only
jmp exception
_simd_fpoint_err:
push dword 19 ; SIMD float point err , SSE and SSE2 floating-point instructions
jmp exception
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 16
exception:
;mov dword [ss:trap_errno], 0
;pop dword [ss:ex_number]
jmp exception1
align 16
errexception:
;pop dword [ss:ex_number]
;pop dword [ss:trap_errno]
exception1:
push eax
mov eax, dword [esp+4]
;mov dword [ss:old_eip], eax
mov eax, dword [esp+8]
;mov dword [ss:old_cs], eax
mov eax, dword [esp+12]
;mov dword [ss:old_eflags], eax
pop eax
;save
;push dword [old_eflags]
;push dword [old_cs]
;push dword [old_eip]
;push dword [trap_errno]
;push dword [ex_number]
;call _exception
add esp, 5*4
;load
ret
;/*
; * 硬件中断处理
; *
; *
; */
section .data
global __irq_table ; void vector(int vct_num)
__irq_table dd 0
times 32 dd 0
section .text
%macro int_handle 1
cld
push ds ; save ds
push es ; save es
;push fs ; save fs
;push gs ; save gs
pusha ; save "general" registers
;mov dx, ss ; ss is kernel data segment
;mov ds, dx ; load rest of kernel segments
;mov es, dx ; kernel does not use fs, gs
push dword %1 ; vct_num
call [__irq_table + 4*%1] ;
add esp,4
popa ; save "general" registers
;pop gs ; save gs
;pop fs ; save fs
pop es ; save es
pop ds ; save ds
iret
%endmacro
;/*
; * 用宏产生中断处理函数, 这是第一级中断处理
; * 这些处理函数的地址填入IDT 0x20----0x2F
; *
; */
%macro Int_Handler 1-* ;多参数宏, 产生IDT Interrupt Handler
%rep %0 ; 0 号参数是参数个数
;本文件访问就可以了
align 16
__hw_int_h%1:
int_handle %1;
%rotate 1 ; 1 号参数变成下一个参数
%endrep
%endmacro
;==========
Int_Handler 00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15 ;idt 中irq的中断门
%macro handler_array_def 1-* ;多参数宏, 把
%rep %0 ; 0 号参数是参数个数
dd __hw_int_h%1;
%rotate 1 ; 1 号参数变成下一个参数
%endrep
%endmacro
;=======================
global __all_int_handler
__all_int_handler:
handler_array_def 00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -