Reputation: 21
as part of an academic course we're implementing a simple OS. We've used QEMU so far to simulate an x86 processor to run our OS on. Now, we've come up with an idea to extend our OS to support multiple users, preferably in such a way that would support simultaneous use of the OS and several of its resources.
My question is if there's any way we could run QEMU in a way that would, for example, open 2 QEMU monitors/consoles/terminals (not sure about the correct term in this case), each representing a different user, and both use a single instance of the OS. Say these two monitors are initialized to run a distinct instance of shell program that we have as a user program in out OS.
A similar ability we've seen so far was to run QEMU while listening on some port for gdb connection, which we're able to connect to through another console by running gdb, thus entering debugging mode. One console would display our OS output, and the other is used for gdb commands.
Has anyone got any idea how can such a thing be done? Thanks!
Upvotes: 2
Views: 1177
Reputation: 397
Yes, there is a way. As Peter Cordes said, you need to configure a multi-seat VM. A seat is a set of human interface devices which commonly includes a monitor, a keyboard, and a mouse. The difficulty isn't as much in hardware configuration as in software configuration. The circle of Linux users building multi-seat (physical) computers is small, so software support is scarce and buggy. Below I described a hardware configuration which I run in a VM.
An example command line creating a VM with two seats:
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
The output of lspci -tv
in the VM should be:
-[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 devices 08.0
, 09.0
, and 0a.0
are intended for seat0
. PCI devices 0c.0
, 0d.0
, and 0e.0
are intended for seat1
. tablet
is actually a mouse. A GPU is the main device of a seat. The display
parameter of a non-main device belonging to a seat should be the identifier of the main device of that seat so QEMU GUI shows seats properly.
This hardware topology is simplified comparing to topologies of physical computers with PCI Express. In this VM, all devices are on the same PCI bus, while a physical computer with PCI Express have a PCI bus for every physical device. If this topology doesn't work, try to imitate physical topology more closely as described in “PCI EXPRESS GUIDELINES” of QEMU.
In the QEMU GUI window that shows GPU output and receives mouse and keyboard events, click on the main menu View → Show Tabs. There should be a tab for every GPU.
OVMF is needed because this VM runs a UEFI BIOS. $HOME/temp/qemu/ata.qcow2
is a block device containing a root file system of Linux.
Abstractly, you need to communicate device identifiers to programs implementing UI. Usual GUI programs like the Xorg server and the Weston server get this information from udev. A sysadmin should attach devices to seats by setting the ID_SEAT
variable of a device to the name of the seat this device belongs to. Then UI programs should be started with a command line option telling which seat the program should work on.
ID_SEAT
is a udev ENV
variable. It can be set depending on the device's properties and place in the hardware topology with udev rules. If a device has no ID_SEAT
, it's assumed to belong to the seat called seat0
.
The udev daemon executes rules in “/etc/udev/rules.d/”. An example rules file “/etc/udev/rules.d/97-seat.rules” which sets 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"
The meaning of a rule above is to set ID_SEAT
of a device whose DEVPATH
variable matches the specified regular expression and whose TAGS
variable contains the string seat
. The DEVPATH
variable of a device stores the path to that device in the sys
file system. The asterisk in the rule matches strict descendants of /devices/pci0000:00/0000:00:0[cdef].0
, but doesn't match this device itself. This is why two rules are needed. The command udevadm info $DEV_PATH
shows ENV
variables of the device referred by $DEV_PATH
. For example, udevadm info /sys/devices/pci0000:00/0000:00:0c.0/virtio5/drm/card1
should output:
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:
As was said, UI programs should be started with a seat command line option. For the Xorg server, this option is called -seat
. Display servers like the Xorg server are more often started via a display manager. I know only one display manager that supports multi-seat, LightDM. There is an indication that SDDM supports multi-seat too. LightDM presents user login forms on all seats (that have a GPU). Unfortunately, there is no way to make LightDM to ignore a seat.
Upvotes: 1