aboutsummaryrefslogtreecommitdiff
path: root/docs/qemu.md
blob: 0ff4dcddaf74327cf0fccc93fffac609d9a5d7a4 (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
qemu usage walkthrough
======================

In this walk-through, we'll use an Ubuntu cloudimg along with the
[gpio sample server](../samples/gpio-pci-idio-16.c) to emulate a very simple GPIO
device.

Building qemu
-------------

`vfio-user` client support is not yet merged into `qemu`. Instead, download and
build [jlevon's master.vfio-user branch of
qemu](https://github.com/jlevon/qemu/tree/master.vfio-user); for example:

```
git clone -b master.vfio-user git@github.com:jlevon/qemu.git
cd qemu

./configure --prefix=/usr --enable-kvm --enable-vnc --target-list=x86_64-softmmu --enable-debug  --enable-vfio-user-client
make -j
```

Configuring the cloudimg
------------------------

Set up the necessary metadata files:

```
sudo apt install cloud-image-utils

$ cat metadata.yaml
instance-id: iid-local01
local-hostname: cloudimg

$ cat user-data.yaml
#cloud-config
ssh_import_id:
  - gh:jlevon

cloud-localds seed.img user-data.yaml metadata.yaml
```

don't forget to replace `jlevon` with *your* github user name.

Starting the server
-------------------

Start the `gpio` server process:

```
rm -f /tmp/vfio-user.sock
./build/samples/gpio-pci-idio-16 -v /tmp/vfio-user.sock &
```

Booting the guest OS
--------------------

Make sure your system has hugepages available:

```
$ cat /proc/sys/vm/nr_hugepages
1024
```

Now you should be able to start qemu:

```
$ imgpath=/path/to/bionic-server-cloudimg-amd64.img
$ sudo ~/src/build/qemu-system-x86_64 \
   -machine accel=kvm,type=q35 -cpu host -m 2G \
   -mem-prealloc -object memory-backend-file,id=ram-node0,prealloc=yes,mem-path=/dev/hugepages/gpio,share=yes,size=2G \
   -numa node,memdev=ram-node0 \
   -nographic \
   -device virtio-net-pci,netdev=net0 \
   -netdev user,id=net0,hostfwd=tcp::2222-:22 \
   -drive if=virtio,format=qcow2,file=$imgpath \
   -drive if=virtio,format=raw,file=seed.img \
   -device vfio-user-pci,socket=/tmp/vfio-user.sock
```

Log in to your VM and load the kernel driver:

```
$ ssh -p 2222 ubuntu@localhost
...
$ sudo apt install linux-modules-extra-$(uname -r)
$ sudo modprobe gpio-pci-idio-16
```

Now we should be able to observe the emulated GPIO device's pins:

```
$ sudo su -
# cat /sys/class/gpio/gpiochip480/base > /sys/class/gpio/export
# for ((i=0;i<12;i++)); do cat /sys/class/gpio/OUT0/value; done
```

and the server should output something like:

```
gpio: region2: read 0 from (0:1)
gpio: region2: read 0 from (0:1)
gpio: region2: read 0 from (0:1)
gpio: region2: read 0x1 from (0:1)
gpio: region2: read 0x1 from (0:1)
gpio: region2: read 0x1 from (0:1)
gpio: region2: read 0x2 from (0:1)
gpio: region2: read 0x2 from (0:1)
gpio: region2: read 0x2 from (0:1)
gpio: region2: read 0x3 from (0:1)
gpio: region2: read 0x3 from (0:1)
gpio: region2: read 0x3 from (0:1)
```