`
xitong
  • 浏览: 6206938 次
文章分类
社区版块
存档分类
最新评论

再谈UNIX流机制和tty驱动

 
阅读更多

忍不住再次说一下unix的流机制。周末在家调试linux的终端驱动,发现linux并没有按照unix流机制的建议来实现tty驱动,虽然我对windows内核理解不如对linux深刻,可是还是略知一二,windows的分层驱动模型倒是和unix流机制甚是相似,如出一辙。windows借鉴了unix的很多思想,或者说英雄所见略同,而linux却是典型的实用主义者,根本不管什么架构。
linux的tty驱动基本分为三层,一层在虚拟文件系统vfs,另一层是线路规程(或者称行规程),最下面一层是设备驱动,了解了大体架构之后再看linux的具体实现,vfs层的基本就是一个file_operations,而线路规程则是一个tty_ldisc,而驱动则没有统一的表示了,驱动层和线路规程有一个接口,那就是线路规程的receive_buf函数,或者在硬件中断中,或者在软中断中,或者在工作队列中等,驱动程序调用receive_buf函数将字符放入一个队列,然后唤醒等待的睡眠进程,在receive_buf执行线路规程规定的键码的解释,最终睡眠在tty的vfs层read方法中继而睡眠在线路规程的read中的进程被唤醒,取出字符;写终端的过程也是这样,vfs的write直接调用线路规程的write,然后数据就到了驱动,每个tty都直接绑定一个tty_driver,后者有一个tty_operations,线路规程的write就是调用了该tty_driver的write...这个过程不就是最原始的unix对tty的处理机制吗?和流机制相去甚远,在流机制中,vfs层往下调用,应该对下层是什么一无所知,是线路规程还是一般的驱动程序,还是一系列的规程等等,这些都应该对vfs层完全透明,可是linux的tty驱动实现中,一切都好似硬编码的,虽然一个线路规程可以透明地堆叠在另一个线路规程上,但是vfs层下却只能是一个线路规程,和最原始的unix实现一样,unix的队列是用clist(别指望在网上得到大量信息,如果你搜索clist,结果十有八九是mfc的)实现的,该clist机制是基于单独字符的缓冲,因此取字符或者放字符只能一个一个进行,linux的队列也是这样,只是不用clist这个结构体了,unix操作clist开销要比linux的更大一些,因为操作clist结构体要比linux如今使用的单一队列更复杂。
看看unix后来的实现,特别是bsd的实现,流机制引导下的分层模型大行其道,具体参见我前面的文章《从文件系统看系统架构》。unix原始的clist实现的tty驱动和linux的一些tty设备驱动一样,都是对输入和输出的不对称处理,输入可以直接输出到驱动,而输入却涉及到了设备的中断,所以为了不使中断更延迟,原始unix和linux的某些设备驱动实现都安排了两个输入队列,中断程序首先将数据放入第一个队列,然后中断返回,而后的进程上下文或者软中断中在将这些裸数据经过线路规程后加入第二个输入队列(linux的receive_buf)。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics