qemu提供了控制台console和串口serial用来与虚拟机进行交互通讯。Console是一个输出系统管理信息的文本输出设备,这些信息来自于内核,系统启动和系统用户,serial console就是串口作为输出终端设备,使这些信息可以通过串口在远程的终端上显示。
1、串行端口终端(/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)端口的设备上。
2、控制台终端(/dev/ttyn, /dev/console)
在Linux 系统中,计算机显示器通常被称为控制台终端(Console)。它仿真了类型为Linux的一种终端(TERM=Linux),并且有一些设备特殊文件与之相关联:tty0、tty1、tty2等。当在控制台上登录时,使用的是tty1。使用Alt+[F1—F6]组合键时,我们就可以切换到tty2、tty3等上面去。tty1–tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上(这时也叫控制台终端)。因此不管当前正在使用哪个虚拟终端,系统信息都会发送到控制台终端上。/dev/console即控制台,是与操作系统交互的设备,系统将一些信息直接输出到控制台上。目前只有在单用户模式下,才允许用户登录控制台。
3、串行和控制台的关系
历史原因,serial和console元素的作用域有部分重叠。通常这两个元素均可用于配置一个或多个serial consoles,用于与guest交互。
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
两者之间的主要区别是:
Serial用于仿真本地serial console,console利用serial口进行控制台交互;console用于半虚拟化serial console,console可独立使用的;
仿真serial console和半虚拟化serial console都有优势和劣势:
仿真serial console通常比半虚拟化serial console更早出现,它可以用来控制引导加载程序、显示固件和早期的启动信息;
每个guest只能有一个仿真serial console,但半虚拟化serial console不受限制,可以有多个。
...
<devices>
<console type='pty'>
<target type='serial'/>
</console>
<console type='pty'>
<target type='virtio'/>
</console>
</devices>
...
由此可生成一个仿真serial console,用于启动时的日志记录/交互/恢复,一个半虚拟化serial console,可作为侧信道(除标准信道之外,能够泄露信息的其他途径,比如tcp传输过程中,传输不同信息花费的时间、CPU占用率、电能消耗等,都可能会泄露传输的信息本身)。多数情况下,通常使用第一个控制台元素(也就是仿真serial console)就可以。如果特殊需要,两个元素都应该指定。
注意,如果担心之前提到的兼容性问题,可分开配置,如下,合并也可以生成简单的仿真serial console,供guest使用。
..
<devices>
<serial type='pty'/>
</devices>
...
...
<devices>
<console type='pty'/>
</devices>
...
...
<devices>
<serial type='pty'/>
<console type='pty'/>
</devices>
...
4、用法实例
配置了三个serial,和两个console,其中配置xml如下:
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<serial type='pty'>
<target type='isa-serial' port='1'>
<model name='isa-serial'/>
</target>
</serial>
<serial type='pty'>
<target type='isa-serial' port='2'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<console type='pty'>
<target type='virtio' port='1'/>
</console>
第一个串口serial0分给了console0,console0是仿真serial console;console1是虚拟化的serial console,两个可以同时登录;
在虚拟机内部
给虚拟机添加了virtio类型的console设备后,在虚拟机内部对应设备文件/dev/hvc*,给虚拟机添加了serial类型的serial设备后,在虚拟机内部对应设备文件/dev/ttyS*,登录console0和serial0:(前一次登录也是console0或者serial0,退出之后重新登录)
登录console1:(退出console1之后,第二次登录console1)
要进入虚拟机的控制台只能通过console设备,不能通过serial设备(可以通过serial0,因为serial0也是一个console设备),所以通过serial1的方式进入不了console设备:
对于serial2串口通信,虚机端发送:
主机端可接收到信息: