终端总体.docx
《终端总体.docx》由会员分享,可在线阅读,更多相关《终端总体.docx(24页珍藏版)》请在冰豆网上搜索。
终端总体
终端分析
在linux系统中,所有的输入和输出都尽可能的做成象从普通文件的输入输出一样。
但是,终端I/O是比较困难的情况之一。
通常,一个进程通过从它的双亲进程继承文件描述符0,1和2,被自动的附属于一个终端。
这时,open()函数已经由进程完成,并且所附属的终端将是该进程的控制终端。
O_CREAT,O_EXCL,O_EXCL,O_TRUCN和O_APPEND标志用到终端文件时没有任何意义。
但是,有两个新的标志有用
O_NOCTTY停止这个终端作为控制终端。
O_NONBLOCK使open(),read()和write()不被阻塞。
为了简化分析,我们主要分析主机console,即主设备号为4的设备,对应下图的Memory-mappedinterface.
各种终端类型:
数据结构
structtty_struct
tty.h
当一个tty打开时,它所有的状态存于此结构。
有些信息即使tty关闭了也要维护,
如baudrate,所以它们被存放于另一个结构termios中。
tty_struct用一个struct
指向它。
由于本结构动态分配,所以它不能大于4096字节。
/*
*Whereallofthestateassociatedwithattyiskeptwhilethetty
*isopen.Sincethetermiosstateshouldbekeptevenifthetty
*hasbeenclosed---forthingslikethebaudrate,etc---itis
*notstoredhere,butratherapointertotherealstateisstored
*here.Possiblethewinsizestructureshouldhavethesame
*treatment,but
(1)thedefault80x24isusuallyrightand
(2)it's
*mostoftenusedbyawindowingsystem,whichwillsetthecorrect
*sizeeachtimethewindowiscreatedorresizedanyway.
*IMPORTANT:
sincethisstructureisdynamicallyallocated,itmust
*benolargerthan4096bytes.ChangingTTY_BUF_SIZEwillchange
*thesizeofthisstructure,anditneedstobedonewithcare.
*-TYT,9/14/92
*/
structtty_struct{
intmagic;
structtty_driverdriver;//驱动程序
structtty_ldiscldisc;//主要读写都是通过调用ldisc中的函数实现。
structtermios*termios,*termios_locked;
intpgrp;//相关进程的组识别号。
intsession;//会话号。
kdev_tdevice;//设备号
unsignedlongflags;
intcount;
structwinsizewinsize;
unsignedcharstopped:
1,hw_stopped:
1,packet:
1;
unsignedcharctrl_status;
structtty_struct*link;
structfasync_struct*fasync;
structtty_flip_bufferflip;/*用于存放键盘传来的字符*/
intmax_flip_cnt;
structwait_queue*write_wait;/*写等待队列*/
structwait_queueread_wait;/*读等待队列*/
void*disc_data;
void*driver_data;
#defineN_TTY_BUF_SIZE4096
/*
*ThefollowingisdatafortheN_TTYlinediscipline.For
*historicalreasons,thisisincludedinthettystructure.
*/
unsignedintcolumn;
unsignedcharlnext:
1,erasing:
1,raw:
1,real_raw:
1,icanon:
1;
unsignedcharclosing:
1;
unsignedshortminimum_to_wake;
unsignedoverrun_time;
intnum_overrun;
unsignedlongprocess_char_map[256/(8*sizeof(unsignedlong))];
char*read_buf;
intread_head;
intread_tail;
intread_cnt;
unsignedlongread_flags[N_TTY_BUF_SIZE/(8*sizeof(unsignedlong))];
intcanon_data;
unsignedlongcanon_head;
unsignedintcanon_column;
};
structtty_driver
tty_driver.h
structtty_driver{
intmagic;/*magicnumberforthisstructure*/
constchar*name;
intname_base;/*offsetofprintedname*/
shortmajor;/*majordevicenumber*/
shortminor_start;/*startofminordevicenumber*/
shortnum;/*numberofdevices*/
shorttype;/*typeofttydriver*/
shortsubtype;/*subtypeofttydriver*/
structtermiosinit_termios;/*Initialtermios*/
intflags;/*ttydriverflags*/
int*refcount;/*forloadablettydrivers*/
structtty_driver*other;/*onlyusedforthePTYdriver*/
/*
*Pointertothettydatastructures
*/
structtty_struct**table;
structtermios**termios;
structtermios**termios_locked;
/*
*Interfaceroutinesfromtheupperttylayertothetty
*driver.
*/
int(*open)(structtty_struct*tty,structfile*filp);
void(*close)(structtty_struct*tty,structfile*filp);
int(*write)(structtty_struct*tty,intfrom_user,
constunsignedchar*buf,intcount);
void(*put_char)(structtty_struct*tty,unsignedcharch);
void(*flush_chars)(structtty_struct*tty);
int(*write_room)(structtty_struct*tty);
int(*chars_in_buffer)(structtty_struct*tty);
int(*ioctl)(structtty_struct*tty,structfile*file,
unsignedintcmd,unsignedlongarg);
void(*set_termios)(structtty_struct*tty,structtermios*old);
void(*throttle)(structtty_struct*tty);
void(*unthrottle)(structtty_struct*tty);
void(*stop)(structtty_struct*tty);
void(*start)(structtty_struct*tty);
void(*hangup)(structtty_struct*tty);
void(*flush_buffer)(structtty_struct*tty);
void(*set_ldisc)(structtty_struct*tty);
/*
*linkedlistpointers
*/
structtty_driver*next;
structtty_driver*prev;
};
structtermios
termbits.h
structtermios{
tcflag_tc_iflag;/*输入模式标志inputmodeflags*/
tcflag_tc_oflag;/*输出模式标志outputmodeflags*/
tcflag_tc_cflag;/*控制模式标志controlmodeflags*/
tcflag_tc_lflag;/*局部模式标志localmodeflags*/
cc_tc_line;/*行的控制linediscipline*/
typedefunsignedcharcc_t;
cc_tc_cc[NCCS];/*控制字符controlcharacters*/
};
每个终端设备都有这样一个结构,包含在这一结构中的标志集合控制终端接口的各种特征。
访问和修改termios结构内容的主要函数。
Inttcgetattr(intfd,structtermios*tptr);
Inttcsetattr(intfd,intactionm,structtermios*tptr);
termios->c_cc数组中中存放了两个使用在非规范模式的参数。
c_cc[VMIN]规定了Read调用读出的最少字符数,c_cc[VTIME]设置了这些调用的时间极限。
TIME=0
TIME>0
MIN=0
从0到n个字节,无论可得到多少都立即返回。
立即启动定时器,如果有输入返回第一个字节,或者由于超时返回0个字节
MIN>0
至少返回MIN个字节,最多返回N个字节,可能无限封锁。
输入第一个字节后启动输入字节定时器,超时时如果输入3N个字节就返回N个字节,超时时至少返回一个字节,可能无限封锁
structtty_ldisc
ttylinediscipline
tty_ldisc.h
structtty_ldisc{
intmagic;
intnum;
intflags;
/*
*Thefollowingroutinesarecalledfromabove.
*/
int(*open)(structtty_struct*);
void(*close)(structtty_struct*);
void(*flush_buffer)(structtty_struct*tty);
int(*chars_in_buffer)(structtty_struct*tty);
int(*read)(structtty_struct*tty,structfile*file,
unsignedchar*buf,unsignedintnr);
int(*write)(structtty_struct*tty,structfile*file,
constunsignedchar*buf,unsignedintnr);
int(*ioctl)(structtty_struct*tty,structfile*file,
unsignedintcmd,unsignedlongarg);
void(*set_termios)(structtty_struct*tty,structtermios*old);
int(*select)(structtty_struct*tty,structinode*inode,
structfile*file,intsel_type,
structselect_table_struct*wait);
/*
*Thefollowingroutinesarecalledfrombelow.
*/
void(*receive_buf)(structtty_struct*,constunsignedchar*cp,
char*fp,intcount);
int(*receive_room)(structtty_struct*);
void(*write_wakeup)(structtty_struct*);
};
structtask_struct
sched.c
structtask_struct{
/*thesearehardcoded-don'ttouch*/
volatilelongstate;/*-1unrunnable,0runnable,>0stopped*/
longcounter;
longpriority;
unsignedlongsignal;
unsignedlongblocked;/*bitmapofmaskedsignals*/
unsignedlongflags;/*perprocessflags,definedbelow*/
interrno;
longdebugreg[8];/*Hardwaredebuggingregisters*/
structexec_domain*exec_domain;
/*variousfields*/
structlinux_binfmt*binfmt;
structtask_struct*next_task,*prev_task;
structtask_struct*next_run,*prev_run;
unsignedlongsaved_kernel_stack;
unsignedlongkernel_stack_page;
intexit_code,exit_signal;
/*?
?
?
*/
unsignedlongpersonality;
intdumpable:
1;
intdid_exec:
1;
/*shouldn'tthisbepid_t?
*/
intpid;
intpgrp;
inttty_old_pgrp;
intsession;
/*booleanvalueforsessiongroupleader*/
intleader;
intgroups[NGROUPS];
/*
*pointersto(original)parentprocess,youngestchild,youngersibling,
*oldersibling,respectively.(p->fathercanbereplacedwith
*p->p_pptr->pid)
*/
structtask_struct*p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_osptr;
structwait_queue*wait_chldexit;/*forwait4()*/
unsignedshortuid,euid,suid,fsuid;
unsignedshortgid,egid,sgid,fsgid;
unsignedlongtimeout,policy,rt_priority;
unsignedlongit_real_value,it_prof_value,it_virt_value;
unsignedlongit_real_incr,it_prof_incr,it_virt_incr;
structtimer_listreal_timer;
longutime,stime,cutime,cstime,start_time;
/*mmfaultandswapinfo:
thiscanarguablybeseenaseithermm-specificorthread-specific*/
unsignedlongmin_flt,maj_flt,nswap,cmin_flt,cmaj_flt,cnswap;
intswappable:
1;
unsignedlongswap_address;
unsignedlongold_maj_flt;/*oldvalueofmaj_flt*/
unsignedlongdec_flt;/*pagefaultcountofthelasttime*/
unsignedlongswap_cnt;/*numberofpagestoswaponnextpass*/
/*limits*/
structrlimitrlim[RLIM_NLIMITS];
unsignedshortused_math;
charcomm[16];
/*filesysteminfo*/
intlink_count;
structtty_struct*tty;/*NULLifnotty*/
/*ipcstuff*/
structsem_undo*semundo;
structsem_queue*semsleeping;
/*ldtforthistask-usedbyWine.IfNULL,default_ldtisused*/
structdesc_struct*ldt;
/*tssforthistask*/
structthread_structtss;
/*filesysteminformation*/
structfs_struct*fs;
/*openfileinformation*/
structfiles_struct*files;
/*memorymanagementinfo*/
structmm_struct*mm;
/*signalhandlers*/
structsignal_struct*sig;
#ifdef__SMP__
intprocessor;
intlast_processor;
intlock_depth;/*Lockdepth.Wecancontextswitchinandoutofholdingasyscallkernellock...*/
#endif
};
structwait_queue
wait.h
structwait_queue{
structtask_struct*task;
structwait_queue*next;
};
等待着的进程的队列。
structwinsize
terios.h
structwinsize{
unsignedshortws_row;
unsignedshortws_col;
unsignedshortws_xpixel;
unsignedshortws_ypixel;
};
structpty_struct
pty.c
structpty_struct{
intmagic;
structwait_queue*open_wait;
};
magic号加上等待队列
structkbd_struct
kbd_kern.h
structkbd_struct{
unsignedcharlockstate;
/*8modifiers-thenamesdonothaveanymeaningatall;
theycanbeassociatedtoarbitrarilychosenkeys*/
#defineVC_SHIFTLOCKKG_SHIFT/*shiftlockmode*/
#defineVC_ALTGRLOCKKG_ALTGR/*altgrlockmode*/
#defineVC_CTRLLOCKKG_CTRL/*controllockmode*/
#defineVC_ALTLOCKKG_ALT/*altlockmode*/
#defineVC_SHIFTLLOCKKG_SHIFTL/*shiftllockmode*/
#defineVC_SHIFTRLOCKKG_SHIFTR/*shiftrlockmode*/
#defineVC_CTRLLLOCKK