summaryrefslogtreecommitdiff
path: root/source/qemu.rst
blob: 8b64cb22e6752ffeec60a996e0169b473f652567 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
####
QEMU
####

Basic VM command
================

.. code-block:: bash

   #!/bin/sh
   exec qemu-system-x86_64 \
       -machine type=q35,accel=kvm \
       -enable-kvm \
       -cpu host \
       -smp cores=6,threads=2,sockets=1 \
       -m 8G \
       -drive file=ubuntu.qcow2,format=qcow2 \
       -netdev user,id=mynet0 \
       -device e1000,netdev=mynet0 \
       -device qemu-xhci,id=xhci \
       -device usb-tablet,bus=xhci.0 \
       -usb \
       -device usb-ehci,id=ehci \
       -device usb-host,bus=usb-bus.0,hostbus=1,hostport=1 \
       -device intel-hda \
       -device hda-duplex \
       -name Ubuntu \
       -boot d \
       -monitor stdio \
       -display none \
       "$@"

.. admonition:: TODO

   Describe the command and split it apart into sepatate sections.

TCP port forwarding
==========================================================

If you want to forward an SSH port use the following options::

  -net user,hostfwd=tcp::2222-:22 \

If you need to forward multiple TCP ports, add another ``hostfwd`` entry after a
comma like this::

  -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::51822-:51822 \

Exchange files with the host using samba [#shared-folder]_
==========================================================

When running QEMU, add the following options to the ``qemu-system-x86_64``
invocation command::

  -netdev user,smb="/path/to/shared/directory",id=mynet0 \
  -device e1000,netdev=mynet0 \

The shared directory can be mounted by a guest Linux machine like this::

  mount -t cifs //10.0.2.4/qemu <mountpoint> -o user=<user>,pass=<password>

The ``<user>`` and the ``<password>`` can be almost *anything* existing or not,
even nothing, you even can provide just ``-o user=,pass=``.

The ``-t cifs`` part might be optional if ``mount`` supports inferring file
system type.

To mount it via ``/etc/fstab`` add the following line to the file::

  //10.0.2.4/qemu <mountpoint> cifs user=<user>,pass=<password> 0 0

On Windows you can just enter the following address into explorer's address
bar, no authentication required::

  \\10.0.2.4\qemu

Overall it looks like this:

.. image:: windows-guest-explorer-exe-qemu-samba.png

Pass specific USB port to the guest [#qemu-usb-emulation]_
==========================================================

Here is how it's done::

  -device qemu-xhci \
  -device usb-host,hostbus=<bus>,hostport=<port> \

First find the <bus> and <port> values of the USB port (physical socket) you
need to pass to the guest machine. Take a USB device you can clearly identify in
the ``lsusb`` output and insert it into the port. Then run ``lsusb -t`` and
observe the output::

  /:  Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/10p, 480M
      |__ Port 001: Dev 123, If 0, Class=Hub, Driver=hub/4p, 480M
          |__ Port 002: Dev 031, If 0, Class=Vendor Specific Class, Driver=cp210x, 12M
          |__ Port 004: Dev 127, If 0, Class=Hub, Driver=hub/4p, 480M
              |__ Port 002: Dev 006, If 0, Class=Hub, Driver=hub/4p, 480M
      |__ Port 004: Dev 003, If 0, Class=Wireless, Driver=btusb, 12M
      |__ Port 004: Dev 003, If 1, Class=Wireless, Driver=btusb, 12M
      |__ Port 007: Dev 005, If 0, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 008: Dev 007, If 0, Class=Wireless, Driver=btusb, 12M
      |__ Port 008: Dev 007, If 1, Class=Wireless, Driver=btusb, 12M
  /:  Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 10000M
      |__ Port 001: Dev 015, If 0, Class=Hub, Driver=hub/4p, 5000M
  /:  Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 480M
      |__ Port 002: Dev 002, If 0, Class=Audio, Driver=snd-usb-audio, 12M
      |__ Port 002: Dev 002, If 1, Class=Audio, Driver=snd-usb-audio, 12M
      |__ Port 002: Dev 002, If 2, Class=Audio, Driver=snd-usb-audio, 12M
      |__ Port 002: Dev 002, If 3, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 003: Dev 003, If 0, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 003: Dev 003, If 1, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 003: Dev 003, If 2, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 004: Dev 004, If 0, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 004: Dev 004, If 1, Class=Human Interface Device, Driver=usbhid, 12M
      |__ Port 004: Dev 004, If 2, Class=Human Interface Device, Driver=usbhid, 12M
  /:  Bus 004.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 10000M

You can also run just ``lsusb`` command, since it has human friendly device
description, but without tree structure, and note the ``Device`` number listed
to use it to identify the device in the ``lsusb -t`` command output::

  Bus 001 Device 031: ID 10c4:ea60 Silicon Labs CP210x UART Bridge

My device here is ``cp210x`` with number ``031`` and it sits on the bus ``1``
and port ``1.2``. Look closely at how these numbers are inferred::

            +- The bus number (1)
            |    +- The first number of the <port> value (1)
            |    |   +- The second number of the <port> value (2)
            v    |   |
  /:  Bus 001    v   |  Dev 001, Class=root_hub, Driver=xhci_hcd/10p, 480M
      |__ Port 001:  v  123, If 0, Class=Hub, Driver=hub/4p, 480M
          |__ Port 002: Dev 031, If 0, Class=Vendor Specific Class, Driver=cp210x, 12M

I am going to use these ``<hostbus>`` (``1``) and ``<port>`` (``1.2``) values
like this::

  -device qemu-xhci \
  -device usb-host,hostbus=1,hostport=1.2 \

Note that the ``<port>`` value complexity depends on how many USB hubs you have
inserted into each other. If there are no USB hubs, then there will be most
likely just a single number. If you are trying to pass a port of a USB hub, then
you will end up with two numbers separated by dot. If it is a port of a USB hub
inserted in another USB hub, then you will need three numbers separated by dots
to describe the ``hostport`` like ``1.5.2``. It is possible that your
motherboard has a USB hub on it (laptops are made like this sometimes) and
expose it's ports, then such a port may have two numbers, separated by a dot.

.. [#shared-folder] `Shared folder between QEMU Windows guest and Linux host / stackexchange.com <https://unix.stackexchange.com/a/183609>`_
.. [#qemu-usb-emulation] `USB emulation - QEMU documentation / www.qemu.org <https://www.qemu.org/docs/master/system/devices/usb.html>`_