哈工大操作系统实验5—I/O设备管理

实验内容

本实验的基本内容是修改Linux 0.11的终端设备处理代码,对键盘输入和字符显示进行非常规的控制。

在初始状态,一切如常。用户按一次F12后,把应用程序向终端输出所有字母都替换为“*”。用户再按一次F12,又恢复正常。第三次按F12,再进行输出替换。依此类推。

以ls命令为例:

正常情况:

ls 
hello.c hello.o hello

第一次按F12,然后输入ls:

** 
*

第二次按F12,然后输入ls:

ls 
hello.c hello.o hello

第三次按F12,然后输入ls:

** 
*

linux-0.11/kernel/chr_drv/keyboard.S

func:
    /*程序210行子函数处理功能键
      将功能键转化成转义字符存取到读队列中*/
    pushl %eax
    pushl %ecx
    pushl %edx
    //call show_stat   //将该行注释掉,调用显示各任务的状态函数,我们不需要显示
    popl %edx
    popl %ecx
    popl %eax

linux-0.11/kernel/chr_drv/tty_io.c

修改copy_to_cooked函数 

增加字符判断,由于按下F12时,判断是否为F1-F12的扫描码,若是,则将查func_table中的4个字节的转义字符序列放入缓冲队列中。 
若不是,则不处理并返回。例如:功能键发送的扫描码,F12键为:‘esc [ [ L’。

具体参考:Linux0.11完全注释keyboard.S文件238行左右的代码。 
/* 
* linux/kernel/tty_io.c 
* 
* (C) 1991 Linus Torvalds 
*/

/*
 * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
 * or rs-channels. It also implements echoing, cooked mode etc.
 *
 * Kill-line thanks to John T Kohl.
 */
#include <ctype.h>
#include <errno.h>
#include <signal.h>

#define ALRMMASK (1<<(SIGALRM-1))
#define KILLMASK (1<<(SIGKILL-1))
#define INTMASK (1<<(SIGINT-1))
#define QUITMASK (1<<(SIGQUIT-1))
#define TSTPMASK (1<<(SIGTSTP-1))

#include <linux/sched.h>
#include <linux/tty.h>
#include <asm/segment.h>
#include <asm/system.h>

#define _L_FLAG(tty,f)  ((tty)->termios.c_lflag & f)
#define _I_FLAG(tty,f)  ((tty)->termios.c_iflag & f)
#define _O_FLAG(tty,f)  ((tty)->termios.c_oflag & f)

#define L_CANON(tty)    _L_FLAG((tty),ICANON)
#define L_ISIG(tty) _L_FLAG((tty),ISIG)
#define L_ECHO(tty) _L_FLAG((tty),ECHO)
#define L_ECHOE(tty)    _L_FLAG((tty),ECHOE)
#define L_ECHOK(tty)    _L_FLAG((tty),ECHOK)
#define L_ECHOCTL(tty)  _L_FLAG((tty),ECHOCTL)
#define L_ECHOKE(tty)   _L_FLAG((tty),ECHOKE)

#define I_UCLC(tty) _I_FLAG((tty),IUCLC)
#define I_NLCR(tty) _I_FLAG((tty),INLCR)
#define I_CRNL(tty) _I_FLAG((tty),ICRNL)
#define I_NOCR(tty) _I_FLAG((tty),IGNCR)

#define O_POST(tty) _O_FLAG((tty),OPOST)
#define O_NLCR(tty) _O_FLAG((tty),ONLCR)
#define O_CRNL(tty) _O_FLAG((tty),OCRNL)
#define O_NLRET(tty)    _O_FLAG((tty),ONLRET)
#define O_LCUC(tty) _O_FLAG((tty),OLCUC)


int flag = -1;
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int flag4 = 0;


struct tty_struct tty_table[] = {
    {
        {ICRNL,     /* change incoming CR to NL */
        OPOST|ONLCR,    /* change outgoing NL to CRNL */
        0,
        ISIG | ICANON | ECHO | ECHOCTL | ECHOKE,
        0,      /* console termio */
        INIT_C_CC},
        0,          /* initial pgrp */
        0,          /* initial stopped */
        con_write,
        {0,0,0,0,""},       /* console read-queue */
        {0,0,0,0,""},       /* console write-queue */
        {0,0,0,0,""}        /* console secondary queue */
    },{
        {0, /* no translation */
        0,  /* no translation */
        B2400 | CS8,
        0,
        0,
        INIT_C_CC},
        0,
        0,
        rs_write,
        {0x3f8,0,0,0,""},       /* rs 1 */
        {0x3f8,0,0,0,""},
        {0,0,0,0,""}
    },{
        {0, /* no translation */
        0,  /* no translation */
        B2400 | CS8,
        0,
        0,
        INIT_C_CC},
        0,
        0,
        rs_write,
        {0x2f8,0,0,0,""},       /* rs 2 */
        {0x2f8,0,0,0,""},
        {0,0,0,0,""}
    }
};

/*
 * these are the tables used by the machine code handlers.
 * you can implement pseudo-tty's or something by changing
 * them. Currently not done.
 */
struct tty_queue * table_list[]={
    &tty_table[0].read_q, &tty_table[0].write_q,
    &tty_table[1].read_q, &tty_table[1].write_q,
    &tty_table[2].read_q, &tty_table[2].write_q
    };

void tty_init(void)
{
    rs_init();
    con_init();
}

void tty_intr(struct tty_struct * tty, int mask)
{
    int i;

    if (tty->pgrp <= 0)
        return;
    for (i=0;i<NR_TASKS;i++)
        if (task[i] && task[i]->pgrp==tty->pgrp)
            task[i]->signal |= mask;
}

static void sleep_if_empty(struct tty_queue * queue)
{
    cli();
    while (!current->signal && EMPTY(*queue))
        interruptible_sleep_on
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值