作为学术课程的一部分,我们正在实现一个简单的操作系统。到目前为止,我们已经使用 QEMU 来模拟运行操作系统的 x86 处理器。现在,我们提出了一个扩展操作系统以支持多个用户的想法,最好是以支持同时使用操作系统及其多个资源的方式。
我的问题是,是否有任何方法可以运行 QEMU,例如,打开 2 个 QEMU 监视器/控制台/终端(在这种情况下不确定正确的术语(,每个监视器代表一个不同的用户,并且都使用操作系统的单个实例。 假设这两个监视器被初始化为运行我们作为 out OS 中的用户程序的不同 shell 程序实例。
到目前为止,我们看到的类似功能是在侦听某个端口进行 gdb 连接的同时运行 QEMU,我们可以通过运行 gdb 通过另一个控制台连接到该端口,从而进入调试模式。一个控制台将显示我们的操作系统输出,另一个控制台用于 gdb 命令。
有谁知道怎么能做这样的事情?谢谢!
是的,有办法。正如 Peter Cordes 所说,您需要配置一个多席位 VM。座椅是一组人机接口设备,通常包括显示器、键盘和鼠标。困难不在于硬件配置,而在于软件配置。构建多座席(物理(计算机的Linux用户圈子很小,因此软件支持稀缺且有缺陷。下面我描述了我在 VM 中运行的硬件配置。
硬件
创建具有两个席位的 VM 的示例命令行:
qemu-system-x86_64 -display gtk -enable-kvm -cpu host -monitor stdio
-nodefaults
-machine q35,accel=kvm -m 1G
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2-ovmf/x64/OVMF_CODE.fd -drive if=pflash,format=raw,file=OVMF_VARS.fd
-device virtio-blk-pci,addr=01.0,drive=root-fs -drive id=root-fs,file="$HOME/temp/qemu/ata.qcow2",if=none
-device virtio-gpu-pci,id=seat0-video,addr=08.0,xres=1024,yres=768
-device virtio-keyboard-pci,addr=09.0,display=seat0-video
-device virtio-tablet-pci,addr=0a.0,display=seat0-video
-device virtio-gpu-pci,id=seat1-video,addr=0c.0,xres=600,yres=800
-device virtio-keyboard-pci,addr=0d.0,display=seat1-video
-device virtio-tablet-pci,addr=0e.0,display=seat1-video
VM 中lspci -tv
的输出应为:
-[0000:00]-+-00.0 Intel Corporation 82G33/G31/P35/P31 Express DRAM Controller
+-01.0 Red Hat, Inc. Virtio block device
+-08.0 Red Hat, Inc. Virtio GPU
+-09.0 Red Hat, Inc. Virtio input
+-0a.0 Red Hat, Inc. Virtio input
+-0c.0 Red Hat, Inc. Virtio GPU
+-0d.0 Red Hat, Inc. Virtio input
+-0e.0 Red Hat, Inc. Virtio input
+-1f.0 Intel Corporation 82801IB (ICH9) LPC Interface Controller
+-1f.2 Intel Corporation 82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode]
-1f.3 Intel Corporation 82801I (ICH9 Family) SMBus Controller
PCI 设备08.0
、09.0
和0a.0
用于seat0
。PCI 设备0c.0
、0d.0
和0e.0
用于seat1
。tablet
实际上是一只老鼠。GPU 是座椅的主要设备。属于座席的非主设备的display
参数应为该座席主设备的标识符,以便 QEMU GUI 正确显示座席。
与具有 PCI Express 的物理计算机的拓扑相比,此硬件拓扑得到了简化。在此 VM 中,所有设备都位于同一 PCI 总线上,而具有 PCI Express 的物理计算机的每个物理设备都有一个 PCI 总线。如果此拓扑不起作用,请尝试更密切地模仿物理拓扑,如 QEMU 的"PCI Express 指南"中所述。
在显示 GPU 输出并接收鼠标和键盘事件的 QEMU GUI 窗口中,单击主菜单查看→显示选项卡。每个 GPU 都应该有一个选项卡。
需要 OVMF,因为此 VM 运行 UEFI BIOS。$HOME/temp/qemu/ata.qcow2
是一个包含 Linux 根文件系统的块设备。
乌德夫
抽象地说,您需要将设备标识符传达给实现 UI 的程序。通常的GUI程序,如Xorg服务器和Weston服务器,从udev获取这些信息。系统管理员应通过将设备的ID_SEAT
变量设置为该设备所属的席位名称来将设备连接到座席。然后,应该使用命令行选项启动UI程序,告诉程序应该在哪个座位上工作。
ID_SEAT
是一个 udevENV
变量。可以根据设备的属性进行设置,并使用udev 规则将其放置在硬件拓扑中。如果一个设备没有ID_SEAT
,则假定它属于名为seat0
的席位。
udev 守护进程在 "/etc/udev/rules.d/" 中执行规则。一个示例规则文件"/etc/udev/rules.d/97-seat.rules",它设置ID_SEAT
:
TAG=="seat", ENV{DEVPATH}=="/devices/pci0000:00/0000:00:0[cdef].0", ENV{ID_SEAT}="seat1"
TAG=="seat", ENV{DEVPATH}=="/devices/pci0000:00/0000:00:0[cdef].0/*", ENV{ID_SEAT}="seat1"
上述规则的含义是设置设备的ID_SEAT
,其DEVPATH
变量与指定的正则表达式匹配,并且其TAGS
变量包含字符串seat
。设备的DEVPATH
变量将该设备的路径存储在sys
文件系统中。规则中的星号匹配/devices/pci0000:00/0000:00:0[cdef].0
的严格后代,但与此设备本身不匹配。这就是为什么需要两条规则。命令udevadm info $DEV_PATH
显示$DEV_PATH
引用的设备ENV
变量。例如,udevadm info /sys/devices/pci0000:00/0000:00:0c.0/virtio5/drm/card1
应输出:
P: /devices/pci0000:00/0000:00:0c.0/virtio5/drm/card1
N: dri/card1
L: 0
S: dri/by-path/pci-0000:00:0c.0-card
E: DEVPATH=/devices/pci0000:00/0000:00:0c.0/virtio5/drm/card1
E: DEVNAME=/dev/dri/card1
E: DEVTYPE=drm_minor
E: MAJOR=226
E: MINOR=1
E: SUBSYSTEM=drm
E: USEC_INITIALIZED=1661999
E: ID_PATH=pci-0000:00:0c.0
E: ID_PATH_TAG=pci-0000_00_0c_0
E: ID_FOR_SEAT=drm-pci-0000_00_0c_0
E: ID_SEAT=seat1
E: DEVLINKS=/dev/dri/by-path/pci-0000:00:0c.0-card
E: TAGS=:master-of-seat:uaccess:seat:
E: CURRENT_TAGS=:master-of-seat:uaccess:seat:
显示服务器
如前所述,UI 程序应使用 seat 命令行选项启动。对于 Xorg 服务器,此选项称为-seat
。像 Xorg 服务器这样的显示服务器更经常通过显示管理器启动。我知道只有一个支持多座席的显示管理器LightDM。有迹象表明SDDM也支持多座席。LightDM 在所有席位(具有 GPU(上显示用户登录表单。不幸的是,没有办法让LightDM忽略一个座位。