修改Linux0.00时钟中断为键盘中断

修改Linux0.00时钟中断为键盘中断

首先修改task1的代码使其运行一次后进入无限循环
将jmp _task1修改为jmp $
将timer_interrupt修改为:

 1  _timer_interrupt:
 2      PUSH ds
 3      PUSH edx
 4      PUSH ecx
 5      PUSH ebx
 6      PUSH eax
 7      ;MOV eax, 0x10
 8      ;MOV dx,ax
 9       in  al, 0x21             ; ┓
10      or al,( 1   <<   1 )    ; ┣ 屏蔽当前中断
11       out   0x21 ,al            ; ┛
12      mov al, 0x20             ; ┓置EOI位,其后8259A才能相应新的中断
13       out   0x20 ,al            ; ┛
14      sti                            ; 允许响应新中断
15       in  al, 0x60             ; 从0x60端口读出扫描码
16      ;MOV eax, 1
17      ;cmp DWORD [current],eax
18      ;je y1
19      ;MOV DWORD [current],eax
20      ;JMP TSS1_SEL :  0
21      ;jmp y2
22  y1:
23      ;MOV DWORD [current], 0
24      ;JMP TSS0_SEL :  0
25      ;MOV eax, 0x17
26      ;MOV ds,ax
27      ;MOV al, 65
28      call write_char    ; 这里仅简单的将扫描码作为ANSI码打印出来
29      ;MOV ecx, 0xfff
30  y2:
31      cli
32       in  al, 0x21                 ; ┓
33      and al, ~ ( 1   <<   1 )    ; ┣ 恢复接受当前中断
34       out   0x21 ,al                ; ┛
35      POP eax
36      POP ebx
37      POP ecx
38      POP edx
39      POP ds
40      IRET

注:因为键盘中断处理过程运行于Ring0,应此可以直接调用内核函数write_char
然后修改IDT表的0x21(0x21对应于IRQ1,表示键盘中断)项的offset_l和offset_h使其指向timer_interrupt中断处理过程.
 1  void  init_idt()
 2  {
 3       int  i;
 4       for (i = 0 ;i < 256 ;i ++ )
 5      {
 6           if ( 0x21   ==  i  ||   0x80   ==  i)
 7          {
 8               continue ;
 9          }
10          setup_int_gate((dword)ignore_int,i);        
11      }
12       // setup_int_gate((dword)timer_interrupt,0x20);
13      setup_int_gate((dword)timer_interrupt, 0x21 );
14      setup_trap_gate((dword)system_interrupt, 0x80 );    
15      
16      idtr[ 0 =   8   *   256 ;
17      idtr[ 1 =  ((dword) & idt_[ 0 +  KERNEL_BASE)  &   0xffff ;
18      idtr[ 2 =  ((dword) & idt_[ 0 +  KERNEL_BASE) >> 16 ;
19  }

最后启动键盘中断,将8259A主片的IRQ0位设为1,IRQ1位设为0
1      MOV edx, 0x21
2       in  al,dx
3      AND al, 0xFD
4      OUT dx,al
注:0xFD对应二进制码11111101
调试结果:
修改Linux0.00时钟中断为键盘中断_第1张图片
按下a键输出一个字符,弹起a键输出另一个字符
由于直接将扫描码作为ANSI码输出因此会出现两个乱码字符

完整代码打包下载

你可能感兴趣的:(修改Linux0.00时钟中断为键盘中断)