1. 程式人生 > >哈爾濱工業大學作業系統第六次實驗---姚逢靖

哈爾濱工業大學作業系統第六次實驗---姚逢靖

如何對輸出字元進行過濾,我的第二種方案是採用將待輸出的字串輸出過濾到一塊對映到使用者態的記憶體中,這種方法的好處是不管是什麼樣的檔案都不需要

修改它的“write”函式。

修改程序控制快(sched.h),修改struct task_struct的最後兩行,修改INIT_TASK :

#ifndef _SCHED_H
#define _SCHED_H


#define NR_TASKS 64
#define HZ 100


#define FIRST_TASK task[0]
#define LAST_TASK task[NR_TASKS-1]


#include <linux/head.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <signal.h>


#if (NR_OPEN > 32)
#error "Currently the close-on-exec-flags are in one word, max 32 files/proc"
#endif


#define TASK_RUNNING0
#define TASK_INTERRUPTIBLE1
#define TASK_UNINTERRUPTIBLE2
#define TASK_ZOMBIE3
#define TASK_STOPPED4


#ifndef NULL
#define NULL ((void *) 0)
#endif


extern int copy_page_tables(unsigned long from, unsigned long to, long size);
extern int free_page_tables(unsigned long from, unsigned long size);


extern void sched_init(void);
extern void schedule(void);
extern void trap_init(void);
#ifndef PANIC
volatile void panic(const char * str);
#endif
extern int tty_write(unsigned minor,char * buf,int count);


typedef int (*fn_ptr)();


struct i387_struct {
longcwd;
longswd;
longtwd;
longfip;
longfcs;
longfoo;
longfos;
longst_space[20];/* 8*10 bytes for each FP-reg = 80 bytes */
};


struct tss_struct {
longback_link;/* 16 high bits zero */
longesp0;
longss0;/* 16 high bits zero */
longesp1;
longss1;/* 16 high bits zero */
longesp2;
longss2;/* 16 high bits zero */
longcr3;
longeip;
longeflags;
longeax,ecx,edx,ebx;
longesp;
longebp;
longesi;
longedi;
longes;/* 16 high bits zero */
longcs;/* 16 high bits zero */
longss;/* 16 high bits zero */
longds;/* 16 high bits zero */
longfs;/* 16 high bits zero */
longgs;/* 16 high bits zero */
longldt;/* 16 high bits zero */
longtrace_bitmap;/* bits: trace 0, bitmap 16-31 */
struct i387_struct i387;
};


struct task_struct {
/* these are hardcoded - don't touch */
//long filter;
long state; /* -1 unrunnable, 0 runnable, >0 stopped */
long counter;
long priority;
long signal;
struct sigaction sigaction[32];
long blocked; /* bitmap of masked signals */
/* various fields */
int exit_code;
unsigned long start_code,end_code,end_data,brk,start_stack;
long pid,father,pgrp,session,leader;
unsigned short uid,euid,suid;
unsigned short gid,egid,sgid;
long alarm;
long utime,stime,cutime,cstime,start_time;
unsigned short used_math;
/* file system info */
int tty; /* -1 if no tty, so it must be signed */
unsigned short umask;
struct m_inode * pwd;
struct m_inode * root;
struct m_inode * executable;
unsigned long close_on_exec;
struct file * filp[NR_OPEN];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
struct desc_struct ldt[3];
/* tss for this task */
struct tss_struct tss;
long filter;
char *filter_kernel;
};


/*
 *  INIT_TASK is used to set up the first task table, touch at
 * your own risk!. Base=0, limit=0x9ffff (=640kB)
 */
#define INIT_TASK \
/*state etc */{ 0,15,15, \
/* signals */0,{{},},0, \
/* ec,brk... */0,0,0,0,0,0, \
/* pid etc.. */0,-1,0,0,0, \
/* uid etc */0,0,0,0,0,0, \
/* alarm */0,0,0,0,0,0, \
/* math */0, \
/* fs info */-1,0022,NULL,NULL,NULL,0, \
/* filp */{NULL,}, \
{ \
{0,0}, \
/* ldt */{0x9f,0xc0fa00}, \
{0x9f,0xc0f200}, \
}, \
/*tss*/{0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,\
0,0,0,0,0,0,0,0, \
0,0,0x17,0x17,0x17,0x17,0x17,0x17, \
_LDT(0),0x80000000, \
{}, \
0, 0\
}, \
}


extern struct task_struct *task[NR_TASKS];
extern struct task_struct *last_task_used_math;
extern struct task_struct *current;
extern long volatile jiffies;
extern long startup_time;


#define CURRENT_TIME (startup_time+jiffies/HZ)


extern void add_timer(long jiffies, void (*fn)(void));
extern void sleep_on(struct task_struct ** p);
extern void interruptible_sleep_on(struct task_struct ** p);
extern void wake_up(struct task_struct ** p);


/*
 * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall
 * 4-TSS0, 5-LDT0, 6-TSS1 etc ...
 */
#define FIRST_TSS_ENTRY 4
#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
#define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n)))
#define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n)))
#define str(n) \
__asm__("str %%ax\n\t" \
"subl %2,%%eax\n\t" \
"shrl $4,%%eax" \
:"=a" (n) \
:"a" (0),"i" (FIRST_TSS_ENTRY<<3))
/*
 *switch_to(n) should switch tasks to task nr n, first
 * checking that n isn't the current task, in which case it does nothing.
 * This also clears the TS-flag if the task we switched to has used
 * tha math co-processor latest.
 */
#define switch_to(n) {\
struct {long a,b;} __tmp; \
__asm__("cmpl %%ecx,current\n\t" \
"je 1f\n\t" \
"movw %%dx,%1\n\t" \
"xchgl %%ecx,current\n\t" \
"ljmp *%0\n\t" \
"cmpl %%ecx,last_task_used_math\n\t" \
"jne 1f\n\t" \
"clts\n" \
"1:" \
::"m" (*&__tmp.a),"m" (*&__tmp.b), \
"d" (_TSS(n)),"c" ((long) task[n])); \
}


#define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000)


#define _set_base(addr,base)  \
__asm__ ("push %%edx\n\t" \
"movw %%dx,%0\n\t" \
"rorl $16,%%edx\n\t" \
"movb %%dl,%1\n\t" \
"movb %%dh,%2\n\t" \
"pop %%edx" \
::"m" (*((addr)+2)), \
"m" (*((addr)+4)), \
"m" (*((addr)+7)), \
"d" (base) \
)


#define _set_limit(addr,limit) \
__asm__ ("push %%edx\n\t" \
"movw %%dx,%0\n\t" \
"rorl $16,%%edx\n\t" \
"movb %1,%%dh\n\t" \
"andb $0xf0,%%dh\n\t" \
"orb %%dh,%%dl\n\t" \
"movb %%dl,%1\n\t" \
"pop %%edx" \
::"m" (*(addr)), \
"m" (*((addr)+6)), \
"d" (limit) \
)


#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )


/**
#define _get_base(addr) ({\
unsigned long __base; \
__asm__("movb %3,%%dh\n\t" \
"movb %2,%%dl\n\t" \
"shll $16,%%edx\n\t" \
"movw %1,%%dx" \
:"=d" (__base) \
:"m" (*((addr)+2)), \
"m" (*((addr)+4)), \
"m" (*((addr)+7)) \
        :"memory"); \
__base;})
**/


static inline unsigned long _get_base(char * addr)
{
         unsigned long __base;
         __asm__("movb %3,%%dh\n\t"
                 "movb %2,%%dl\n\t"
                 "shll $16,%%edx\n\t"
                 "movw %1,%%dx"
                 :"=&d" (__base)
                 :"m" (*((addr)+2)),
                  "m" (*((addr)+4)),
                  "m" (*((addr)+7)));
         return __base;
}


#define get_base(ldt) _get_base( ((char *)&(ldt)) )


#define get_limit(segment) ({ \
unsigned long __limit; \
__asm__("lsll %1,%0\n\tincl %0":"=r" (__limit):"r" (segment)); \
__limit;})


#endif

修改read_write檔案,主要是sys_write中的if(filter_mark){...}:

/*
 *  linux/fs/read_write.c
 *
 *  (C) 1991  Linus Torvalds
 */


#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>


#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/segment.h>
#include <string.h>


extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos);
extern int read_pipe(struct m_inode * inode, char * buf, int count);
extern int write_pipe(struct m_inode * inode, char * buf, int count);
extern int block_read(int dev, off_t * pos, char * buf, int count);
extern int block_write(int dev, off_t * pos, char * buf, int count);
extern int file_read(struct m_inode * inode, struct file * filp,
char * buf, int count);
extern int file_write(struct m_inode * inode, struct file * filp,
char * buf, int count);
extern int filter_mark;


//#define FILTER_BUFFER_SIZE (1024 * 4)
//static char *filter_buffer;
int sys_lseek(unsigned int fd,off_t offset, int origin)
{
struct file * file;
int tmp;


if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)
  || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev)))
return -EBADF;
if (file->f_inode->i_pipe)
return -ESPIPE;
switch (origin) {
case 0:
if (offset<0) return -EINVAL;
file->f_pos=offset;
break;
case 1:
if (file->f_pos+offset<0) return -EINVAL;
file->f_pos += offset;
break;
case 2:
if ((tmp=file->f_inode->i_size+offset) < 0)
return -EINVAL;
file->f_pos = tmp;
break;
default:
return -EINVAL;
}
return file->f_pos;
}


static char to_star(char c)
{
if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
c = '*';
return c;


}


void do_filter(char *buf, int count, char *filter_buffer, char *user)
{
int i = 0;
char c;
for(; i < count; i ++)
{
c = get_fs_byte(buf + i);
//printk("%c", c);
filter_buffer[i] = to_star(c);
put_fs_byte(to_star(c), user + i);
}
//printk("\n");
}


int sys_read(unsigned int fd,char * buf,int count)
{
struct file * file;
struct m_inode * inode;



if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))
return -EINVAL;
if (!count)
return 0;
verify_area(buf,count);

inode = file->f_inode;
if (inode->i_pipe)
return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;
if (S_ISCHR(inode->i_mode))
return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);
if (S_ISBLK(inode->i_mode))
return block_read(inode->i_zone[0],&file->f_pos,buf,count);
if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {
if (count+file->f_pos > inode->i_size)
count = inode->i_size - file->f_pos;
if (count<=0)
return 0;
return file_read(inode,file,buf,count);
}
printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
return -EINVAL;
}


int sys_write(unsigned int fd,char * buf,int count)
{
struct file * file;
struct m_inode * inode;
char *filter_addr; /*使用者態記憶體地址*/
char *filter_buffer;/*核心態的地址*/

if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd]) || count > 4 * 1024)
return -EINVAL;
if (!count)
return 0;
inode=file->f_inode;
/*使用字元過濾*/
if(filter_mark)
{
if(!current->filter && !current->filter_kernel)
{
filter_buffer = (char*)get_free_page();
if(!filter_buffer)
{
panic("Init sys_write failed\n");
}
current->filter_kernel = filter_buffer;


filter_addr = put_page(filter_buffer, current->start_code + current->brk);
if(!filter_addr)
{
panic("page mape failed\n");
}


current->filter = current->brk;
}


do_filter(buf, count, current->filter_kernel, current->filter);


buf = current->filter;

}
if (inode->i_pipe)
return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO;
if (S_ISCHR(inode->i_mode))
return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos);
if (S_ISBLK(inode->i_mode))
return block_write(inode->i_zone[0],&file->f_pos,buf,count);
if (S_ISREG(inode->i_mode))
return file_write(inode,file,buf,count);
printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);
return -EINVAL;
}

修改console.c,新增(隨便新增到哪),只要是全域性的)

/*是否進行過濾的標誌*/
int filter_mark = 0;


void reserve_filter_mark()
{
filter_mark = filter_mark ? 0 : 1;
//printk("I am filtering...and filter is %d\n", filter_mark);
}

修改keyboard.S:

/*
 *  linux/kernel/keyboard.S
 *
 *  (C) 1991  Linus Torvalds
 */


/*
 *Thanks to Alfred Leung for US keyboard patches
 *Wolfgang Thiel for German keyboard patches
 *Marc Corsini for the French keyboard
 */


#include <linux/config.h>


.text
.globl keyboard_interrupt


/*
 * these are for the keyboard read functions
 */
size= 1024 /* must be a power of two ! And MUST be the same
  as in tty_io.c !!!! */
head = 4
tail = 8
proc_list = 12
buf = 16


mode:.byte 0 /* caps, alt, ctrl and shift mode */
leds:.byte 2 /* num-lock, caps, scroll-lock mode (nom-lock on) */
e0:.byte 0


/*
 *  con_int is the real interrupt routine that reads the
 *  keyboard scan-code and converts it into the appropriate
 *  ascii character(s).
 */
keyboard_interrupt:
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
push %ds
push %es
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
xor %al,%al /* %eax is scan code */
inb $0x60,%al
cmpb $0xe0,%al
je set_e0
cmpb $0xe1,%al
je set_e1
call key_table(,%eax,4)
movb $0,e0
e0_e1:inb $0x61,%al
jmp 1f
1:jmp 1f
1:orb $0x80,%al
jmp 1f
1:jmp 1f
1:outb %al,$0x61
jmp 1f
1:jmp 1f
1:andb $0x7F,%al
outb %al,$0x61
movb $0x20,%al
outb %al,$0x20
pushl $0
call do_tty_interrupt
addl $4,%esp
pop %es
pop %ds
popl %edx
popl %ecx
popl %ebx
popl %eax
iret
set_e0:movb $1,e0
jmp e0_e1
set_e1:movb $2,e0
jmp e0_e1


/*
 * This routine fills the buffer with max 8 bytes, taken from
 * %ebx:%eax. (%edx is high). The bytes are written in the
 * order %al,%ah,%eal,%eah,%bl,%bh ... until %eax is zero.
 */
put_queue:
pushl %ecx
pushl %edx
movl table_list,%edx# read-queue for console
movl head(%edx),%ecx
1:movb %al,buf(%edx,%ecx)
incl %ecx
andl $size-1,%ecx
cmpl tail(%edx),%ecx# buffer full - discard everything
je 3f
shrdl $8,%ebx,%eax
je 2f
shrl $8,%ebx
jmp 1b
2:movl %ecx,head(%edx)
movl proc_list(%edx),%ecx
testl %ecx,%ecx
je 3f
movl $0,(%ecx)
3:popl %edx
popl %ecx
ret


ctrl:movb $0x04,%al
jmp 1f
alt:movb $0x10,%al
1:cmpb $0,e0
je 2f
addb %al,%al
2:orb %al,mode
ret
unctrl:movb $0x04,%al
jmp 1f
unalt:movb $0x10,%al
1:cmpb $0,e0
je 2f
addb %al,%al
2:notb %al
andb %al,mode
ret


lshift:
orb $0x01,mode
ret
unlshift:
andb $0xfe,mode
ret
rshift:
orb $0x02,mode
ret
unrshift:
andb $0xfd,mode
ret


caps:testb $0x80,mode
jne 1f
xorb $4,leds
xorb $0x40,mode
orb $0x80,mode
set_leds:
call kb_wait
movb $0xed,%al/* set leds command */
outb %al,$0x60
call kb_wait
movb leds,%al
outb %al,$0x60
ret
uncaps:andb $0x7f,mode
ret
scroll:
xorb $1,leds
jmp set_leds
num:xorb $2,leds
jmp set_leds


/*
 *  curosr-key/numeric keypad cursor keys are handled here.
 *  checking for numeric keypad etc.
 */
cursor:
subb $0x47,%al
jb 1f
cmpb $12,%al
ja 1f
jne cur2 /* check for ctrl-alt-del */
testb $0x0c,mode
je cur2
testb $0x30,mode
jne reboot
cur2:cmpb $0x01,e0/* e0 forces cursor movement */
je cur
testb $0x02,leds/* not num-lock forces cursor */
je cur
testb $0x03,mode/* shift forces cursor */
jne cur
xorl %ebx,%ebx
movb num_table(%eax),%al
jmp put_queue
1:ret


cur:movb cur_table(%eax),%al
cmpb $'9,%al
ja ok_cur
movb $'~,%ah
ok_cur:shll $16,%eax
movw $0x5b1b,%ax
xorl %ebx,%ebx
jmp put_queue


#if defined(KBD_FR)
num_table:
.ascii "789 456 1230."
#else
num_table:
.ascii "789 456 1230,"
#endif
cur_table:
.ascii "HA5 DGC YB623"


/*
 * this routine handles function keys
 */
func:
pushl %eax
pushl %ecx
pushl %edx
/*call show_stat*/
popl %edx
popl %ecx
popl %eax
subb $0x3B,%al
jb end_func
cmpb $9,%al
jbe ok_func
subb $18,%al
cmpb $10,%al
jb end_func
/*如果是F11*/
cmpb $10, %al
je ok_func
cmpb $11,%al
je is_f12;
jmp end_func
is_f12:
call reserve_filter_mark
ret
ok_func:
cmpl $4,%ecx /* check that there is enough room */
jl end_func
movl func_table(,%eax,4),%eax
xorl %ebx,%ebx
jmp put_queue
end_func:
ret


/*
 * function keys send F1:'esc [ [ A' F2:'esc [ [ B' etc.
 */
func_table:
.long 0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b
.long 0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b
.long 0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b


#ifdefined(KBD_FINNISH)
key_map:
.byte 0,27
.ascii "1234567890+'"
.byte 127,9
.ascii "qwertyuiop}"
.byte 0,13,0
.ascii "asdfghjkl|{"
.byte 0,0
.ascii "'zxcvbnm,.-"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '<
.fill 10,1,0


shift_map:
.byte 0,27
.ascii "!\"#$%&/()=?`"
.byte 127,9
.ascii "QWERTYUIOP]^"
.byte 13,0
.ascii "ASDFGHJKL\\["
.byte 0,0
.ascii "*ZXCVBNM;:_"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '>
.fill 10,1,0


alt_map:
.byte 0,0
.ascii "\

[email protected]\0$\0\0{[]}\\\0"
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte '~,13,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0 /* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte 0,0,0,0,0/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '|
.fill 10,1,0


#elif defined(KBD_US)


key_map:
.byte 0,27
.ascii "1234567890-="
.byte 127,9
.ascii "qwertyuiop[]"
.byte 13,0
.ascii "asdfghjkl;'"
.byte '`,0
.ascii "\\zxcvbnm,./"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '<
.fill 10,1,0




shift_map:
.byte 0,27
.ascii "[email protected]#$%^&*()_+"
.byte 127,9
.ascii "QWERTYUIOP{}"
.byte 13,0
.ascii "ASDFGHJKL:\""
.byte '~,0
.ascii "|ZXCVBNM<>?"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '>
.fill 10,1,0


alt_map:
.byte 0,0
.ascii "\[email protected]\0$\0\0{[]}\\\0"
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte '~,13,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0 /* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte 0,0,0,0,0/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '|
.fill 10,1,0


#elif defined(KBD_GR)


key_map:
.byte 0,27
.ascii "1234567890\\'"
.byte 127,9
.ascii "[email protected]+"
.byte 13,0
.ascii "asdfghjkl[]^"
.byte 0,'#
.ascii "yxcvbnm,.-"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '<
.fill 10,1,0




shift_map:
.byte 0,27
.ascii "!\"#$%&/()=?`"
.byte 127,9
.ascii "QWERTZUIOP\\*"
.byte 13,0
.ascii "ASDFGHJKL{}~"
.byte 0,''
.ascii "YXCVBNM;:_"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '>
.fill 10,1,0


alt_map:
.byte 0,0
.ascii "\[email protected]\0$\0\0{[]}\\\0"
.byte 0,0
.byte '@,0,0,0,0,0,0,0,0,0,0
.byte '~,13,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0 /* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte 0,0,0,0,0/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '|
.fill 10,1,0




#elif defined(KBD_FR)


key_map:
.byte 0,27
.ascii "&{\"'(-}_/@)="
.byte 127,9
.ascii "azertyuiop^$"
.byte 13,0
.ascii "qsdfghjklm|"
.byte '`,0,42 /* coin sup gauche, don't know, [*|mu] */
.ascii "wxcvbn,;:!"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '<
.fill 10,1,0


shift_map:
.byte 0,27
.ascii "1234567890]+"
.byte 127,9
.ascii "AZERTYUIOP<>"
.byte 13,0
.ascii "QSDFGHJKLM%"
.byte '~,0,'#
.ascii "WXCVBN?./\\"
.byte 0,'*,0,32/* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte '-,0,0,0,'+/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '>
.fill 10,1,0


alt_map:
.byte 0,0
.ascii "\0~#{[|`\\^@]}"
.byte 0,0
.byte '@,0,0,0,0,0,0,0,0,0,0
.byte '~,13,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0 /* 36-39 */
.fill 16,1,0 /* 3A-49 */
.byte 0,0,0,0,0/* 4A-4E */
.byte 0,0,0,0,0,0,0/* 4F-55 */
.byte '|
.fill 10,1,0


#else
#error "KBD-type not defined"
#endif
/*
 * do_self handles "normal" keys, ie keys that don't change meaning
 * and which have just one character returns.
 */
do_self:
lea alt_map,%ebx
testb $0x20,mode/* alt-gr */
jne 1f
lea shift_map,%ebx
testb $0x03,mode
jne 1f
lea key_map,%ebx
1:movb (%ebx,%eax),%al
orb %al,%al
je none
testb $0x4c,mode/* ctrl or caps */
je 2f
cmpb $'a,%al
jb 2f
cmpb $'},%al
ja 2f
subb $32,%al
2:testb $0x0c,mode/* ctrl */
je 3f
cmpb $64,%al
jb 3f
cmpb $64+32,%al
jae 3f
subb $64,%al
3:testb $0x10,mode/* left alt */
je 4f
orb $0x80,%al
4:andl $0xff,%eax
xorl %ebx,%ebx
call put_queue
none:ret


/*
 * minus has a routine of it's own, as a 'E0h' before
 * the scan code for minus means that the numeric keypad
 * slash was pushed.
 */
minus:cmpb $1,e0
jne do_self
movl $'/,%eax
xorl %ebx,%ebx
jmp put_queue


/*
 * This table decides which routine to call when a scan-code has been
 * gotten. Most routines just call do_self, or none, depending if
 * they are make or break.
 */
key_table:
.long none,do_self,do_self,do_self/* 00-03 s0 esc 1 2 */
.long do_self,do_self,do_self,do_self/* 04-07 3 4 5 6 */
.long do_self,do_self,do_self,do_self/* 08-0B 7 8 9 0 */
.long do_self,do_self,do_self,do_self/* 0C-0F + ' bs tab */
.long do_self,do_self,do_self,do_self/* 10-13 q w e r */
.long do_self,do_self,do_self,do_self/* 14-17 t y u i */
.long do_self,do_self,do_self,do_self/* 18-1B o p } ^ */
.long do_self,ctrl,do_self,do_self/* 1C-1F enter ctrl a s */
.long do_self,do_self,do_self,do_self/* 20-23 d f g h */
.long do_self,do_self,do_self,do_self/* 24-27 j k l | */
.long do_self,do_self,lshift,do_self/* 28-2B { para lshift , */
.long do_self,do_self,do_self,do_self/* 2C-2F z x c v */
.long do_self,do_self,do_self,do_self/* 30-33 b n m , */
.long do_self,minus,rshift,do_self/* 34-37 . - rshift * */
.long alt,do_self,caps,func/* 38-3B alt sp caps f1 */
.long func,func,func,func/* 3C-3F f2 f3 f4 f5 */
.long func,func,func,func/* 40-43 f6 f7 f8 f9 */
.long func,num,scroll,cursor/* 44-47 f10 num scr home */
.long cursor,cursor,do_self,cursor/* 48-4B up pgup - left */
.long cursor,cursor,do_self,cursor/* 4C-4F n5 right + end */
.long cursor,cursor,cursor,cursor/* 50-53 dn pgdn ins del */
.long none,none,do_self,func/* 54-57 sysreq ? < f11 */
.long func,none,none,none/* 58-5B f12 ? ? ? */
.long none,none,none,none/* 5C-5F ? ? ? ? */
.long none,none,none,none/* 60-63 ? ? ? ? */
.long none,none,none,none/* 64-67 ? ? ? ? */
.long none,none,none,none/* 68-6B ? ? ? ? */
.long none,none,none,none/* 6C-6F ? ? ? ? */
.long none,none,none,none/* 70-73 ? ? ? ? */
.long none,none,none,none/* 74-77 ? ? ? ? */
.long none,none,none,none/* 78-7B ? ? ? ? */
.long none,none,none,none/* 7C-7F ? ? ? ? */
.long none,none,none,none/* 80-83 ? br br br */
.long none,none,none,none/* 84-87 br br br br */
.long none,none,none,none/* 88-8B br br br br */
.long none,none,none,none/* 8C-8F br br br br */
.long none,none,none,none/* 90-93 br br br br */
.long none,none,none,none/* 94-97 br br br br */
.long none,none,none,none/* 98-9B br br br br */
.long none,unctrl,none,none/* 9C-9F br unctrl br br */
.long none,none,none,none/* A0-A3 br br br br */
.long none,none,none,none/* A4-A7 br br br br */
.long none,none,unlshift,none/* A8-AB br br unlshift br */
.long none,none,none,none/* AC-AF br br br br */
.long none,none,none,none/* B0-B3 br br br br */
.long none,none,unrshift,none/* B4-B7 br br unrshift br */
.long unalt,none,uncaps,none/* B8-BB unalt br uncaps br */
.long none,none,none,none/* BC-BF br br br br */
.long none,none,none,none/* C0-C3 br br br br */
.long none,none,none,none/* C4-C7 br br br br */
.long none,none,none,none/* C8-CB br br br br */
.long none,none,none,none/* CC-CF br br br br */
.long none,none,none,none/* D0-D3 br br br br */
.long none,none,none,none/* D4-D7 br br br br */
.long none,none,none,none/* D8-DB br ? ? ? */
.long none,none,none,none/* DC-DF ? ? ? ? */
.long none,none,none,none/* E0-E3 e0 e1 ? ? */
.long none,none,none,none/* E4-E7 ? ? ? ? */
.long none,none,none,none/* E8-EB ? ? ? ? */
.long none,none,none,none/* EC-EF ? ? ? ? */
.long none,none,none,none/* F0-F3 ? ? ? ? */
.long none,none,none,none/* F4-F7 ? ? ? ? */
.long none,none,none,none/* F8-FB ? ? ? ? */
.long none,none,none,none/* FC-FF ? ? ? ? */


/*
 * kb_wait waits for the keyboard controller buffer to empty.
 * there is no timeout - if the buffer doesn't empty, we hang.
 */
kb_wait:
pushl %eax
1:inb $0x64,%al
testb $0x02,%al
jne 1b
popl %eax
ret
/*
 * This routine reboots the machine by asking the keyboard
 * controller to pulse the reset-line low.
 */
reboot:
call kb_wait
movw $0x1234,0x472/* don't do memory check */
movb $0xfc,%al/* pulse reset and A20 low */
outb %al,$0x64
die:jmp die

相關推薦

哈爾濱工業大學作業系統實驗---

如何對輸出字元進行過濾,我的第二種方案是採用將待輸出的字串輸出過濾到一塊對映到使用者態的記憶體中,這種方法的好處是不管是什麼樣的檔案都不需要 修改它的“write”函式。 修改程序控制快(sched.h),修改struct task_struct的最後兩行,修改INIT_T

南京郵電大學java實驗報告

hid AR 控制結構 swing textarea 報告 lis tr1 listener 實 驗 報 告 ( 2017 / 2018學年 第2學期) 課程名稱 JAVA語言程序設計 實驗名

實驗:包與介面以及常用工具類的使用

實驗目的 瞭解 Java 中包(package)和介面(interface)的作用,掌握包和介面的設計方法。掌握Math類,String類和StringBuffer類的使用。 二、實驗要求 1.   瞭解 Java 系統包的結構,建立並使用自定義包。 2.   掌握介面的定義

實驗

math 素數 調用 spa can src 函數實現 \n nbsp 心得: 1)學會了如何運用函數的調用 2) 通過循環嵌套實現,用函數實現素數的判斷 1 /*利用函數計算素數個數並求和:輸入兩個正整數m 和 n(1<=m, n<=500)

作業系統2實驗報告:建立程序

姓名:倪曉東 學號:201821121020 班級:計算1811 1. 編寫程式 在伺服器上用VIM編輯器編寫一個程式:一個程序建立(fork)兩個子程序。給出原始碼:      原始碼執行結果:       2. 列印程序樹 列印1所建

哈爾濱工業大學計算機學院-模式識別-課程總結-實驗考試

我來填坑了,最近好忙,沒有時間寫部落格,今天上午剛剛進行完本課程的實驗考試,在這裡進行簡要彙總。 任務介紹 利用20000條手寫識別資料,提前訓練好分類器,考試時只需要跑預測模型即可。 本質上一個分類問題,類別總數是10。 本任務比較有意思的一點是,老師提供的訓練資料,是利用PCA與LDA降

感測器實驗報告(

7.11煙霧感測器採集實驗 一、實驗目的 掌握煙霧感測器的操作方法; 掌握煙霧感測器採集程式的程式設計方法。 二、實驗內容 在 IAR 整合開發環境中編寫煙霧感測器採集程式。 三、基礎知識 採用 MQ-2 可燃氣體感測器,它可在工業或家

小組學習總結

交流 專家 問題 master ftw print 競爭 軟件行業 利用 範佳怡 http://www.cnblogs.com/1078246525FJY/p/6883755.html 本章的敏捷流程讓我思考了許多。要想很好的應用敏捷流程其實是很考驗一個團隊人員的經驗,交

實驗報告+061+陳小蘭

內容 黑盒測試 測試 實驗 音樂 組合 正交 目的 場景 一、實驗目的 掌握黑盒測試用例設計方法 二、實驗要求 (1)對被測程序進行黑盒測試用例設計 (2)運用等價類、邊界值、決策表、狀態圖法等進行測試用例設計。 (3)對手機上任意一款音樂軟件進行黑盒測試實踐。(作

構建之法 心得

兩個 類方法 標準 目的 font 下載軟件 幫助文檔 軟件測試 使用 構建之法12、13章小結 第12章 這一章講的是用戶體驗,對於軟件的使用,用戶的體驗是非常重要的方面,如果一個軟件給用戶的體驗不好,那麽這個軟件無疑是不會受到歡迎的。但是用戶體驗和用戶界面的領域不是那麽

【Beta】 Daily Scrum Meeting

接下來 url 研究 工作 val 模塊 ref dai 團隊 【Beta】 第六次Daily Scrum Meeting 一、本次會議為第六次meeting會議 二、時間:10:00AM—10:20AM 地點:禹州樓 三、會議站立式照片 四、今日任務安

meeting會議

www 手機 div 操作 研究 開發 困難 界面 pos 【Beta】 第六次Daily Scrum Meeting 一、本次會議為第六次meeting會議 二、時間:10:00AM—10:20AM 地點:禹州樓 三、會議站立式照片 四、今日任務安排

【beta】階段 Scrum Meeting

uri eight 昨天 組成 困難 https 分析 界面 開始界面 每日任務 1.本次會議為第六次 Meeting會議; 2.本次會議在周六上午大課間,在陸大樓召開,召開本次會議為15分鐘。 一、今日站立式會議照片 二、每個人的工作 (有work item 的ID

隨筆

會有 分配任務 時間 天都 由於 甚至有 普通 當前 之間 通過學習第六章的內容,我了解了敏捷流程就是又快又好的完成工作,與傳統流程的區別在於,需要團隊所有成員根據自己的能力領取任務,以達到最高效的目的,在沖刺階段還要求成員之間每天都要開會交流,以便了解當前的進度和

七章學習體會-----(

可用 nbsp 關註 授權 體會 發的 持續交付 第七章 變化 在這周我看了第六章敏捷流程跟第七章MSF。並有了以下學習總結。 敏捷這個詞聽起來就是反應靈敏迅速而有效,而在軟件按工程裏,敏捷不同於現有做法之處在於,敏捷的價值觀和流程是個人和交流、可用的軟件、與客戶合作、響應

實驗+160+曾元鵬

java 需要 用戶名 進一步 click set 不存在 技術 利用 軟件測試實驗四 一、實驗目的 1) 學習QTP工具的使用 2)了解黑盒自動化測試 二、實驗要求 (1)對被測程序進行黑盒測試用例設計 (2)對QTP的飛機訂票系統的任一界面或控件實現自動化測

【第一組】沖刺例會

高斯模糊 osi log api 9.png 做了 設計 成員 position 開發小組:Neu Old Driver 沖刺經理:何圖 小組成員:李白洋、王彬宇、李恒雨、黃文睿、安迪 1、昨天做了什麽: 黃文睿:高斯模糊的2D效果

【第二組】項目沖刺(Beta版本)每日例會 2017/7/24

ima size 界面優化 png 整理 strong 技術 eight logs 項目沖刺(Beta版本)第六次每日例會 開發小組:Hunter 沖刺經理:林貴淵 小組成員:林軒宇,張太,李明君,劉仁人 1、每日例會內容 (1)昨天做了什麽 1、林軒宇:Button音

作業(二)

第六次作業 absolut margin posit logs jpg ng- mage ima div { margin: 20px } #d1 { width: 180px; height: 180px; background-color: yellow; border

實驗計算分段函數 計算分段函數和循環NEW 分支+循環加強版 實驗報告

scan amp 函數 寬度 中大 解決方法 sca -1 三次 一.實驗題目,設計思路,實現方法 第四次分支+循環 加強版 (2-2計算個人所得稅,2-7 裝睡,2-8計算天數) 設計思路:2-2 用if-else的語句,與計算分段函數的題類似的做法;2-7 運用for語