终端、虚拟终端和伪终端(二)

一个具有输入输出属性的设备并不特殊,tty设备的特殊在于其作为与用户交互接口这一功能。经常与终端产生联想的是串口,串口的驱动又如何与tty联系起来的呢?串口无非是具有输入输出接口,将其实现为一个普通的字符设备有何不可?为一个串口维护一个输入缓存与输出缓存,从串口中来到的数据放到输入缓存中,用户读设备文件时则从输入缓存中拿数据;用户写的数据放至输出缓存,再由驱动适时放在串口上传输。这个过程不就像对socket的处理吗?tty驱动又是有如何特殊?



所以说,tty驱动之特殊就在于其功能。它最核心的逻辑与反倒与具体输入输出无关。在标准模式下,从输入获得的数据要积累到一行才返回给用户;收到一些特殊字符要做处理(tab展开,换行符变换,退格,中断等);收到的字符有可能要马上放到输出上。tty层无非就是满足诸如此类的需求。我们可以为每个串行设备写独立的驱动,每个驱动都做这些事。而把这些代码抽出来,就莫名其妙地成为tty驱动。



其实,上面说的一些逻辑处理确实抽象出来了,但不是成了tty,而是成了line discipline。据说这部分功能本来是放在用户态实现的(Shell?),后来发现它太重要了,就把它放到内核态了。在Unix V6里面还没有line discipline的概念,上面的这一切就是tty的核心代码。后来有了line discipline,确实是很聪明的抽象,问题是把这些逻辑放到line discipline后,tty层还剩下些什么?可能只剩下一些RS232串行接口的抽象(?)。



Unix V6里的tty代码倒不好称之为层。Lions只列出一个最基本串行设备,可以想象其它设备基本类似。这个设备的驱动是独立的,它实现的就是一个字符设备,它有读方法,有写方法,看起来就像之前描述的普通字符设备一般。而需要处理的逻辑,则调用tty函数。这样看起来,与其说tty层,不如说tty库。所谓的tty设备驱动只不过是调用tty库函数的普通字符设备驱动。而这种字符设备驱动的逻辑太简单,几乎只需要直接调用tty库函数就可以完成任务,以至于tty设备驱动就像是对tty库函数的一层封装。



既然库函数是公共的,我们就需要“实例”的概念,这些公共的库函数的第一个参数便是指向这些实例的指针,每个串行设备驱动维护一个”实例“。有数据输入时,设备产生中断,驱动设下的中断处理函数调用tty_input将收到的字符放入自己维护”实例“的输入队列。用户的读请求最终路由到驱动的读函数,而这个函数的主要工作是调用tty_read让库函数去读自己维护”实例“上存有的数据源;用户的写请求最终路由到驱动的写函数,而这个函数主要工作是调用tty_write让库函数把来自用户的字符放到自己维护”实例“的输出队列,有可能会输出(输出的方法挂在”实例“上)。tty的核心逻辑则都在库函数里完成。多么清晰明白的概念与流程,如果去看Linux的代码,恐怕只会陷于无穷的细节之中。



每个设备的特殊之处,则在于自己的输入输出手段。通常以中断告之输入,驱动程序里的中断处理函数去特定的寄存器或者IO口里读到数据。输出时驱动程序检查现在是否可以输出,然后将字符放到特定寄存器或IO口中由设备输出。甚至输入输出不一定是同一个设备,现在PC机上的键盘、显卡不正是如此吗?仔细区分的话,键盘有自己的驱动程序,显卡有自己的驱动程序。而莫明的tty驱动根没有对应具体设备,只是凌驾于两种驱动程序之上,它最精华部分是设备无关的。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值