qdev初步解析
classDiagram Object --|> DeviceState DeviceState --|> USBDevice USBDevice --|> USBRedirDevice Object o-- ObjectClass ObjectClass --|> DeviceClass DeviceClass --|> USBDeviceClass
1 | //hw/usb/redirect.c |
1 | //hw/usb/bus.c |
1 | //hw/core/qdev.c |
1 | //qom/object.c |
继承关系一路找到object,并未发现“bus”属性
全局搜索,在下面文件中发现了bus属性
1 | //blockdev.c |
这里的bus是一个int类型,不是我们要找的结构
又在qdev-monitor.c中找到bus的相关代码,这里应该是我们要找的东西
1 | //qdev-monitor.c |
//sysbus_get_default 明显应该就是设备树的根了
然后用qbus_find_recursive递归查找节点
1 | static BusState *qbus_find_recursive(BusState *bus, const char *name, |
可以看到,如果你没有设置id选项,设备就会随便给你一个名字device[n]
1 | //调用顺序 |
看下面代码,不难看出,object的所有property均以数组的形式存在
你指定一个设备比如id=pci 那么它的实际id其实是pci.0
你再指定一个id为pci的设备,它不会产生冲突,反而会变成pci.1
1 | //调用顺序 |
1 | typedef struct Object Object; |
1 | // file bootdevice.c |
关于addr
经过一系列转化后,变成两部分保存在devfn中
- 一部分是pci的slot 在前5位保存,最大1f(0-31),对应硬件设备的插槽
- 一部分是FUN,后3位保存,最大值7(0-7)
- 通过和名为slot_reserved_mask的bitmap比较确认空闲与否
- 如果默认没有填写,会从前往后依次尝试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17static Property pci_props[] = {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1)
//...
};
static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
{
return bus->slot_reserved_mask & (1UL << PCI_SLOT(devfn));
}
static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
{
return bus->slot_reserved_mask & (1UL << PCI_SLOT(devfn));
}
这里的devfn就是addr
1 | static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, |
关于masterbus字段,我们看以下下面这段代码
没有配置masterbus,直接使用usb_register_port在bus(pci)上注册
如果使用了,则使用usb_register_companion注册共用port
1 | static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) |
1 | //hw/usb/bus.c |
在被共用的USB设备上(这里指ehci),除了定义自己的ports之外,还定义了一个USBPort*的公用指针数组
,然后在注册时,把共用的PORT放在这个指针上
ehci自己的realize函数,则把所有端口都注册到bus总线上
这里的bus总线,是usbbus,通过usb_bus_new函数创建
每个主控驱动独立使用时,都会创建一个,复用则不会
1 | USBPort ports[NB_PORTS]; |
qemu的设备结构,基本上是Device-Bus-Device-Bus这样的
添加Device的时候,在指定的Bus上加入Device.id[{x}]
而添加Bus的时候,如果不指定名字,名字自动设置为Device.id.{x}
1 | static void qbus_realize(BusState *bus, DeviceState *parent, const char *name) |
- 本文作者: crazyboy
- 本文链接: http://crazyboy.www.crazyboy.info/blog/blog/2022/04/26/it/linux/qemu/qemu-device/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!