全部博文(489)
分类:
2012-01-03 12:41:33
原文地址:一个操作系统的实现笔记五之中断 作者:飘之叶
中断好像书上描述的比较少,最近由于工作需要要看android
一个操作系统的实现就这个没有那么多的时间看了,看到突破512B限制的时候看得有点蒙了,FAT12的格式书上介绍的不是很清楚。
中断的使用
1、 增加IDT,20h号和80h号中断
; IDT
[SECTION .idt]
ALIGN 32
[BITS 32]
LABEL_IDT:
; 门 目标选择子, 偏移, DCount, 属性
%rep 32
Gate SelectorCode32, SpuriousHandler, 0, DA_386IGate
%endrep
.020h: Gate SelectorCode32, ClockHandler, 0, DA_386IGate
%rep 95
Gate SelectorCode32, SpuriousHandler, 0, DA_386IGate
%endrep
.080h: Gate SelectorCode32, UserIntHandler, 0, DA_386IGate
IdtLen equ $ - LABEL_IDT
IdtPtr dw IdtLen - 1 ; 段界限
dd 0 ; 基地址
; END of [SECTION .idt]
2、选择子
; int handler ---------------------------------------------------------------
_ClockHandler:
ClockHandler equ _ClockHandler - $$
inc byte [gs:((80 * 0 + 70) * 2)] ; 屏幕第 0 行, 第 70 列。
mov al, 20h
out 20h, al ; 发送 EOI
iretd
_UserIntHandler:
UserIntHandler equ _UserIntHandler - $$
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'I'
mov [gs:((80 * 0 + 70) * 2)], ax ; 屏幕第 0 行, 第 70 列。
iretd
_SpuriousHandler:
SpuriousHandler equ _SpuriousHandler - $$
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, '!'
mov [gs:((80 * 0 + 75) * 2)], ax ; 屏幕第 0 行, 第 75 列。
jmp $
iretd
; ---------------------------------------------------------------------------
3、
; Init
Init
mov al, 011h
out 020h, al ; 主8259, ICW1.
call io_delay
out
call io_delay
mov al, 020h ; IRQ0 对应中断向量 0x20
out 021h, al ; 主8259, ICW2.
call io_delay
mov al, 028h ; IRQ8 对应中断向量 0x28
out
call io_delay
mov al, 004h ; IR2 对应从8259
out 021h, al ; 主8259, ICW3.
call io_delay
mov al, 002h ; 对应主8259的 IR2
out
call io_delay
mov al, 001h
out 021h, al ; 主8259, ICW4.
call io_delay
out
call io_delay
;mov al, 11111111b ; 屏蔽主8259所有中断
mov al, 11111110b ; 仅仅开启定时器中断
out 021h, al ; 主8259, OCW1.
call io_delay
mov al, 11111111b ; 屏蔽从8259所有中断
out
call io_delay
ret
; Init
4、加载IDT
; 为加载 IDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_IDT ; eax <- idt 基地址
mov dword [IdtPtr + 2], eax ; [IdtPtr + 2] <- idt 基地址
; 保存 IDTR
sidt [_SavedIDTR]
; 保存中断屏蔽寄存器(IMREG)值
in al, 21h
mov [_SavedIMREG], al
; 加载 GDTR
lgdt [GdtPtr]
; 关中断
;cli
; 加载 IDTR
lidt [IdtPtr]
中断使用
call Init
int 080h
sti
jmp $