Linux tty core 源码分析.docx

上传人:b****3 文档编号:10821737 上传时间:2023-05-27 格式:DOCX 页数:56 大小:42.78KB
下载 相关 举报
Linux tty core 源码分析.docx_第1页
第1页 / 共56页
Linux tty core 源码分析.docx_第2页
第2页 / 共56页
Linux tty core 源码分析.docx_第3页
第3页 / 共56页
Linux tty core 源码分析.docx_第4页
第4页 / 共56页
Linux tty core 源码分析.docx_第5页
第5页 / 共56页
Linux tty core 源码分析.docx_第6页
第6页 / 共56页
Linux tty core 源码分析.docx_第7页
第7页 / 共56页
Linux tty core 源码分析.docx_第8页
第8页 / 共56页
Linux tty core 源码分析.docx_第9页
第9页 / 共56页
Linux tty core 源码分析.docx_第10页
第10页 / 共56页
Linux tty core 源码分析.docx_第11页
第11页 / 共56页
Linux tty core 源码分析.docx_第12页
第12页 / 共56页
Linux tty core 源码分析.docx_第13页
第13页 / 共56页
Linux tty core 源码分析.docx_第14页
第14页 / 共56页
Linux tty core 源码分析.docx_第15页
第15页 / 共56页
Linux tty core 源码分析.docx_第16页
第16页 / 共56页
Linux tty core 源码分析.docx_第17页
第17页 / 共56页
Linux tty core 源码分析.docx_第18页
第18页 / 共56页
Linux tty core 源码分析.docx_第19页
第19页 / 共56页
Linux tty core 源码分析.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Linux tty core 源码分析.docx

《Linux tty core 源码分析.docx》由会员分享,可在线阅读,更多相关《Linux tty core 源码分析.docx(56页珍藏版)》请在冰点文库上搜索。

Linux tty core 源码分析.docx

Linuxttycore源码分析

Linuxttycore源码分析

[日期:

2011-02-08]

来源:

CSDN 作者:

sirzjp

本文以linux2.6.27内核为基础,阅读ttycore源码并作注解,自己接触时间不长,希望与爱好者共同分享,错误之处还望指正。

linuxttycore是建立在字符设备驱动的基础之上,并为tty类型设备(串口、控制台、虚拟终端)提供一个公用的平台。

所以任何一个tty设备驱动的注册都是作为一个字符设备驱动而操作的。

下面我们看看代码中是如何处理的:

/*3/2004jmc:

whydothesedevicesexist?

*/

//tty核心默认在内核中实现的字符型tty设备驱动

staticstructcdevtty_cdev,console_cdev;

#ifdefCONFIG_UNIX98_PTYS

staticstructcdevptmx_cdev;

#endif

#ifdefCONFIG_VT

staticstructcdevvc0_cdev;

#endif

/*

 *Ok,nowwecaninitializetherestofthettydevicesandcancount

 *onmemoryallocations,interruptsetc..

 */

staticint__inittty_init(void)

{

//在字符设备模型中加入注册tty_cdev驱动并加入/dev/tty这样的设备

 cdev_init(&tty_cdev,&tty_fops);

 if(cdev_add(&tty_cdev,MKDEV(TTYAUX_MAJOR,0),1)||

    register_chrdev_region(MKDEV(TTYAUX_MAJOR,0),1,"/dev/tty")<0)

 panic("Couldn'tregister/dev/ttydriver\n");

 device_create_drvdata(tty_class,NULL,MKDEV(TTYAUX_MAJOR,0),NULL,

        "tty");

//在字符设备模型中加入注册console_cdev驱动并加入/dev/console这样的设备

 cdev_init(&console_cdev,&console_fops);

 if(cdev_add(&console_cdev,MKDEV(TTYAUX_MAJOR,1),1)||

    register_chrdev_region(MKDEV(TTYAUX_MAJOR,1),1,"/dev/console")<0)

 panic("Couldn'tregister/dev/consoledriver\n");

 device_create_drvdata(tty_class,NULL,MKDEV(TTYAUX_MAJOR,1),NULL,

        "console");

//在字符设备模型中加入注册ptmx_cdev驱动并加入/dev/ptmx这样的设备

#ifdefCONFIG_UNIX98_PTYS

 cdev_init(&ptmx_cdev,&ptmx_fops);

 if(cdev_add(&ptmx_cdev,MKDEV(TTYAUX_MAJOR,2),1)||

    register_chrdev_region(MKDEV(TTYAUX_MAJOR,2),1,"/dev/ptmx")<0)

 panic("Couldn'tregister/dev/ptmxdriver\n");

 device_create_drvdata(tty_class,NULL,MKDEV(TTYAUX_MAJOR,2),NULL,"ptmx");

#endif

//在字符设备模型中加入注册vc0_cdev驱动并加入/dev/tty0这样的设备

#ifdefCONFIG_VT

 cdev_init(&vc0_cdev,&console_fops);

 if(cdev_add(&vc0_cdev,MKDEV(TTY_MAJOR,0),1)||

    register_chrdev_region(MKDEV(TTY_MAJOR,0),1,"/dev/vc/0")<0)

 panic("Couldn'tregister/dev/tty0driver\n");

 device_create_drvdata(tty_class,NULL,MKDEV(TTY_MAJOR,0),NULL,"tty0");

 vty_init();//这里暂时不做解释

#endif

 return0;

}

//上面是本身加入的,也就是我们系统一般都有的设备,而且这几种设备都是指向其他的设备,在tty_open中我们将看到以后都会指向其

//他具体的设备。

对这几种设备大多数人都存在一定的混淆,这里我就自己的理解解释下:

///dev/console(5,1)表示系统的控制台

///dev/tty(5,0)表示进程的控制终端

///dev/tty0(4,0)表示当前使用的虚拟终端

//这样的解释也不是很清楚,这得从历史说起,以前计算机还是比较昂贵的时候,一台电脑上一般接有很多键盘与显示器的组合设备用以

//操作计算机这样的组合设备就是所谓的终端,而还存在一种直接和电脑连接键盘和显示器这就是控制台。

而现在的应用环境发生了变化,

//一般把能直接显示系统信息的终端称呼为系统控制台,而其他设备则称呼虚拟终端。

也就是当前虚拟终端作控制台。

staticconststructfile_operationstty_fops={

 .llseek =no_llseek,

 .read =tty_read,

 .write =tty_write,

 .poll =tty_poll,

 .unlocked_ioctl=tty_ioctl,

 .compat_ioctl=tty_compat_ioctl,

 .open =tty_open,

 .release=tty_release,

 .fasync =tty_fasync,

};

#ifdefCONFIG_UNIX98_PTYS

staticconststructfile_operationsptmx_fops={

 .llseek =no_llseek,

 .read =tty_read,

 .write =tty_write,

 .poll =tty_poll,

 .unlocked_ioctl=tty_ioctl,

 .compat_ioctl=tty_compat_ioctl,

 .open =ptmx_open,

 .release=tty_release,

 .fasync =tty_fasync,

};

#endif

staticconststructfile_operationsconsole_fops={

 .llseek =no_llseek,

 .read =tty_read,

 .write =redirected_tty_write,

 .poll =tty_poll,

 .unlocked_ioctl=tty_ioctl,

 .compat_ioctl=tty_compat_ioctl,

 .open =tty_open,

 .release=tty_release,

 .fasync =tty_fasync,

};

//从上面看几个驱动的操作函数大致相同,只有ptmx_fops的open方法和console_fops的write方法不同其他操作都是相同的所以在其

//他操作上要兼顾各种设备

//下面我们介绍下tty_driver结构和tty_struct结构。

tty_driver表示一个具体的tty设备的驱动程序,而tty_struct表示tty设备在

//具体的分析中介绍其成员。

structtty_driver{

 intmagic; /*magicnumberforthisstructure*/

 structkrefkref;/*Referencemanagement*/

 structcdevcdev;//可见tty设备驱动是一个字符设备设备驱动

 structmodule*owner;

 constchar*driver_name;//这里是指驱动程序的名字

 constchar*name;//tty设备的命名相关

 intname_base;/*offsetofprintedname*/

 intmajor; /*majordevicenumber*/

 intminor_start;/*startofminordevicenumber*/

 intminor_num;/*numberof*possible*devices*/

 intnum; /*numberofdevicesallocated*/

 shorttype; /*typeofttydriver*/

 shortsubtype;/*subtypeofttydriver*/

 structktermiosinit_termios;/*Initialtermios*/

 intflags; /*ttydriverflags*/

 structproc_dir_entry*proc_entry;/*/procfsentry*/

 structtty_driver*other;/*onlyusedforthePTYdriver*/

 /*

 *Pointertothettydatastructures

 */

 structtty_struct**ttys;//驱动操作的具体tty设备

 structktermios**termios;

 structktermios**termios_locked;

 void*driver_state;

 /*

 *Drivermethods

 */

 conststructtty_operations*ops;

 structlist_headtty_drivers;//用于链接tty驱动全局链表

};

//下面对tty_open函数进行分析,open函数的具体操作就是初始化tty_struct结构并作为赋值filp->private_data,为后续的操作做准备

/**

 *tty_open -openattydevice

 *@inode:

inodeofdevicefile

 *@filp:

filepointertotty

 *

 *tty_openandtty_releasekeepupthettycountthatcontainsthe

 *numberofopensdoneonatty.Wecannotusetheinode-count,as

 *differentinodesmightpointtothesametty.

 *

 *Open-countingisneededforptymasters,aswellasforkeeping

 *trackofseriallines:

DTRisdroppedwhenthelastclosehappens.

 *(Thisisnotdonesolelythroughtty->count,now. -Ted1/27/92)

 *

 *Thetermiosstateofaptyisresetonfirstopensothat

 *settingsdon'tpersistacrossreuse.

 *

 *Locking:

tty_mutexprotectstty,get_tty_driverandinit_devwork.

 *  tty->countshouldprotecttherest.

 *  ->siglockprotects->signal/->sighand

 */

staticint__tty_open(structinode*inode,structfile*filp)

{

 structtty_struct*tty;

 intnoctty,retval;

 structtty_driver*driver;

 intindex;

 dev_tdevice=inode->i_rdev;//得到设备的设备号

 unsignedshortsaved_flags=filp->f_flags;

 nonseekable_open(inode,filp);//主要是设置file->f_mode的一些标志使文件不可定位

retry_open:

 noctty=filp->f_flags&O_NOCTTY;//是否终端绑定到指定的进程

 index =-1;

 retval=0;

 mutex_lock(&tty_mutex);

//这里表示的是设备号为(5,0)及/dev/tty是进程控制终端的别名,因此是一个要找到真正的设备

 if(device==MKDEV(TTYAUX_MAJOR,0)){   

 tty=get_current_tty();

 if(!

tty){//进程没有控制终端则直接返回

  mutex_unlock(&tty_mutex);

  return-ENXIO;

 }

 driver=tty->driver;

 index=tty->index;//设备在驱动中的driver->ttys中的位置

 filp->f_flags|=O_NONBLOCK;/*Don'tlet/dev/ttyblock*/

 /*noctty=1;*/

 gotogot_driver;

 }

#ifdefCONFIG_VT

//这里表示的是设备号为(4,0)及/dev/tty0是当前进程使用虚拟终端的别名,因此是一个要找到真正的设备

 if(device==MKDEV(TTY_MAJOR,0)){

 externstructtty_driver*console_driver;//控制台的驱动

 driver=console_driver;

 index=fg_console;//表示当前控制台索引

 noctty=1;

 gotogot_driver;

 }

#endif

//这里表示的是设备号为(5,1)及/dev/console是指系统控制台,因此是一个要找到真正的设备

 if(device==MKDEV(TTYAUX_MAJOR,1)){

 driver=console_device(&index);

 if(driver){

  /*Don'tlet/dev/consoleblock*/

  filp->f_flags|=O_NONBLOCK;

  noctty=1;

  gotogot_driver;

 }

 mutex_unlock(&tty_mutex);

 return-ENODEV;

 }

//依据设备的设备号来确定设备在具体驱动中的索引。

 driver=get_tty_driver(device,&index);

 if(!

driver){

 mutex_unlock(&tty_mutex);

 return-ENODEV;

 }

/*到此位置我们的目的是确定设备驱动和设备在驱动中的位置以及设备是否和进程绑定*/

got_driver:

//init_dev初始化一个tty_struct结构具体在下面分析

 retval=init_dev(driver,index,&tty);

 mutex_unlock(&tty_mutex);

 if(retval)

 returnretval;

 filp->private_data=tty;//把tty_struct结构作为file->private_data这也是open函数的主要目的

 file_move(filp,&tty->tty_files);

 check_tty_count(tty,"tty_open");//统计tty设备打开的次数

 if(tty->driver->type==TTY_DRIVER_TYPE_PTY&&

    tty->driver->subtype==PTY_TYPE_MASTER)

 noctty=1;

#ifdefTTY_DEBUG_HANGUP

 printk(KERN_DEBUG"opening%s...",tty->name);

#endif

 if(!

retval){

 if(tty->ops->open)

  retval=tty->ops->open(tty,filp);//调用tty_operations中的回调函数tty驱动中我们要实现的%%%%%

 else

  retval=-ENODEV;

 }

 filp->f_flags=saved_flags;

 if(!

retval&&test_bit(TTY_EXCLUSIVE,&tty->flags)&&//设备是否为互斥设备

     !

capable(CAP_SYS_ADMIN))

 retval=-EBUSY;

 if(retval){

#ifdefTTY_DEBUG_HANGUP

 printk(KERN_DEBUG"error%dinopening%s...",retval,

        tty->name);

#endif

 release_dev(filp);//init_dev的反操作

 if(retval!

=-ERESTARTSYS)

  returnretval;

 if(signal_pending(current))

  returnretval;

 schedule();

 /*

  *Needtoresetf_opincaseahanguphappened.

  */

 if(filp->f_op==&hung_up_tty_fops)

  filp->f_op=&tty_fops;

 gotoretry_open;

 }

 mutex_lock(&tty_mutex);

 spin_lock_irq(¤t->sighand->siglock);

 if(!

noctty&&    //设备和进程绑定作为进程回话的控制终端

    current->signal->leader&&

    !

current->signal->tty&&

    tty->session==NULL)

 __proc_set_tty(current,tty);

 spin_unlock_irq(¤t->sighand->siglock);

 mutex_unlock(&tty_mutex);

 return0;

}

/*BKLpushdown:

scarycodeavoidancewrapper*/

staticinttty_open(structinode*inode,structfile*filp)

{

 intret;

 lock_kernel();

 ret=__tty_open(inode,filp);

 unlock_kernel();

 returnret;

}

/**

 *init_dev -initialiseattydevice

 *@driver:

ttydriverweareopeningadeviceon

 *@idx:

deviceindex

 *@tty:

returnedttystructure

 *

 *Prepareattydevice.Thismaynotbea"new"cleandevicebut

 *couldalsobeanactivedevice.Theptydriversrequirespecial

 *handlingbecauseofthis.

 *

 *Locking:

 * Thefunctioniscalledunderthetty_mutex,which

 *protectsusfromthettystructordriveritselfgoingaway.

 *

 *Onexitthettydevicehasthelinedisciplineattachedand

 *areferencecountof1.Ifapairwascreatedforpty/ttyuse

 *andtheotherwasaptymasterthenittoohasareferencecountof1.

 *

 *WSH06/09/97:

Rewrittentoremoveracesandproperlycleanupaftera

 *failedopen. Thenewcodeprotectstheopenwithamutex,soit's

 *reallyquitestraightforward. Themutexlockingcanprobablybe

 *relaxedforthe(mostcommon)caseofreopeningatty.

 */

staticintinit_dev(structtty_driver*driver,i

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2