操作系统与网络实现 之二十一

来源:互联网 发布:archlinux网络配置 编辑:程序博客网 时间:2024/05/15 22:42

 

添加中断

中断描述符

中断门IDT

字节7

字节6

字节5

字节4

字节3

字节2

字节1

字节0

offset 31:16

P DPL 0 D 110

000保留

段选择符

offset 15:0

中断门的选择子必须指向代码段描述符

每个中断占8字节

 

两片i8259A级联

                    IRQ0        定时计数

                    IRQ1        键盘

                    IRQ2        连接从8259A

                    IRQ3        异步通信 COM1

                    IRQ4        异步通信 COM2

                    IRQ5         LPT2

                    IRQ6        软盘

                    IRQ7        打印机

                    IRQ8        实时时钟

                    IRQ9        重定向的IRQ2

                    IRQ10

                    IRQ11

                    IRQ12        PS/2鼠标

                    IRQ13        FPU异常

                    IRQ14        AT硬盘

                    IRQ15

按以上列出的中断去编写我们程序会出错,因为这只是适用在非保护模式下,那么保护模式下情况就不一样了,在保护模式下前0x20中断即前32个是系统保留的中断(0x00x1f),接下来才是i8259A中断。

addinter.asm中,对应中断描述符地址都要加上一个数32,如下:

idt_table   equ pdescr+ 6 +3*8   ;3个段描述符占用3X8字节

kb           equ pdescr+ 6 +3*8 + 33*8 ;键盘中断的段 在irq132+1=33294=0x126

tm           equ pdescr+ 6 + 3*8 + 32*8 ;时钟中断的段,irq0,同上

ms           equ pdescr+ 6 + 3*8 + 44*8 ;鼠标中断的段,鼠标在irq12 32+12=44

 

 

具体程序如下:

addinter.asm

[BITS 32]

 

[GLOBAL _addin]   ;我们必须导出这个函数让C程序使用,注意此函数名不用出现在头文件里

......

 

[SECTION .data]

 

pdescr       equ   0x8000

null         equ   0h

os_code32_selequ   8h       ;1,gdt,rpl=00

os_data32_selequ   10h  ;2,gdt,rpl=00

gdt_entries  equ   3        ;共有3个段描述符:null,os code32,os data32,

idt_entries  equ   47      

gdt_table    equ pdescr+ 6

idt_table    equ pdescr+ 6 +3*8

kb           equ pdescr+ 6 +3*8 + 33*8 ;键盘中断的段 在irq132+1=33294=0x126

tm           equ pdescr+ 6 + 3*8 + 32*8 ;时钟中断的段,irq0

ms           equ pdescr+ 6 + 3*8 + 44*8 ;鼠标中断的段,鼠标在irq12 32+12=44

wollequ 0x500000

[SECTION .text]

_addin:           ;入口

pushad

 

jmp                 main

 

default_hand:

;默认中断处理函数  在256个中断里大部分用此中断,什么也不做就返回

;告诉硬件,中断处理完毕,即发送EOI 消息

......

;运行调试模式,c,程序结束,先敲击键盘几下,ctrl+c退出程序,通过x/10 0x500000查看

 mov              al , 0x20

 out              0x20 , al

 out              0xa0 , al

iret

 

time_hand:

;时钟中断处理函数 

......

 mov              al , 0x20

 out              0x20 , al

 out              0xa0 , al

iret

 

keyboard_hand:

;键盘中断处理函数。

......

 

 mov              al , 0x20

 out              0x20 , al

 out              0xa0 , al

 

iret

 

mouse_hand:

;时钟中断处理函数 

......

 mov              al , 0x20

 out              0x20 , al

 out              0xa0 , al

iret

 

init_8259A:

;发送ICW1 : 使用ICW4,级联工作

mov al,011h 

out 020h,al ;8259ICW1

out 0A0h,al ;8259ICW1

;发送ICW2,中断起始号从0x20 开始(第一片)及0x28开始(第二片)

mov al,020h ;IRQ0对应中断向量0x20

out 021h,al ;8259ICW2

mov al,028h ;IRQ8对应中断向量0x28

out 0A1h,al ;8259ICW2

 

mov al,04h  ;IRQ2与从8259相连

out 021h,al ;8259ICW3

mov al,02h  ;对应主8259IRQ2

out 0A1h,al ;8259ICW3

 

mov al,01h 

out 021h,al ;8259ICW4

out 0A1h,al ;8259ICW4

 

mov al,11111101b;屏蔽主8259,不屏蔽IRQ1键盘中断

out 021h,al     ;8259,OCW1

 

mov al,0xff ;屏蔽从8259所有中断

out 0A1h,al     ;8259,OCW1

 

ret

 

main:

 

;built up GDT table

cli

 

;初始化8259A

call init_8259A

 

mov eax,gdt_table

;item 0:null descriptor,

mov dword[eax],0

mov dword[eax+4],0

add eax,8

;item 1,OS code32 descriptor,

;Base=00000000h,limit=0ffh,G=1,D=1,type=a,dpl=0

mov word[eax],0ffh

mov word[eax+2],0

mov byte[eax+4],00h

mov byte[eax+5],09ah

mov byte[eax+6],0c0h

mov byte[eax+7],00h

add eax,8

;item 2,OS data32 descriptor

;Base=00000000h,Limit=0fffffh,G=1,D=1,Type=2,DPL=0

mov word[eax],0ffffh

mov word[eax+2],0000h

mov byte[eax+4],00h

mov byte[eax+5],092h

mov byte[eax+6],0cfh   ;高四位是G D 0 AVL,此处为1100 = c ,低四位是limit bit 16-19此处为f

mov byte[eax+7],00h

add eax,8

;built false GDT descriptor

mov word[pdescr+0],(gdt_entries*8) 

mov dword[pdescr+2],gdt_table

lgdt [pdescr]

 

;建中断门

mov eax,idt_table

mov ebx,default_hand

mov word[eax],bx    ;offset 15:0  在于0x801e 显示0x0c4e

mov word[eax+2],os_code32_sel

mov byte[eax+4],00h ;000 +五位保留 = 00h

mov byte[eax+5],8eh ;高四位是P=1 DPL=00 0 此处为1000 =8  ,低四位是D=1 110  =E

shr ebx,16

mov word[eax+6],bx  ;offset 31:16 显示0x0008 与前面合成地址为 0x80c4e

 

;fill all IDT table with default item

mov esi,idt_table

mov edi,(idt_table+8)

mov ecx,(idt_entries-1)*2

rep movsd    

;IRQ0        定时计数 

mov eax, tm

mov ebx, time_hand

mov word[eax],bx    ;offset 15:0  0x8  显示0x

shr ebx,16

mov word[eax+6],bx  ;offset 31:16 显示0x0008 与前面合成地址为

 

;IRQ1        键盘 其表地址在 pdescr + 6 +3*8 + 33*8 将其处理程序地址填上keyboard_hand

mov eax, kb

mov ebx, keyboard_hand

mov word[eax],bx    ;offset 15:0  0x8126 显示0x0c5f

shr ebx,16

mov word[eax+6],bx  ;offset 31:16 显示0x0008 与前面合成地址为 0x80c5f

 

;built false GDT descriptor for中断

mov word[pdescr+0],(idt_entries*8) 

mov dword[pdescr+2],idt_table

lidt [pdescr]

 

sti  ;开中断

 

popad

ret

0 0