6 37 38 39 40
GDB显示其内部数据为: (gdb) p *obj //Object *obj
$11 = {class = 0x555556a50e50, free = 0x7ffff7424020 , properties = {tqh_first = 0x555556a17da0, tqh_last = 0x555556a50fd0}, ref = 1, parent = 0x0}
(gdb) p *obj->class //ObjectClass * class
$12 = {type = 0x5555566e5cb0, interfaces = 0x0, unparent = 0x5555556b1ac0 }
(gdb) p *obj->class->type //struct TypeImpl * type
$13 = {name = 0x5555566e5e30 \instance_size = 664, class_init = 0x55555579b790 , class_base_init = 0,
class_finalize = 0, class_data = 0x0, instance_init = 0, instance_finalize = 0, abstract = false, parent = 0x5555566e5e50 \
parent_type = 0x5555566d8bd0, class = 0x555556a50e50, num_interfaces = 0, interfaces = {{typename = 0x0} }}
QOM设备初始化
基于Object和ObjectClass实现的QOM设备,何时触发他的初始化,以PIT为例,将之前的Object和ObjectClass想象成C++,那么PIT对应的PitCommonState定义应该类似如下所示:
class PITCommonClass : public ISADeviceClass { public: virtual int init(PITCommonState *s) = 0; }; class ISADevice : public DeviceState { public: int nirqs; int ioport_id; }; class PITCommonState : public ISADevice, public PITCommonClass { int init(PITCommonState *s); };
Class PITCommonClass:publicISADeviceClass{ public:
virtual int init(PITCommonState*s)=0; };
Class ISADevice:publicDeviceState{ public: int nirqs; int ioport_id; };
Class PITCommonState:publicISADevice,publicPITCommonClass{ Int init(PITCommonState*s); };
看吧,QEMU绕了这么大一个圈子,就想实现这样一个结构,所以有的时候用C++还是有好处的(虽然本人生理周期现正处于不太喜欢C++时间)。 那么,何处调用了new PITCommonState()?
这得从main函数开始看,main函数里面,有machine->init(&args);函数调用,这是对注册的machine的初始 化,而默认的machine是在pc_piix.c里面pc_machine_init函数注册的第一个machine,即:
static QEMUMachine pc_i440fx_machine_v1_4 = { .name = \.alias = \
.desc = \.init = pc_init_pci, .max_cpus = 255, .is_default = 1,
.default_machine_opts = KVM_MACHINE_OPTIONS, DEFAULT_MACHINE_OPTIONS, };
qemu_register_machine(&pc_i440fx_machine_v1_4);
staticQEMUMachinepc_i440fx_machine_v1_4={ .name=\ .alias=\
.desc=\ .init=pc_init_pci, .max_cpus=255,
.is_default=1,
.default_machine_opts=KVM_MACHINE_OPTIONS, DEFAULT_MACHINE_OPTIONS, };
qemu_register_machine(&pc_i440fx_machine_v1_4);
当main函数调用machine->init时,我的实验环境默认情况其实就是调用的pc_i440fx_machine_v1_4的初始化回调pc_init_pci -> pc_init1,这个函数主要初始化相关PC硬件:
static void pc_init1(MemoryRegion *system_memory, MemoryRegion *system_io, ram_addr_t ram_size, const char *boot_device, const
char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, int pci_enabled, int kvmclock_enabled) { //CPU类型初始化-> cpu_x86_init -> mce_init/qemu_init_vcpu,初始化VCPU pc_cpus_init(cpu_model); //初始化acpi_tables pc_acpi_init(\(!xen_enabled()) { //ROM, BIOS, RAM相关初始化 fw_cfg = pc_memory_init(system_memory, kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size, rom_memory, &ram_memory); } //IRQ,初始化 //VGA初始化 pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); /* init basic PC hardware */ pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled()); //这里调用pit_init //初始化网卡 pc_nic_init(isa_bus, pci_bus); //初始化硬盘,音频设备 //初始化cmos数据,比如设置cmos rtc时钟,是否提供PS/2设备
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, floppy, idebus[0], idebus[1], rtc_state); //初始化USB if (pci_enabled && usb_enabled(false)) { pci_create_simple(pci_bus, piix3_devfn + 2, \
pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, bool no_vmport) { //初始化HPET //初始化mc146818 rtc //初始化i8042 PIT pit = pit_init(isa_bus,
0x40, pit_isa_irq, pit_alt_irq); //初始化串口,并口 //初始化vmmouse ps2_mouse }
staticvoidpc_init1(MemoryRegion*system_memory,
MemoryRegion*system_io, ram_addr_tram_size, constchar*boot_device, constchar*kernel_filename, constchar*kernel_cmdline, constchar*initrd_filename, constchar*cpu_model, intpci_enabled,
intkvmclock_enabled) {
//CPU类型初始化-> cpu_x86_init -> mce_init/qemu_init_vcpu,初始化VCPU
pc_cpus_init(cpu_model); //初始化acpi_tables
pc_acpi_init(\ if(!xen_enabled()){
//ROM, BIOS, RAM相关初始化
fw_cfg=pc_memory_init(system_memory,
kernel_filename,kernel_cmdline,initrd_filena me,
below_4g_mem_size,above_4g_mem_size, rom_memory,&ram_memory); }
//IRQ,初始化 //VGA初始化
pc_vga_init(isa_bus,pci_enabled?pci_bus:NULL); /* init basic PC hardware */
pc_basic_device_init(isa_bus,gsi,&rtc_state,&floppy,xen_enabled());//这里调用pit_init //初始化网卡
pc_nic_init(isa_bus,pci_bus); //初始化硬盘,音频设备
//初始化cmos数据,比如设置cmos rtc时钟,是否提供PS/2设备 pc_cmos_init(below_4g_mem_size,above_4g_mem_size,boot_device,
floppy,idebus[0],idebus[1],rtc_state); //初始化USB
if(pci_enabled&&usb_enabled(false)){
pci_create_simple(pci_bus,piix3_devfn+2,\