Table of Contents
QEMU启动的命令带有参数“-M q35 ”,它表示虚拟机的machine和chipset为q35。
架构
QEMU支持的chipset很少。1996年诞生的I440FX由于不支持PCIe等原因,被2012年Jason Baron引入的Q35 chipset所替代。
I440FX架构图如下。支持的总线都比较古老。
Q35架构图如下。分为南北桥,北桥MCH通过前端总线FSB与CPU连接,提供PCIe接口和DDR内存接口等。南桥ICH9通过DMI总线连接到北区MCH,提供USB2.0, SATA等各种低速外设。
q35架构有两种类型的属性结构,第一个是qtree,第二个是qom-tree。
qtree
通过“info qtree”命令可以查看QEMU中系统设备架构信息。以下是删减过dev细节的示例,其中q35-pcihost会整个Q35 chipset的根节点。
[root@localhost kvm]# x86_64-softmmu/qemu-system-x86_64 -M q35 -m 1024 -enable-kvm -monitor stdio
QEMU 4.1.0 monitor - type 'help' for more information
(qemu) VNC server running on ::1:5901
(qemu) info qtree
bus: main-system-bus
type System
dev: hpet, id ""
dev: kvm-ioapic, id ""
dev: q35-pcihost, id ""
bus: pcie.0
type PCIE
dev: e1000e, id ""
dev: VGA, id ""
dev: ICH9 SMB, id ""
bus: i2c
type i2c-bus
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: smbus-eeprom, id ""
dev: ich9-ahci, id ""
bus: ide.5
type IDE
bus: ide.4
type IDE
bus: ide.3
type IDE
bus: ide.2
type IDE
dev: ide-cd, id ""
bus: ide.1
type IDE
bus: ide.0
type IDE
dev: ICH9-LPC, id ""
bus: isa.0
type ISA
dev: port92, id ""
dev: vmmouse, id ""
dev: vmport, id ""
dev: i8042, id ""
dev: isa-parallel, id ""
dev: isa-serial, id ""
dev: i8257, id ""
dev: i8257, id ""
dev: isa-pcspk, id ""
dev: kvm-pit, id ""
dev: mc146818rtc, id ""
dev: kvm-i8259, id ""
dev: kvm-i8259, id ""
dev: mch, id ""
dev: fw_cfg_io, id ""
dev: kvmclock, id ""
dev: kvmvapic, id ""
(qemu)
简化示意图如下。可以清楚的看到这个设备树是总线和设备交替连接的。每个设备都是挂载在一个总线上的,设备又可以生成新的总线,如此往复。
这种bus和device交替的关系,也体现在设备和总线对象结构的定义上
struct DeviceState {
...
BusState *parent_bus; //设备device的parent是总线bus
QLIST_HEAD(, BusState) child_bus; //设备device的child是总线bus
int num_child_bus;
...
};
struct BusState {
...
DeviceState *parent; //总线bus的parent是设备device
int num_children;
QTAILQ_HEAD(, BusChild) children; //总线bus的child是BusChild结构中定义的设备device
QLIST_ENTRY(BusState) sibling; //总线bus的sibling是总线bus
...
};
typedef struct BusChild {
DeviceState *child;
int index;
QTAILQ_ENTRY(BusChild) sibling;
} BusChild;
main-system-bus不是根设备对象,main-system-bus之前还有root和machine两级对象。
main-system-bus系统总线
所有设备都是挂载在main-system-bus是系统总线的后面。它是个虚拟的总线。
它的type_info定义如下,
static const TypeInfo system_bus_info = {
.name = TYPE_SYSTEM_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(BusState),
.class_init = system_bus_class_init,
};
sysbus_get_default调用main_system_bus_create生成main_system_bus对象。
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
static BusState *main_system_bus; #全局变量
static void main_system_bus_create(void)
{
/* assign main_system_bus before qbus_create_inplace()
* in order to make "if (bus != sysbus_get_default())" work */
main_system_bus = g_malloc0(system_bus_info.instance_size);
qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
TYPE_SYSTEM_BUS, NULL, "main-system-bus");
OBJECT(main_system_bus)->free = g_free;
}
BusState *s