对Linux内核tty设备的一点理解(转)

虽然一直作嵌入式Linux,宿主机和开发板通讯每天都在用tty设备通讯,可是其实本身对TTY设备及终端的概念认识几乎是0。对于Linux内核的终端、tty、控制台等概念的认识很模糊。因为在学习的时候碰到了重定向console的问题,因此借机学习下tty的知识。如下是我对tty的认识总结,信息来源于网络和内核文档。参考资料见文章末尾。html

tty一词源于Teletypes,或Teletypewriters,它是最先出现的一种终端设备,相似电传打字机,由Teletype公司生产。最初tty是指链接到Unix系统上的物理或者虚拟终端。终端是一种字符型设备,一般使用tty来统称各类类型的终端设备。随着时间的推移,当经过串行口可以创建起终端链接后,这个名字也用来指任何的串口设备。它还有多种类,例如串口(ttySn、ttySACn、ttyOn)、USB到串口的转换器(ttyUSBn),还有须要特殊处理才能正常工做的调制解调器(好比传统的WinModem类设备)等。tty虚拟设备支持虚拟控制台,它能经过键盘及网络链接或者经过xterm会话登陆到计算机上。node

  1.     其实起初终端和控制台都不是我的电脑的概念,而是多人共用的小型中型大型计算机上的概念。
  2.    终端为主机提供了人机接口,每一个人都经过终端使用主机的资源。终端有字符终端和图形终端两种。一台主机能够连不少终端。
  3.    控制台是一种特殊的人机接口, 是人控制主机的第一人机接口。而主机对于控制台的信任度高于其余终端。
 
     对此还能够结合内核启动代码中init进程打开/dev/console和执行两次sys_dup(0),以及标准输入、标准输出、标准出错,还有就是进程fork后的标准输入输出的复制状况来一块儿理解。
 
  1.     而我的计算机只有控制台,没有终端。固然愿意的话,能够在串口上连一两台字符哑终端。可是linux按POSIX标准把我的计算机当成小型机来用,在控制台上经过getty软件虚拟了六个字符哑终端(或者叫虚拟控制台终端tty1-tty6)(数量能够在/etc/inittab里本身调整)和一个图型终端, 在虚拟图形终端中又能够经过软件(如rxvt)再虚拟无限多个伪终端(pts/0等)。但这全是虚拟的,虽然用起来同样,但实际上没有物理实体。因此在我的计算机上,只有一个实际的控制台,没有终端,全部终端都是在控制台上用软件模拟的。要把我的计算机当主机再经过串口或网卡外连真正的物理终端也能够,论成本,谁会怎么作呢。

 

 

终端按照其自身能力分类,能够分为:linux

一、哑终端(瘦客户端)shell

早期的计算机终端是经过串行RS-232通讯的,它只能解释有限数量的控制码(CR,LF等),但没有能力处理执行特殊的转义序列功能(如清行、清屏或控制光标的位置)。简单来讲就是处理能力有限的终端机,他们通常基本上只具备和机械电传打字机相似的有限功能。这种类型的终端称为哑终端。如今仍然在现代类Unix系统上获得支持,经过设置环境变量TERM=dumb。哑终端有时用来指任何类型的经过RS-232链接的传统计算机终端,不对数据进行本地处理或本地执行用户程序的串行通讯终端。哑终端有时也指功能有限,只有单色文本处理能力或直接传输每个键入的字符而不等待主机轮询的公共计算机终端。编程

二、智能终端(胖客户端)windows

智能终端就是有能力处理转义序列,也就是说处理能力较强的终端机。网络

 

 

Linux系统的终端设备通常有如下几种:session

 

  • 一、 控制台

 

  • 系统控制台/dev/console

/dev/console是系统控制台,是与操做系统交互的设备。系统所产生的信息会发送到该设备上。平时咱们看到的PC只有一个屏幕和键盘,它其实就是控制台。目前只有在单用户模式下,才容许用户登陆控制台/dev/console。(能够在单用户模式下输入tty命令进行确认)。app

console有缓冲的概念,为内核提供打印输出。内核把要打印的内容装入缓冲区__log_buff,而后由console来决定打印到哪里(好比是tty0仍是ttySn等)。 console指向激活的终端。历史上,console指主机自己的屏幕和键盘,而tty指用电缆连接的其它位置的控制台。

某些状况下console和tty0是一致的,就是当前所使用的是虚拟终端,也是激活虚拟终端。因此有些资料中称/dev/console是到/dev/tty0的符号连接,可是这样说如今看来是不对的:根据内核文档,在2.1.71以前,/dev/console根据不一样系统设定,符号连接到/dev/tty0或者其余tty*上,在2.1.71版本以后则彻底由内核代码内部控制它的映射。 ssh

若是一个终端设备要实现console功能,必须向内核注册一个struct console结构,通常的串口驱动中都会有。若是设备要实现tty功能,必需要内核的tty子系统注册一个struct tty_driver结构,注册函数在drivers/tty/tty_io.c中。一个设备能够同时实现console和tty_driver,通常串口都这么作。

 

 

 

  • 当前控制台: /dev/tty

 

这是应用程序中的概念,若是当前进程有控制终端(Controlling Terminal),那么/dev/tty就是当前进程控制台的设备文件。对于你登陆的shell,/dev/tty就是你使用的控制台,设备号是(5,0)。不过它并不指任何物理意义上的控制台,/dev/tty会映射到当前设备(使用命令“tty”能够查看它具体对应哪一个实际物理控制台设备)。输出到/dev/tty的内容只会显示在当前工做终端上(不管是登陆在ttyn中仍是pty中)。你若是在控制台界面下(即字符界面下)那么dev/tty就是映射到dev/tty1-6之间的一个(取决于你当前的控制台号),可是若是你如今是在图形界面(Xwindows),那么你会发现如今的/dev/tty映射到的是/dev/pts的伪终端上。/dev/tty有些相似于到实际所使用终端设备的一个联接。

你能够输入命令 “tty",将显示当前映射终端如:/dev/tty1或者/dev/pts/0等。也可使用命令“ps -ax”来查看其余进程与哪一个控制终端相连。

在当前终端中输入 echo “tekkaman” > /dev/tty ,都会直接显示在当前的终端中。

 

 

  • 虚拟控制台 /dev/ttyn

 

/dev/ttyn是进程虚拟控制台,他们共享同一个真实的物理控制台。

若是在进程里打开一个这样的文件且该文件不是其余进程的控制台时,那该文件就是这个进程的控制台。进程printf数据会输出到这里。在PC上,用户可使用alt+Fn切换控制台,看起来感受存在多个屏幕,这种虚拟控制台对应tty1~n,其中 :

/dev/tty1等表明第一个虚拟控制台

例如当使用ALT+F2进行切换时,系统的虚拟控制台为/dev/tty2 ,当前控制台(/dev/tty)则指向/dev/tty2

在UNIX系统中,计算机显示器一般被称为控制台(Console)。它仿真了类型为Linux的一种终端,而且有一些设备特殊文件与之相关联:tty0、tty一、tty2等。当你在控制台上登陆时,使用的是tty1。使用Alt+[F1—F6]组合键时,咱们就能够切换到tty二、tty3等上面去。

你能够登陆到不一样的虚拟控制台上去,于是可让系统同时有几个不一样的会话存在。

而比较特殊的是/dev/tty0他表明当前虚拟控制台,是当前所使用虚拟控制台的一个别名。所以无论当前正在使用哪一个虚拟控制台(注意:这里是虚拟控制台,不包括伪终端),系统信息都会发送到/dev/tty0上。只有系统或超级用户root能够向/dev/tty0进行写操做。tty0是系统自动打开的,但不用于用户登陆。在Framebuffer设备没有启用的系统中,可使用/dev/tty0访问显卡。

 

 

  • 二、 伪终端pty(pseudo-tty)

 

        伪终端(Pseudo Terminal)是终端的发展,为知足如今需求(好比网络登录、xwindow窗口的管理)。它是成对出现的逻辑终端设备(即master和slave设备, 对master的操做会反映到slave上)。它多用于模拟终端程序,是远程登录(telnet、ssh、xterm等)后建立的控制台设备。

 

历史上,有两套伪终端软件接口:
BSD接口:较简单,master为/dev/pty[p-za-e][0-9a-f] ;slave为 /dev/tty[p-za-e][0-9a-f] ,它们都是配对的出现的。例如/dev/ptyp3和/dev/ttyp3。但因为在编程时要找到一个合适的终端须要逐个尝试,因此逐渐被放弃。
 
Unix 98接口:使用一个/dev/ptmx做为master设备,在每次打开操做时会获得一个master设备fd,并在/dev/pts/目录下获得一个slave设备(如 /dev/pts/3和/dev/ptmx),这样就避免了逐个尝试的麻烦。因为可能有好几千个用户登录,因此/dev/pts/*是动态生成的,不象其余设备文件是构建系统时就已经产生的硬盘节点(若是未使用devfs、udev、mdev等) 。第一个用户登录,设备文件为/dev/pts/0,第二个为/dev/pts/1,以此类推。它们并不与实际物理设备直接相关。如今大多数系统是经过此接口实现pty。

 

       咱们在X Window下打开的终端或使用telnet 或ssh等方式登陆Linux主机,此时均经过pty设备。例如,若是某人在网上使用telnet程序链接到你的计算机上,则telnet程序就可能会打开/dev/ptmx设备获取一个fd。此时一个getty程序就应该运行在对应的/dev/pts/*上。当telnet从远端获取了一个字符时,该字符就会经过ptmx、pts/*传递给 getty程序,而getty程序就会经过pts/*、ptmx和telnet程序往网络上返回“login:”字符串信息。这样,登陆程序与telnet程序就经过“伪终端”进行通讯。

 

  1. telnet<--->/dev/ptmx(master)<--->pts/*(slave)<--->getty

 

 

        若是一个程序把 pts/*看做是一个串行端口设备,则它对该端口的读/写操做会反映在该逻辑终端设备对的另外一个/dev/ptmx上,而/dev/ptmx则是另外一个程序用于读写操做的逻辑设备。这样,两个程序就能够经过这种逻辑设备进行互相交流,这很象是逻辑设备对之间的管道操做。对于pts/*,任何设计成使用一个串行端口设备的程序均可以使用该逻辑设备。但对于使用/dev/ptmx的程序,则须要专门设计来使用/dev/ptmx逻辑设备。

       经过使用适当的软件,就能够把两个甚至多个伪终端设备链接到同一个物理串行端口上。

 

      • 实验:
      • 一、在X下打开一个或N个终端窗口
      • 二、#ls /dev/pts/*
      • 三、关闭这个X下的终端窗口,再次运行;比较两次输出信息就明白了。
      • 输出为/dev/ptmx /dev/pts/1存在一(master)对多(slave)的状况

 

 
  • 三、 串口终端(/dev/ttySn)

 

        串行端口终端(Serial Port Terminal)是使用计算机串行端口链接的终端设备。计算机把每一个串行端口都看做是一个字符设备。有段时间串行端口设备一般被称为终端设备,那时它的最大用途就是用来链接终端,因此这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev /ttyS1)等,设备号分别是(4,0)、(4,1)等(对应于win系统下的COM一、COM2等)。若要向一个端口发送数据,能够在命令行上把标准输出重定向到这些特殊文件名上便可。

       例如,在命令行提示符下键入:echo tekkaman> /dev/ttyS1会把“tekkaman”发送到链接在ttyS1(COM2)端口的设备上。

       在2.6之后的内核中,部分三星芯片(例如S3C24x0等)将串口终端设备节点命名为ttySACn。TI的Omap系列芯片从2.6.37开始芯片自带的UART设备开始使用专有的的omap-uart驱动,故设备节点命名为ttyOn,以区别于使用8250驱动时的设备名“ttySn”。

 

  • 四、 其它类型终端

还针对不少不一样的字符设备存在有不少其它种类的终端设备特殊文件,例如针对ISDN设备的/dev/ttyIn终端设备等。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

      其实在理解以上概念的时候,若是了解终端的发展历程,就能够比较容易理解tty、终端的概念。因此请你们阅读最后推荐的wiki英文网页,有助于理解上面的概念。固然,内核文档也是必不可少的参考资料,我顺手翻译了一下。

内核文档/Documentation/devices.txt翻译节选:

 

  1. **** 终端设备
  2. Terminal, or TTY devices are a special class of character devices. A
  3. terminal device is any device that could act as a controlling terminal
  4. for a session; this includes virtual consoles, serial ports, and
  5. pseudoterminals .
  6. 终端或这TTY设备是一类特殊的字符设备。
  7. 一个终端设备是任何对于一个会话能够做为控制终端的设备。
  8. 这包括虚拟控制台、串口和伪终端(PTYs)。
  9. All terminal devices share a common set of capabilities known as line
  10. disciplines; these include the common terminal line discipline as well
  11. as SLIP and PPP modes.
  12. 全部终端设备共享一系列常规能力-线路规程。
  13. 这包含常见的终端线路规程,例如SLIP和PPP模式。
  14. All terminal devices are named similarly; this section explains the
  15. naming and use of the various types of TTYs. Note that the naming
  16. conventions include several historical warts; some of these are
  17. Linux-specific, some were inherited from other systems, and some
  18. reflect Linux outgrowing a borrowed convention.
  19. 全部终端设备的命名都比较简单。本节介绍不一样类型TTY的命名和用途。
  20. 注意命名的约定包含了一些历史需求:
  21. 某些是Linux特定的,
  22. 某些是从其余的系统中继承下来的,
  23. 还有一些则反映了Linux从借鉴来的约定中发展而来的。
  24. A hash mark (#) in a device name is used here to indicate a decimal
  25. number without leading zeroes.
  26. 设备名中的(#)标志用于标识一个不以0开头的10进制数。
  • Virtual consoles and the console device
  • 虚拟控制台和控制台设备
  1. Virtual consoles are full-screen terminal displays on the system video
  2. monitor. Virtual consoles are named /dev/tty#, with numbering
  3. starting at /dev/tty1; /dev/tty0 is the current virtual console.
  4. /dev/tty0 is the device that should be used to access the system video
  5. card on those architectures for which the frame buffer devices
  6. (/dev/fb*) are not applicable. Do not use /dev/console
  7. for this purpose.
  8. 虚拟控制台是在系统视频监视器上全屏的显示终端。
  9. 虚拟控制台设备名为/dev/tty#,编号开始于/dev/tty1。
  10. /dev/tty0是当前虚拟控制台。
  11. /dev/tty0在那些帧缓冲设备(/dev/fb*)不适用的构架下能够被用来访问系统显卡。
  12. 而/dev/console并不用于此目的。
  13. The console device, /dev/console, is the device to which system
  14. messages should be sent, and on which logins should be permitted in
  15. single-user mode. Starting with Linux 2.1.71, /dev/console is managed
  16. by the kernel; for previous versions it should be a symbolic link to
  17. either /dev/tty0, a specific virtual console such as /dev/tty1, or to
  18. a serial port primary (tty*, not cu*) device, depending on the
  19. configuration of the system.
  20. 控制台设备/dev/console是一个接受系统信息并在单用户模式下容许登陆的设备。
  21. 从Linux 2.1.71开始,/dev/console由内核管理,
  22. 而之前的版本是一个到/dev/tty0、一个特定的虚拟控制台(如/dev/tty1)或者一个串口主(tty*,非cu*)设备动态连接,这些依赖系统配置。
  • Serial ports
  • 串行端口
  1. Serial ports are RS-232 serial ports and any device which simulates
  2. one, either in hardware (such as internal modems) or in software (such
  3. as the ISDN driver.) Under Linux, each serial ports has two device
  4. names, the primary or callin device and the alternate or callout one.
  5. Each kind of device is indicated by a different letter. For any
  6. letter X, the names of the devices are /dev/ttyX# and /dev/cux#,
  7. respectively; for historical reasons, /dev/ttyS# and /dev/ttyC#
  8. correspond to /dev/cua# and /dev/cub#. In the future, it should be
  9. expected that multiple letters will be used; all letters will be upper
  10. case for the "tty" device (e.g. /dev/ttyDP#) and lower case for the
  11. "cu" device (e.g. /dev/cudp#).
  12. 串行端口是RS-232串口和任何相似的设备,不管是硬件的(如内部调制解调器)或者软件(如ISDN驱动)。
  13. 在Linux下,每一个串口有两个设备名,主要的(callin设备)和备用的(callout设备),每类设备都经过不一样的字母标识。对于任何字母X,设备名分别是/dev/ttyX# 和/dev/cux#;因为历史缘由,/dev/ttyS#和/dev/ttyC#对应于/dev/cua#和/dev/cub#。将来,对于“tty”多字母的名字将会被使用,全部的字母都将是大写(如/dev/ttyDP#),对于"cu"设备则使用小写字母(如/dev/cudp#)。
  14. The names /dev/ttyQ# and /dev/cuq# are reserved for local use.
  15. 名字(/dev/ttyQ#和/dev/cuq#)保留,用于本地使用。
  16. The alternate devices provide for kernel-based exclusion and somewhat
  17. different defaults than the primary devices. Their main purpose is to
  18. allow the use of serial ports with programs with no inherent or broken
  19. support for serial ports. Their use is deprecated, and they may be
  20. removed from a future version of Linux.
  21. 备用设备提供基于内核的exclusion和某些与主要设备不一样的默认配置。他们的主要目的是容许那些对于串口并不是内部支持或是有必定问题的程序使用串口。他们的使用已通过时,他们可能会从将来的Linux版本中删除。
  22. Arbitration of serial ports is provided by the use of lock files with
  23. the names /var/lock/LCK..ttyX#. The contents of the lock file should
  24. be the PID of the locking process as an ASCII number.
  25. 串口的仲裁是经过锁文件(/var/lock/LCK..ttyX#)来提供的。
  26. 锁文件的内容应该是锁定进程PID的ASCII码。
  27. It is common practice to install links such as /dev/modem
  28. which point to serial ports. In order to ensure proper locking in the
  29. presence of these links, it is recommended that software chase
  30. symlinks and lock all possible names; additionally, it is recommended
  31. that a lock file be installed with the corresponding alternate
  32. device. In order to avoid deadlocks, it is recommended that the locks
  33. are acquired in the following order, and released in the reverse:
  34. 安装一个例如/dev/modem的连接来指向串口是常见的作法。
  35. 为了确保适当锁定在这些环节的存在,建议软件追踪符号并锁定全部可能的名字;
  36. 此外,建议为相应的备用设备安装一个锁文件。
  37. 为了不死锁,建议按如下顺序获取锁,并按反向的顺序释放:
  38. 1. The symbolic link name, if any (/var/lock/LCK..modem)
  39. 2. The "tty" name (/var/lock/LCK..ttyS2)
  40. 3. The alternate device name (/var/lock/LCK..cua2)
  41. 一、符号连接名,若是有(/var/lock/LCK..modem)
  42. 二、“tty”名(/var/lock/LCK..ttyS2)
  43. 三、备用设备名(/var/lock/LCK..cua2)
  44. In the case of nested symbolic links, the lock files should be
  45. installed in the order the symlinks are resolved.
  46. 在符号连接嵌套的状况下,锁定文件应按照符号连接的顺序来安装以解决问题。
  47. Under no circumstances should an application hold a lock while waiting
  48. for another to be released. In addition, applications which attempt
  49. to create lock files for the corresponding alternate device names
  50. should take into account the possibility of being used on a non-serial
  51. port TTY, for which no alternate device would exist.
  52. 在任何状况下,应用程序应该等待另外一个程序释放锁后,持有这个锁。
  53. 此外,试图为相应的备用设备名建立锁文件的应用程序应考虑被用于非串口的TTY端口的可能性,此时没有备用设备存在。
  • Pseudoterminals (PTYs)
  • 伪终端(PTYs)
  1. Pseudoterminals, or PTYs, are used to create login sessions or provide
  2. other capabilities requiring a TTY line discipline (including SLIP or
  3. PPP capability) to arbitrary data-generation processes. Each PTY has
  4. a master side, named /dev/pty[p-za-e][0-9a-f], and a slave side, named
  5. /dev/tty[p-za-e][0-9a-f]. The kernel arbitrates the use of PTYs by
  6. allowing each master side to be opened only once.
  7. 伪终端(或PTYs)用于建立登陆会话或提供给其余须要tty线路规程(包括SLIP或PPP能力)能力以生成数据的进程。
  8. 每一个PTY有一个主端(/dev/pty[p-za-e][0-9a-f])和一个从端(/dev/tty[p-za-e][0-9a-f])。
  9. 内核经过只容许每一个主端仅容许打开一次来仲裁PTY的使用。
  10. Once the master side has been opened, the corresponding slave device
  11. can be used in the same manner as any TTY device. The master and
  12. slave devices are connected by the kernel, generating the equivalent
  13. of a bidirectional pipe with TTY capabilities.
  14. 一旦主端被打开,相应的从设备能够像任何TTY设备同样的方式被使用。
  15. 主从设备都和内核链接,产生至关于一个带TTY功能的双向管道。
  16. Recent versions of the Linux kernels and GNU libc contain support for
  17. the System V/Unix98 naming scheme for PTYs, which assigns a common
  18. device, /dev/ptmx, to all the masters (opening it will automatically
  19. give you a previously unassigned PTY) and a subdirectory, /dev/pts,
  20. for the slaves; the slaves are named with decimal integers (/dev/pts/#
  21. in our notation). This removes the problem of exhausting the
  22. namespace and enables the kernel to automatically create the device
  23. nodes for the slaves on demand using the "devpts" filesystem.
  24. Linux内核的最近版本和GNU库包含了对于System V和Unix98对PTY命名方式的支持。
  25. 它分配一个共用的设备(/dev/ptmx)给全部的主端(打开它会自动给你一个之前未分配的PTY)和一个子目录(/dev/pts)用于从端;从端经过十进制整数(/dev/pts/#)命名。
  26. 这消除了命名空间枯竭的问题,并使内核经过“devpts”文件系统按需自动为从端动建立设备节点。
 
对于TTY系统的理解(图解):

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

推荐阅读:《Linux C编程一站式学习》----第 34 章 终端、做业控制与守护进程---1. 终端

wiki百科关于终端的网页:Computer terminal | System console | Linux console

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

以上是我参考了网上的资料后对tty的认识整理,参考资料以下:

linux tty pty pts 概念 区别

终端 /dev/console /dev/tty tty

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

LINUX下的tty,console与串口分析

linux下tty,控制台,虚拟终端,串口,console(控制台终端)详解

LINXU下的TTY、CONSOLE、串口

Linux下的console和terminal

相关文章
相关标签/搜索