The document discusses QEMU and adding a new device to it. It begins with an introduction to QEMU and its uses. It then discusses setting up a development environment, compiling QEMU, and examples of existing devices. The main part explains how to add a new "Devix" device by creating source files, registering the device type, initializing PCI configuration, and registering memory regions. It demonstrates basic functionality like interrupts and I/O access callbacks. The goal is to introduce developing new emulated devices for QEMU.
Architecture decision records - How not to get lost in the past
Qemu device prototyping
1. QEMU AND DEVICE EMULATION
Yan Vugenfirer, yan@daynix.com
Daynix Computing LTD
2. Daynix Computing LTD
AGENDA
• Introduction to QEMU
• Development environment
• Examples of existing devices
• Adding a new device to
QEMU
3. Daynix Computing LTD
WHAT IS QEMU?
• Open source project (GPLv2.0+ license)
• Machine emulator
• Virtualizer
• Works together with KVM and Xen
4. Daynix Computing LTD
WHY SHOULDYOU CARE?
• Open source
• Easy to add additional devices
• Emulates different HW architectures
• Can be used for SW development long before
HW is ready
5. Daynix Computing LTD
GET IT NOW
• Project website: http://wiki.qemu.org/Main_Page
• Code repository: git clone git://git.qemu-
project.org/qemu.git
15. Daynix Computing LTD
QEMU DEVICE MODEL
• QDev device model abstraction
• Tree of devices connected by buses
• Represented by DeviceState and BusState
• Devices have common API
• Devices have properties
• Check include/hw/qdev-core.h for more info
18. Daynix Computing LTD
ADDING NEW DEVICE
• Basic source file for the device
• Enable the compilation of the device
• Command line options
• Step by step enhancement of the device
19. Daynix Computing LTD
ADDING NEW DEVICE
• In qemu/HW/net/ let’s create devix.c
• Add CONFIG_DEVIX_PCI option to default-configs/
pci.mak
• Add devix.o to hw/net/Makefile.objs
34. Daynix Computing LTD
LEGACY INTERRUPTS
• Add interrupt line in pci_init
/* Interrupt pin A */
pci_dev->config[PCI_INTERRUPT_PIN] = 0x01;
35. Daynix Computing LTD
LEGACY INTERRUPTS
• Call to void pci_irq_assert(PCIDevice *pci_dev)
when you want to raise interrupt
• Call void pci_irq_deassert(PCIDevice *pci_dev) to
de-assert interrupt from one of your registers
callback depending on clear interrupt logic
36. Daynix Computing LTD
VM POINT OFVIEW
00:04.0 Ethernet controller: Device 9696:1234
(rev 01)
Subsystem: Device 9696:1234
Physical Slot: 4
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr-
DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
INTx-
Interrupt: pin A routed to IRQ 11
Region 0: Memory at febd2000 (32-bit, non-
prefetchable) [size=4K]
Region 1: I/O ports at c000 [size=512]
• sudo lspci -vv
37. Daynix Computing LTD
“DMA”
• Actually guest memory access
• Synchronous
• void cpu_physical_memory_read(hwaddr addr, void *buf, int len)
• void cpu_physical_memory_write(hwaddr addr, const void *buf, int len)
• iov_xxx functions
• Check include/exec/cpu-common.h for more access functions