开发者社区> 技术小胖子> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

终端tty、虚拟控制台、FrameBuffer的切换过程

简介:
+关注继续查看

 一、区分/dev/tty、/dev/console、/dev/pts、/dev/ttyn /dev/ttySn   

     通常我们在linux下看到的控制台(console)是由几个设备完成的。分别是/dev/ttyN.通常使用热键 alt+Fn来在这些虚拟终端之间进行切换。所有的这些tty设备都是由linux/drivers/char/console.c和vt.c对应。

 
       控制终端 /dev/tty指的是当前所处的终端,输出到此的内容只会显示在当前工作的终端显示器上,如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty就是当前进程的控制终端的设备特殊文件。可以使用命令”ps –ax”来查看进程与哪个控制终端相连。对于你登录的shell,/dev/tty就是你使用的终端,设备号是(5,0)。使用命令”tty”可以查看它具体对应哪个实际终端设备。/dev/tty有些类似于到实际所使用终端设备的一个联接。这个终端文件可以由各个用户共享控制台终端 /dev/ttyn  n(0到6)  tty1,tty2就是不同的虚拟终端(virtual console)./dev/console 就是tty0 ,tty0则是当前所使用虚拟终端即激活的虚拟终端的一个别名,系统所产生的信息会发送到该终端上,实际上机器只有一个屏幕,也就是我们看到的这个屏幕,可以理解为console指向激活的那个tty,准确地说是激活的那个tty才将输出显示到console。历史上,console指主机本身的屏幕键盘,而tty指用电缆链接的其它位置的控制台(仅包含屏幕和键盘)。tty0是系统自动打开的,但不用于用户登录
   伪终端 /dev/pts是远程登陆(telnet,ssh等)后创建的控制台设备文件所在的目录。由于可能有好几千个用户登陆,所以/dev/pts其实是动态生成的,不象其他设备文件是构建系统时就已经产生的硬盘节点(如果未使用devfs) 。第一个用户登陆,console的设备文件为/dev/pts/0,第二个为/dev/pts/1,以此类推。这里的0、1、2、3不是具体的标准输入或输出,而是整个控制台。你可尝试 echo 
 "aaaaaa" > /dev/pts0、1、2……。
 串行端口终端(/dev/ttySn) 
串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。有段时间这些串行端口设备通常被称为终端设备,因为 那时它的最大用途就是用来连接终端。这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev 
 
/ttyS1)等,设备号分别是(4,0)、(4,1)等,分别对应于DOS系统下的COM1、COM2等。若要向一个端口发送数据,可以在命令行上把标 准输出重定向到这些
 
特殊文件名上即可。例如,在命令行提示符下键入:echo test > /dev/ttyS1会把单词”test”发送到连接在ttyS1(COM2)端口的设备上。
 
二、用ioct1函数操纵虚终端设备文件
  虚终端,也叫虚屏,它的英文名字为virtual terminal,缩写为VT或vt。在Unix系统用户中,虚终端有着广泛的应用。它解决了主控台单一交互界面的限制,使用户可在保护当前界面的情况下启用另一界面去做另一工作。我们可利用Unix系统提供的系统调用来编制虚终端程序,并可把它加入到我们的应用程序中去。本人就在此虚终端程序的基础上编写了图形软件,它能够保存和恢复先前的界面。可利用ioct1函数操纵虚终端设备文件,实现与Unix系统内核的交互,得到我们所需要的服务。使用ioct1的具体形式如下: int ioct1(int filedes,int request,…/*参数*/) 其中filedes为打开的虚终端设备文件描述符,request为请求的服务,随后的参数可为各种数据类型,视具体情况而定。与虚终端有关的用于ioct1调用中
 
request值主要有以下几个: 
VT_OPENQRY 查找一个可利用的虚终端。用于ioct1系统调用的参数是一个指向长整数的指针。该长整数的值将被置为第一个可利用的无进程在其上打开的虚终端的序号。如果没有可利用的虚终端,则该长整数的值被置为-1。VT_GETMODE 获取活动虚终端当前所在的状态。用于ioct1系统调用的参数是一个指向 vt_mode结构的指针。结构vt-mode定义如下: 
struct vt-mode { 
char mode;/* VT mode */ 
char waitv;/* if set,hang on writes when not active */ 
short relsig;/*signal to use for release request */ 
short acqsig; /*signal to use for display acquired */ 
short frsig; /*not use set to 0 */ 
在结构vt_mode中,mode字段的值可为VT_AUTO和VT_PROCESS,它们的宏定义如下: 
#define VT_AUTO 0x00 /*自动切换*/ 
#define VT_PROCESS 0x01 /*进程控制切换*/ 
VT_SETMODE 设置虚终端模式(自动或进程控制)。用于ioctl系统调用的参数是一个″vt_mode″结构的指针(结构定义见VT_GETMODE)。 
VT_GETSTATE 获取全部虚终端的状态信息。用于ioctl的系统调用的参数是一个指向vt_stat结构的指针,该结构定义如下: 
struct vt_stat { 
ushort v_active;/*活动的vt*/ 
ushort v_signal;/*要发送的信号(用于VT_SENDSIG)*/ 
ushort v_state; /*vt位掩码(VT_SENDSIG和VT_GETSTATE)*/ 
该调用在v_active字段返回活动虚终端号,在v_state字段中可获得全部虚终端状态的位掩码(v_state的位x是虚终端x的状态,该位为1说明对应的虚终端是打开状态,否则为可利用状态)。VT_SENDSIG 指定要发送给虚终端(在v_state中)的位屏蔽的信号(在v_signa1中)。用于ioct1的系统调用的参数是一个指向vt_stat结构的指针(结构定义见前面VT_GETSTATE)。 VT_RELDISP 用于告诉虚终端管理器进程是否已经释放了显示。一个零值指示拒绝释放显示。 VT_ACTIVATE 使在参数中指定的虚终端号为活动虚终端。″VT″管理器将产生一个切换,如同在键盘上按组合热键一样。如果指定的虚终端不处于打开状态或者不存在,调用将失败,并置errno的值为ENXI0。 VT_WAITACTIVE 等待虚终端被激活,不需要参数。
 
有了上面的介绍,现在我们就可以实现虚终端了: 
1?查找是否有可利用的虚终端,如没有,则结束。 
2?打开可利用虚终端设备文件,以便进行。 
3?利用ioct1的TCSETSW功能设置虚终端参数,其作用同Unix的stty命令一样。 
4?利用ioct1的VT_ACTIVATE功能激活虚终端,并利用VT_WAITACTIVE功能等待其可用。 
5?用putenv函数设置环境变量。 
至此,一个虚终端程序就实现了(当然,是利用Unix系统提供的功能,但它与Unix提供的newvt命令的实现并无区别)。在这个虚终端里,我们可方便地实现我们自己想要的功能,而不必担心会破坏原来的环境。
 
三 、虚拟控制台的切换过程
1. 1) 虚拟终端的切换在控制台软中断中运行,当按"ALT F1" 时,键盘中断设置变量want_console 为0,然后激发控制台软中断(console_softint),如果请求的控制台存在并且不等于当前控制台,这时调用change_console(want_console)切换控制台。 
2) 当前控制台就是直接操作物理屏幕的控制台,用fg_console变量指示。控制台的切换就是物理屏幕在虚拟控制台之间的切换,与CPU在进程之间的切换有些类似,当前物理显示屏的内容被保存在当前控制台的局部屏幕缓冲区之中,新控制台成为当前控制台,新当前控制台的局部屏幕被恢复到物理屏幕。当输出到背景控制台时, 文本被缓冲在该控制台的局部屏幕缓冲区中。 
3) 当应用程序在某个虚拟控制台中使显示设备处于图形状态时,内核无法正常切换到另一文本控制台,这时可以用KDSETMODE ioctl将控制台设置为KD_GRAPHICS状态,这样可防止控制台输出和切换操作。为了在图形状态下也能切换控制台,可以采用进程屏幕切换机制(VT_PROCESS)。当某个控制台被某个进程设置为VT_PROCESS模式时,当离开该控制台时, 内核向该进程生成"释放"信号(relsig),当进入该控制台时,内核向该进程发送"获得"信号(acqsig)。该信息由vt_mode结构描述,用VT_SETMODE ioctl设置。 
4) 对于X窗口来说,X服务器启动时切换到第一个未分配的控制台来使用显示器,当离开该控制台时,内核在X服务器中产生信号,X服务器将显示器恢复为文本状态,然后向内核发出"显示器已释放"(VT_RELDISP)设备控制消息,内核再接着将显示器切换到新的控制台。反之,当从文本控制台进入X窗口的图形控制台时,内核保存当前文本控制台的屏幕现场后向X服务器发出信号,X服务器再将屏幕恢复到图形状态。
 
四、基本的读写FrameBuffer的步骤:
1 打开framebuffer设备;
2 通过ioctl取得fixed screen information;
3 通过ioctl取得variable screen information;
4 通过mmap映射设备内存到进程空间;
5 写framebuffer;
6 关闭framebuffer设备;
 
 
/dev/tty的妙用标准的输入输出往往不能够输入到/dev/tty文件中。而是需要通过重定向功能,把一些命令的输出重定向到这个文件中。另外需要说明的是,普通终端的话往往是每个用户之间相互独立的。也就是说,每个用户的输出彼此之间是互不干涉的。但是/det/tty这个文件由其特殊性。这个终端文件可以由各个用户共享。
1. 利用这个文件来屏蔽不需要的结果信息。 
         系统工程师可以轻松的通过/dev/tty文件来过滤这些无用的提示信息。如只需要把脚本程序的运行结果通过重定向服务重定向到/dev/tty文件中。在这个重定向的过程中,Unix系统的shell会采取一定的内部处理机制,会忽略掉echo等命令。也就是说,只要把命令的标准输出重定向到这个文件中,则利用echo命令设置的一些提示信息都会被忽略掉。此时在这个文件中,存储的只有一些必要的运行信息,如错误或者警告信息等等。
2. 当作其他命令的参数。
      系统工程师即希望把命令的结果输出到终端中,同时保存到一个文件中,就需要利用tee命令,如who | tee userinfo.txt。(注意,如果利用了tee命令的话,在可以不再使用重定向符号)。到这里为止没有涉及到/dev/tty这个文件。who | tee userinfo.txt这个命令的显示结果,只会显示当前登录的用户明细,而不会显示当前有多少个用户登录到系统中。如果其他脚本程序需要用到当前登录用户的总数而不需要明细,那么该如何处理呢?此时就需要利用/dev/tty文件作为参数了。如可以使用who | tee /dev/tty |wc –l 命令。这个命令可以把当前用户的明细以及总共的用户数量显示出来。以上这个命令其实我们可以分为四个步骤。第一步系统先执行who命令;第二步tee命令把who命令执行对结果保存到/dev/tty文件中;第三步wc命令会统计/dev/tty文件中的行数。由于一个终端对相当于一个文件,故利用wc命令可以统计出当前系统登录用户的数量。第四步再把这个统计的结果显示在终端上。所以说,把/dev/tty文件当作其他命令的一个参数,一个一起组合以实现一些比较复杂的功能。
   需要注意的是命令 >/dev/tty与命令> file连个命令其最终的结果有可能相同,也有可能不同。前者在把命令的显示结果保存到/dev/tty文件中的时候,会过滤掉echo等命令设置的信息。而后者这个命令这会把显示的结果一五一十的照搬到file文件中去。也就是说,如果在命令或者脚本程序中没有echo等类似的命令设置信息的话在,则这两个命令重定向文件后所保存文件的内容是一致的。但是如果在命令或者脚本程序中有类似的提示命令的话,则两个文件的显示结果则会不同。为此系统工程师就需要根据自己的实际需要,来选择合适的重定向文件,看看有否必要采用/dev/tty文件

 





     本文转自 驿落黄昏 51CTO博客,原文链接:http://blog.51cto.com/yiluohuanghun/1064151,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
win7-vs2012下安装.net frame work 的过程图文详解
win7-vs2012下安装.net frame work 的过程图文详解
81 0
【Unity3D 灵巧小知识点】 ☀️ | 使用代码控制 Image图片层级渲染 顺序
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、r美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。
78 0
好程序员web前端技术之CSS3过渡
好程序员web前端技术之CSS3过渡,css3的transition允许css的属性值在一定的时间区间内平滑地过渡。这种效果可以在鼠标单击、获得焦点、被点击或对元素任何改变中触发,并圆滑地以动画效果改变CSS的属性值 transition-property:检索或设置对象中的参与过渡的属性tran...
856 0
在Xamarin.Forms企业应用程序中进行验证
我们在五月份发布了一本《使用Xamarin.Forms的企业应用程序模式》的电子书。电子书专注于开发Xamarin.Forms更容易测试,维护和发展的企业应用程序的核心模式和架构指导。
995 0
【Web API系列教程】3.2 — 实战:处理数据(添加模型和控制器)
前言 在本部分中,你将添加用于定义数据库实体的模型类。然后你将添加用于在这些实体上执行CRUD(Create、Retrieve、Update、Delete——译者注)操作的Web API 控制器。
940 0
《BREW进阶与精通——3G移动增值业务的运营、定制与开发》连载之77——BREW中位置信息的获得(LBS应用)
版权声明:本文为半吊子子全栈工匠(wireless_com,同公众号)原创文章,未经允许不得转载。
500 0
21114
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载