随笔-91  评论-137  文章-0  trackbacks-0

首先修改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
调试结果:

按下a键输出一个字符,弹起a键输出另一个字符
由于直接将扫描码作为ANSI码输出因此会出现两个乱码字符

完整代码打包下载
posted on 2010-12-11 17:46 lwch 阅读(1971) 评论(5)  编辑 收藏 引用 所属分类: 操作系统

评论:
# re: 修改Linux0.00时钟中断为键盘中断 2010-12-11 23:18 | xx
看样子,直接修改的内核源代码哦?
了不起啊,能整懂哦。  回复  更多评论
  
# re: 修改Linux0.00时钟中断为键盘中断 2010-12-11 23:31 | lwch
@xx
还处于学习阶段,Linux0.00的代码比较短应此拿它来研究.  回复  更多评论
  
# re: 修改Linux0.00时钟中断为键盘中断[未登录] 2011-01-11 20:33 | myjfm
@lwch
你这个是修改的linux源码吗?看代码风格不像阿,是Orange'S吧?  回复  更多评论
  
# re: 修改Linux0.00时钟中断为键盘中断 2011-12-15 21:19 | moon_peak
我也在修改源码,是添加了键盘中断,可是键盘中断只能响应一次,第二次就不能响应了,求指导  回复  更多评论
  
# re: 修改Linux0.00时钟中断为键盘中断 2011-12-15 22:52 | lwch
@moon_peak
这个问题很好解决,弄个全局变量就搞定了.  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理