首页 > QEMU > 如何使用 QEMU 中的虚拟串口

如何使用 QEMU 中的虚拟串口

QEMU 具有模拟 串口并口 的能力, 在 QEMU 的命令行接口, 提供了 -serial 参数供用户设置把虚拟的串口重定向到哪里.

本文档主要介绍如何使用这个虚拟串口, 接下来会从代码方面描述 QEMU 如何模拟 一个串口.

不使用串口

$ qemu-kvm ArchLinux.img -serial none

不管是 Linxu 还是 Window, 在 QEMU 里面禁用了串口, 但是用一些硬件检测 工具还是能检测到串口的存在. 用一段简单的代码来检测是否串口可以使用

#!/usr/bin/python
import serial
try:
    s = serial.Serial('/dev/ttyS0')
    print "Find serial port on /dev/ttyS0"
except:
    print "Cant found serial port on /dev/ttyS0"

重定向到虚拟控制台

$ qemu-kvm ArchLinux.img -serial vc:800x600 # 或者 vc:80Cx24C

实际上, 默认 启动 QEMU 的时候如果不加参数的话, 会自动创建四个控制台, 分别用 Ctrl + Alt + number 来切换, number 为 1, 2 或 3, 4 其中 1 是 QEMU 的图形终端, 2 是 QEMU 的 Monitor 终端(QEMU 的 Monitor 稍候会介绍), 3 是 Serial 终端, 4 是并口终端.

重定向到一个伪终端

$ qemu-kvm ArchLinux.img -serial pty

然后会发生什么呢? QEMU 会自动创建一个伪终端设备(/dev/pts/3) 之类的, 然后 用 screen 之类的工具就可以操纵这个终端了.

PS. 这东西 Linux only 哟

重定向到 null

$ qemu-kvm ArchLinux.img -serial null

这和重定向到 none 有什么区别呢? 区别就是 -> none QEMU 不会虚拟串口设备, 但是 -> null 会虚拟一个串口设备, 丢弃所有的输出: 如以下的代码. 至于输入? 需要输入吗?

static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    return len;
}

重定向要真实串口设备

$ qemu-kvm ArchLinux.img -serial /dev/ttyS0

但是虚拟串口的硬件参数需要和真实串口符合

PS. Linux only 哟

重定向到并口

$ qemu-kvm ArchLinux.img -serial /dev/parportN

重定向到第 N 个并口

PS. Linux only 哟

重定向到一个文件

$ qemu-kvm ArchLinux.img -serial file:/tmp/serial.out

不过从打开文件的方式看来, QEMU 只是把串口的输出写入文件, 而并不支持串口的 输入.

TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),
                       O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));

重定向到 stdio

$ qemu-kvm ArchLinux.img -serial stdio

把串口重定向到标准输入输出, 这给调试 Guest OS(其实我说的是 Linux OS, 你要调试 Window OS? 你吃饱了撑的?)提供了方便.

重定向到管道

$ qemu-kvm ArchLinux.img -serial pipe:/tmp/serial:

不过这玩意还比上面的复杂, 根据 QEMU 打开这类设备的代码, 需要手动创建 /tmp/serial.in 和 /tmp/serial.out 两个管道文件

snprintf(filename_in, 256, "%s.in", filename);
snprintf(filename_out, 256, "%s.out", filename);
TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
$ mkdir fifo /tmp/serial.in
$ mkdir fifo /tmp/serial.out

怎么使用呢? cat /tmp/serial.out 会看到 Linux 登录的一堆信息, 最后停在 virt-debian login: 这里等待输入, 用

$ echo your_username >> /tmp/serial.in
$ echo your_password >> /tmp/serial.in

再打开 cat /tmp/serial.p.out 就可以看到内容已经变成 root@virt-debian:~# 这样的东西了.

所以这玩意对我用处不大

重定向到 udp 端口

$ qemu-kvm ArchLinux.img -serial udp::3333

将 QEMU 的串口重定向到 3333 端口, 使用 nc 访问这个端口 (当然可以自己编写 socket 访问). 这对远程管理很有帮助

$ nc -u -l -p 3333

重定向到 tcp 端口

$ qemu-kvm ArchLinux.img -serial tcp::3333,server,nowait

可以使用 telnet 来访问该端口

$ telnet localhost 3333

重定向到 telnet

几乎 TCP 是一样的

$ qemu-kvm ArchLinux.img -serial telnet::3333,server,nowait

重定向到 Unix socket

$ qemu-kvm ArchLinux.img -serial unix:/tmp/serial.sock,server,nowait

用 socat 连接

$ socat  /tmp/serial.sock STDIO

同时定向到串口和 mon 控制台

$ qemu-kvm ArchLinux.img -serial mon:telnet::3333,server,nowait

这将同时定向串口到 TCP 3333 端口的同时, 可以使用 Ctrl + a 然后按 c 访问 Monitor 终端

定向到 braille

这个太强大了, 相关 google braille

msmouse

重来没有使用过

分类: QEMU 标签:
  1. Leo
    2012年9月1日10:33 | #1

    Hi 哥们,我找kvm serial 配置的时候看到您这篇文章。 我想问问您有没有试过把两个guest 用串口连接起来。 我用的方法是一个 guest 用 -serial tcp::4444,server,nowait , 一个guest 用 -serial tcp:192.168.0.1:4444 , 这样建好之后,我在一个guest 上 echo “hello” > /dev/ttyS0 , 在另一个上 cat < /dev/ttyS0 可以看到 hello,但是我用cu 连,却死活连不上, 已经在grub里面配置串口了,不知道怎么回事,您可以给看看吗?

  2. mathslinux
    2012年9月1日11:31 | #2

    @Leo
    我简单的测试了一下, 你看看是不是你想要的结果?
    我启动了两台虚拟机A和B, 其中A是linux-mint, 用minicom连接串口,
    B是debian, 在grub里我设置了串口的参数.

    A 启动之后, 用mincom打开 ttyS0, 等待 B启动, B启动之后, 你可以在
    mincom里面看到B的启动信息, 完了等待你登录, 就想标准的linux控制台
    一样.

    的启动参数(A的tcp 控制台作为server端)
    ~/usr/bin/qemu-system-x86_64 -enable-kvm ~/Images/linux-mint32-append.img -m 512 -serial tcp::4444,server,nowait

    B的启动参数(B的tcp console 主动连接A的serser, 达到通信的目的)
    ~/usr/bin/qemu-system-x86_64 -enable-kvm ~/Images/debian-append.img -m 512 -serial tcp:127.0.0.1:4444

  3. Leo
    2012年9月1日12:40 | #3

    @mathslinux
    hi, 我试了一下在Guest B用 tcp:127.0.0.1:4444 ,然后在Guest A用minicom连,但是在登录界面出现持续刷屏,不知道你有没有遇到。 然后我又试了在A 用cu 连、 在B出 cat < /dev/ttyS0, 都是一直是login那里刷屏……结果还是没法用

  4. mathslinux
    2012年9月1日15:03 | #4

    @Leo
    没有, 我可以正常的登录, 你确认你的 Guest B 的串口设置正常了, A 的minicom
    设置也正常? 我估计是设置的问题, 把hardware 校验去掉试试

  5. Leo
    2012年9月1日15:28 | #5

    现在又都不行了,重启的时候可以通过minicom看到信息,但是起来之后就什么也看不到了。也不知道哪里出的问题

  6. mathslinux
    2012年9月1日15:52 | #6

    @Leo
    基本上是你两边的串口设置的问题, 如果我没有弄错的话, 你的QEMU是
    什么版本的?

  7. Jiahuan
    2017年2月23日08:01 | #7

    你好,
    我想问一下,qemu里的串口重定向到管道,能用于windows宿主机吗?我不知道怎么在windows主机上创建qemu能用的管道。
    谢谢

  8. mathslinux
    2017年3月16日07:55 | #8

    @Jiahuan
    没有试过,管道是unix的经典概念,不知道windows有没有这个概念,如果有的话,那应该是支持的。

  1. 本文目前尚无任何 trackbacks 和 pingbacks.