字符显示的控制

来源:互联网 发布:权重域名出售 编辑:程序博客网 时间:2024/05/16 16:14

第六次实验可以算是很简单的一次了,只要知道了0.11如何响应你的键盘事件,一切问题都迎刃而解了。实现这个实验的方法有很多,我的也是仅供参考,其他方法可能还有些是涉及到修改汇编代码的。

首先,要做的就是在linux-0.11\kernel\chr_drv文件夹下的keyboard.S文件中,将第245行的call show_stat注释掉或者删掉都可以。在原来的代码中,按下F12便是调用了keyboard.S的call show_stat,而call show_stat又调用了其他的一些方法,是用来显示进程信息的。

原始的keyboard.S文件,方便大家查找call show_stat的位置。

func:pushl %eaxpushl %ecxpushl %edxcall show_statpopl %edxpopl %ecxpopl %eaxsubb $0x3B,%aljb end_funccmpb $9,%aljbe ok_funcsubb $18,%alcmpb $10,%aljb end_funccmpb $11,%alja end_func
接着,进入正题,我们需要知道操作系统对于F12的按下,所获取的code是什么。为了知道这,我采用了很简单但也很暴力的方法,用printk方法来打印。最后根据打印的信息,我们可以知道F12的按下相当于三个键的按下,分别是21,97和76。在完成了这些准备工作之后,可以进入编写对F12按下的响应捕获事件了。

值得说明的一点是,对于这三个键值的捕获利用到了状态机的思想。虽然当时并不了解状态机,但是确实在编程中使用了这样的思想,也即必须在连续获取21,97和76才认为是F12的按下。

在linux-0.11\kernel\chr_drv文件夹下的tty_io.c文件

首先声明了这些标志位

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

在copy_to_cooked函数里实现我们的获取键值为21,97,和76.在获取了这三个键之后设置标志位flag

void copy_to_cooked(struct tty_struct * tty){signed char c;while (!EMPTY(tty->read_q) && !FULL(tty->secondary)) {GETCH(tty->read_q,c);/*printk("\nI am %d\n",c);*/if (c == 27){flag1 = 1;}else if (flag1 == 1 && c == 91 && flag2 == 0){flag2 = 1;}else if (flag1 == 1 && flag2 == 1 && c == 91){flag3 = 1;}else if (flag1 == 1 && flag2 == 1 && flag3 == 1 && c == 76){flag *= -1;continue ;}else {flag1 = 0;flag2 = 0;flag3 = 0;}if (c==13)if (I_CRNL(tty))c=10;else if (I_NOCR(tty))continue;else ;else if (c==10 && I_NLCR(tty))c=13;if (I_UCLC(tty))c=tolower(c);if (L_CANON(tty)) {if (c==KILL_CHAR(tty)) {/* deal with killing the input line */while(!(EMPTY(tty->secondary) ||        (c=LAST(tty->secondary))==10 ||        c==EOF_CHAR(tty))) {call show_statif (L_ECHO(tty)) {if (c<32)PUTCH(127,tty->write_q);PUTCH(127,tty->write_q);tty->write(tty);}DEC(tty->secondary.head);}continue;}if (c==ERASE_CHAR(tty)) {if (EMPTY(tty->secondary) ||   (c=LAST(tty->secondary))==10 ||   c==EOF_CHAR(tty))continue;if (L_ECHO(tty)) {if (c<32)PUTCH(127,tty->write_q);PUTCH(127,tty->write_q);tty->write(tty);}DEC(tty->secondary.head);continue;}if (c==STOP_CHAR(tty)) {tty->stopped=1;continue;}if (c==START_CHAR(tty)) {tty->stopped=0;continue;}}if (L_ISIG(tty)) {if (c==INTR_CHAR(tty)) {tty_intr(tty,INTMASK);continue;}if (c==QUIT_CHAR(tty)) {tty_intr(tty,QUITMASK);continue;}}if (c==10 || c==EOF_CHAR(tty))tty->secondary.data++;if (L_ECHO(tty)) {if (c==10) {PUTCH(10,tty->write_q);PUTCH(13,tty->write_q);} else if (c<32) {if (L_ECHOCTL(tty)) {PUTCH('^',tty->write_q);PUTCH(c+64,tty->write_q);}} elsePUTCH(c,tty->write_q);tty->write(tty);}/*printk("\nI am %d after..\n",c);*/PUTCH(c,tty->secondary);}wake_up(&tty->secondary.proc_list);}

在linux-0.11\kernel\chr_drv文件夹下的console.c文件

设置了一个外部的变量flag,表明是否是F12的按下

extern int flag;

在con_write方法中对字母和数字替换为“*”即可。


void con_write(struct tty_struct * tty){int nr;char c;nr = CHARS(tty->write_q);while (nr--) {GETCH(tty->write_q,c);switch(state) {case 0:if (c>31 && c<127) {if (x>=video_num_columns) {x -= video_num_columns;pos -= video_size_row;lf();}if (((c>='A' && c<='Z')||(c>='a' && c<='z')) && flag == 1)c = '*';__asm__("movb attr,%%ah\n\t""movw %%ax,%1\n\t"::"a" (c),"m" (*(short *)pos));pos += 2;x++;} else if (c==27)state=1;else if (c==10 || c==11 || c==12)lf();else if (c==13)cr();else if (c==ERASE_CHAR(tty))del();else if (c==8) {if (x) {x--;pos -= 2;}} else if (c==9) {c=8-(x&7);x += c;pos += c<<1;if (x>video_num_columns) {x -= video_num_columns;pos -= video_size_row;lf();}c=9;} else if (c==7)sysbeep();break;case 1:state=0;if (c=='[')state=2;else if (c=='E')gotoxy(0,y+1);else if (c=='M')ri();else if (c=='D')lf();else if (c=='Z')respond(tty);else if (x=='7')save_cur();else if (x=='8')restore_cur();break;case 2:for(npar=0;npar<NPAR;npar++)par[npar]=0;npar=0;state=3;if ((ques=(c=='?')))break;case 3:if (c==';' && npar<NPAR-1) {npar++;break;} else if (c>='0' && c<='9') {par[npar]=10*par[npar]+c-'0';break;} else state=4;case 4:state=0;switch(c) {case 'G': case '`':if (par[0]) par[0]--;gotoxy(par[0],y);break;case 'A':if (!par[0]) par[0]++;gotoxy(x,y-par[0]);break;case 'B': case 'e':if (!par[0]) par[0]++;gotoxy(x,y+par[0]);break;case 'C': case 'a':if (!par[0]) par[0]++;gotoxy(x+par[0],y);break;case 'D':if (!par[0]) par[0]++;gotoxy(x-par[0],y);break;case 'E':if (!par[0]) par[0]++;gotoxy(0,y+par[0]);break;case 'F':if (!par[0]) par[0]++;gotoxy(0,y-par[0]);break;case 'd':if (par[0]) par[0]--;gotoxy(x,par[0]);break;case 'H': case 'f':if (par[0]) par[0]--;if (par[1]) par[1]--;gotoxy(par[1],par[0]);break;case 'J':csi_J(par[0]);break;case 'K':csi_K(par[0]);break;case 'L':csi_L(par[0]);break;case 'M':csi_M(par[0]);break;case 'P':csi_P(par[0]);break;case '@':csi_at(par[0]);break;case 'm':csi_m();break;case 'r':if (par[0]) par[0]--;if (!par[1]) par[1] = video_num_lines;if (par[0] < par[1] &&    par[1] <= video_num_lines) {top=par[0];bottom=par[1];}break;case 's':save_cur();break;case 'u':restore_cur();break;}}}set_cursor();}

最后说明的一点是,上述的修改并不会对向文件输出的字符进行修改,只过滤了向终端输出的字符。





原创粉丝点击