经济学 管理学 法学 理学 工学 计算机 医学 文学 教育 艺术 哲学 马列理论 政治 社会 英语论文
写作指导 实习报告 述职报告 调查报告 求职信 求职简历 工作总结 入党申请书 思想汇报 入党转正申请书
普通高校 民办高校 独立学院 211工程高校 教育部直属高校 成人高校 民办成人高校 985工程高校 军校 各地招生办
 首页 >> 533学习网 >> 资源 >> 论文大全 >> 计算机 >> 正文 加载中...
基于Linux内核的键盘模拟实现
http://edu.533.com 资源频道

可以产生一个六个scancodes的队列。键盘驱动中的 handle_ scancode()函数解析scancodes流并通过kdb_translate()函数里的转换表(translation-table)将击键事件和键的释放事件(key release events)转换成连续的keycode。例如,'a'的keycode是30。击键'a'的时候便会产生keycode 30。释放a键的时候会产生keycode 158(128+30)。
然后,这些keycode通过对keymap的查询被转换成相应key符号。获得的字符被送入raw tty队列—tty_flip_buffer。receive_buf()函数周期性的从tty_flip_buffer中获得字符,然后把这些字符送入 tty read队列。
当用户进程需要得到用户的输入的时候,它会在进程的标准输入(stdin)调用read()函数。sys_read()函数调用定义在相应的tty设备(如/dev/tty0)的file_operations结构中指向tty_read的read()函数来读取字符并且返回给用户进程。

4  键盘模拟的实现
通常情况下,对键盘模拟的实现一般是通过写一个自己的键盘中断句柄来实现,但这种方法容易导致系统崩溃。因此,在这种方法的基础上可以利用勾子函数来实现。
如附图所示,这里主要用到的勾子函数包括handle_ scancode(),put_queue(),receive_buf(),tty_read()和sys_read()等函数。

附图     键盘驱动原理图


4.1  handle_scancode函数
handle_scancode函数是键盘驱动程序中的一个入口函数(参见文件/usr/src/linux/drives/char/keyboard.c):
void handle_scancode(unsigned char scancode, int down);
这里通过替换原始的handle_scancode()函数来实现纪录所有的scancode。即将原始的值保存,把新的值注册进去,从而实现所需要的功能,最后再调用回到原始值的情况下。当此新的功能函数完成后,我们就可以记录下键盘上的正确的击键行为了(其中可以包括一些特殊的key,如ctrl, alt,shift,print screen等等)。
4.2  put_queue函数
handle_scancode()函数会调用put_queue函数,用来将字符放入tty_queue。
put_queue函数在内核中定义如下:
void put_queue(int ch)
{
wake_up(&keypress_wait);
if (tty) {
tty_insert_flip_char(tty, ch, 0);
con_schedule_flip(tty);    }}
4.3  receive_buf函数
底层tty驱动调用receive_buf()这个函数用来发送硬件设备接收处理的字符。参见/usr/src/linux/drivers/char/n_tty.c:
static void n_tty_receive_buf(struct tty_struct *tty, const
unsigned char *cp, char *fp, int count)
参数cp是一个指向设备接收的输入字符的buffer的指针。参数fp是一个指向一个标记字节指针的指针。在具体的实现中,先保存原始的tty receive_buf()函数,然后重置ldisc.receive_buf到自定义的new_receive_buf()函数来记录用户的输入。
例如:要记录在终端tty1设备上的输入。
int fd = open("/dev/tty1", O_RDONLY, 0);
struct file *file = fget(fd);
struct tty_struct *tty = file->private_data;
//保存原始的receive_buf()函数
old_receive_buf = tty->ldisc.receive_buf;
//替换成新的new_receive_buf函数
tty->ldisc.receive_buf = new_receive_buf;   
//新的new_receive_buf函数
void new_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
{   
logging(tty, cp, count);    
//纪录用户击键
/* 调用回原来的receive_buf */
(*old_receive_buf)(tty, cp, fp, count);
}
4.4  tty_read函数
当一个进程需要通过sys_read()函数来读取一个tty终端的输入字符时,tty_read函数就会被调

9 7 3 1 2 3 4 8 :

加载中...
上一篇:
下一篇:
顶我一下
 
  • 最近更新
  • 最受欢迎资源榜
  •   加载中... 加载中...
     加载中...
    值得收藏!
    加载中...
    资源搜索:
     全国各省市普通高校名单
    北京 天津 河北 山西

    内蒙

    辽宁 吉林 黑龙江
    上海 江苏 浙江 安徽 福建 江西 山东 河南
    湖北 湖南 广东 广西 海南 重庆 四川 贵州
    云南 西藏 陕西 甘肃 青海 宁夏 新疆 港澳台
     全国民办普通高校名单
    北京 天津 河北 山西

    内蒙

    辽宁 吉林 黑龙江
    上海 江苏 浙江 安徽 福建 江西 山东 河南
    湖北 湖南 广东 广西 海南 重庆 四川 贵州
    云南 西藏 陕西 甘肃 青海 宁夏 新疆  
     更多导航
    有意见请联系:edu533##126.com(将##换为@)
      更多资源推荐
    论文
     
    实用文档
     
    五三三学习网
     
    好资源一起共享
      图片说话
    加载中...
      精彩推荐
    加载中...
    加载中...
    加载中...