哈工大李治军老师操作系统笔记【25】:键盘(Learning OS Concepts By Coding Them !)

30 篇文章 22 订阅

0 回顾

  • 上一讲开始是操作系统对设备的驱动管理,显示器和键盘是终端设备,看操作系统怎么驱动的

在这里插入图片描述


  • 这是外设工作的基本原理
  • CPU发送一个指令,读或写的指令,然后当外设工作完成的时候,向CPU做回一个中断
  • 以上对于终端设备(不光是外设),其基本思路就是这样的
  • 要想实现外设的驱动,要实现三件事:
  1. 核心:向外设控制器的某些寄存器/存储器端口发送读/写指令,通过out向外设发指令
  2. 操作系统通过文件形成一个统一的文件视图,将所有的外设都做成文件,根据文件所对应的文件名,文件所对应的结构(文件描述的结构当中的信息,inode)决定了要走哪条路,最终到了哪一段out
  3. 进行中断处理,最后回到文件系统

1 键盘


  • 敲了就中断,所以就从中断开始
  • 但是中断开始就得从中断初始化开始
  • 我们得知道键盘中断被初始化成了什么函数
    在这里插入图片描述

  • {set_trap_gate(0x21, &keyboard_interrupt);}这里就是将0x21设置成这个键盘中断
  • out就有in
  • 可以看出这个与CPU交互最核心的指令往往是最简单的
  • in指令把0x60读入al当中
  • 所有的键盘,每一个按键都对应一个码
  • 因为这里是赋给al了,所以存在于ax当中
  • 然后根据不同的码,来调用一个table来执行相应的工作
  • 根据扫描码来知道要干什么,因为键盘,从设备开始的
inb $0x60, %al//从端口0x60读扫描码
call key_table(,%eax,4)//调用key_table + eax*4

1.1 扫描码key_table + eax * 4


  • 根据key_table来决定做什么
  • do_self其实就是函数,汇编里的函数,函数无非就是地址
  • 对一般的显式字符都要执行do_self
    在这里插入图片描述

  • 接下来载入key_map

1.2 key_map


  • 可以看出存入的都是ASCII码,也就是之前的可显式字符
  • 所以这个就是可显式字符的ASCII码表
  • 这个表的起始地址已经赋给了ebxlea key map, %ebx;
  • 再加上刚才的扫描码,扫描码肯定对应的是这个表的偏移
  • 有了这两个东西,就能找到你按下的这个键所对应的ASCII码赋给al
  • 所以执行到这里已经得到ASCII码了,然后放到缓冲队列
  • 现在放到缓冲队列等着上面的进程去拿,执行scanf的时候就要拿到这些东西
  • 所以接下来是put_queue
  • 那么put_queue无非就是得到列表,上次是write_q现在是read_q

在这里插入图片描述


1.3 put_queue

  • 现在得到ASCII码放到了队列

在这里插入图片描述


综上:键盘的驱动就是写个中断处理程序,根据扫描码得到ASCII码,或者根据扫描码进行相应的处理函数,或者得到扫描码,放到read_q这个队列中就完事,然后上层是和文件接在一起了,scanf(read)就从队列中取就行了,和写write_q的队列一样

1.4 键盘处理


  • 从硬件开始,就是从中断开始
  • 取出ASCII码放到read_q里
  • 经过转译放到secondary(这里才是scanf真正取的)
  • 之后回显write_q(回显的时候调用con_write即可回显)
    在这里插入图片描述

1.5 回显

  • 怎么回显?
  • 得到c,放到write_q中写就行
  • 再放到缓冲队列当中,写就行

2 总结


  • 都是文件API
  • 形成了一个统一的文件视图,最终落实到out(如果往下写的话)
  • 设备处理落实到了中断处理
    在这里插入图片描述

  • 解答:
  • 在tty_write当中把c变成了*号,那么按下F12得调用这个程序
  • 所以只需要在相应的扫描码处理的时候,改变一下F12按键的功能,现在的F12肯定用的是func当中的API去处理的,只需要把func改成别的名字,例如
myFunc
{
	if (flag == 0)//设置一个flag,按下一个F12输出全是*,再按下就正常,通过flag来判断
	{
		flag = 1;//等于0就置成1
	}
	tty_write()
	{
		if (flag == 1)
		{
			c = '*';
			cout << "*";//所以write_q里面就是*号
		}
	}
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值