启动虚拟机
virDomainCreate
#0 virDomainCreate (domain=0x697990) at libvirt.c:8133
#1 0x000000000042261f in cmdStart (ctl=0x7fffffffe230, cmd=0x696890)
at virsh.c:3150
#2 0x000000000041cd1e in vshCommandRun (ctl=0x7fffffffe230, cmd=0x696890)
at virsh.c:18449
#3 0x000000000042e2d6 in main (argc=3, argv=0x7fffffffe488) at virsh.c:20052 remote_driver.c
remoteDomainCreate
call-> callWithFD-> virNetClientProgramCall-> virNetClientSendWithReply->
virNetClientSendInternal-> virNetClientIOqemu_driver.c
qemuDomainStart -> qemuDomainStartWithFlags -> qemuDomainObjStart
-> qemuProcessStart-> virCommandRun剩余工作由qemu来完成,如分配内存qemu初始化时会调用pc_memory_init来分配内存。
qemu_domain.c中
qemuDomainObjBeginJobWithDriverqemu_process.c中
qemuProcessStart#0 qemuDomainStart (dom=0x7f34b4001090) at qemu/qemu_driver.c:4862
#1 0x00007f34defc1bef in virDomainCreate (domain=0x7f34b4001090)
at libvirt.c:8153
#2 0x000000000043de40 in remoteDispatchDomainCreate (args=<optimized out>,
rerr=<optimized out>, msg=<optimized out>, client=<optimized out>,
server=<optimized out>) at remote_dispatch.h:852
#3 remoteDispatchDomainCreateHelper (server=<optimized out>,
client=<optimized out>, msg=<optimized out>, rerr=0x7f34d9ed3c80,
args=<optimized out>, ret=<optimized out>) at remote_dispatch.h:830
#4 0x00007f34df00ca61 in virNetServerProgramDispatchCall (
msg=<optimized out>, client=<optimized out>, server=<optimized out>,
prog=<optimized out>) at rpc/virnetserverprogram.c:416
#5 virNetServerProgramDispatch (prog=0x7956d0, server=0x78a4e0,
client=0x790ec0, msg=0x7d58f0) at rpc/virnetserverprogram.c:289
#6 0x00007f34df007e51 in virNetServerHandleJob (jobOpaque=<optimized out>,
opaque=0x78a4e0) at rpc/virnetserver.c:168
#7 0x00007f34def36f66 in virThreadPoolWorker (opaque=<optimized out>)
at util/threadpool.c:144
#8 0x00007f34def36617 in virThreadHelper (data=<optimized out>)
at util/threads-pthread.c:161
#9 0x00007f34dc635f05 in start_thread () from /lib64/libpthread.so.0
#10 0x00007f34dbf7153d in clone () from /lib64/libc.so.6qemu-kvm -m 1024 -smp 2 -hda /home/sdb/kvm_windows7.img -vnc :11
#0 pc_memory_init (system_memory=0x555556401880, kernel_filename=0x0,
kernel_cmdline=0x555555866d97 "", initrd_filename=0x0,
below_4g_mem_size=1073741824, above_4g_mem_size=0,
rom_memory=0x5555564325e0, ram_memory=0x7fffffffde80)
at /home/sdc/wyf/kvm/qemu-kvm-1.0.1/hw/pc.c:977
#1 0x00005555557ec12f in pc_init1 (system_memory=0x555556401880,
system_io=0x555556401980, ram_size=1073741824,
boot_device=0x7fffffffe310 "cad", kernel_filename=0x0,
kernel_cmdline=0x555555866d97 "", initrd_filename=0x0, cpu_model=0x0,
pci_enabled=1, kvmclock_enabled=1)
at /home/sdc/wyf/kvm/qemu-kvm-1.0.1/hw/pc_piix.c:134
#2 0x00005555557ec7ed in pc_init_pci (ram_size=1073741824,
boot_device=0x7fffffffe310 "cad", kernel_filename=0x0,
kernel_cmdline=0x555555866d97 "", initrd_filename=0x0, cpu_model=0x0)
at /home/sdc/wyf/kvm/qemu-kvm-1.0.1/hw/pc_piix.c:257
#3 0x00005555556a7d49 in main (argc=9, argv=0x7fffffffe438,
envp=0x7fffffffe488) at /home/sdc/wyf/kvm/qemu-kvm-1.0.1/vl.c:3389qemu部分
运行状态初始化
runstate_init();
时钟初始化
init_clocks();(gdb) p *envp
$2 = 0x7fffffffe7e2 "LESSKEY=/etc/lesskey.bin"
qemu_cache_utils_init(envp);
链表初始化
QLIST_INIT (&vm_change_state_head);
信号初始化
os_setup_early_signal_handling();
模块调用初始化
module_call_init(MODULE_INIT_MACHINE);
pc_machine_init
fsdev_register_config
找到默认qemu机器
machine = find_default_machine();第一次对选项进行分词
/* first pass of option parsing */
optind = 1;
while (optind < argc) {
if (argv[optind][0] != '-') {
/* disk image */
optind++;
continue;
} else {
const QEMUOption *popt; popt = lookup_opt(argc, argv, &optarg, &optind);
switch (popt->index) {
永远走不到,无定义参数lookup_opt中直接跳出。
case QEMU_OPTION_nodefconfig:
defconfig=0;
break;
}
}
}
if (defconfig) {
int ret;
qemu读取配置文件qemu.conf,没有该配置文件
/usr//etc/qemu/qemu.conf
ret = qemu_read_config_file(CONFIG_QEMU_CONFDIR "/qemu.conf");
if (ret < 0 && ret != -ENOENT) {
exit(1);
}
qemu读取配置文件target-x86_64.conf,
/usr//etc/qemu/target-x86_64.conf
ret = qemu_read_config_file(arch_config_name);
if (ret < 0 && ret != -ENOENT) {
exit(1);
}
}cpu定义初始化
cpudef_init();第二次对参数选项分词
……
将当前位置变到没啥特殊的地方”nowhere in particular”
loc_set_none(); 跟踪后端初始化
if (!trace_backend_init(trace_events, trace_file)) {
exit(1);
} 定义数据目录
/* If no data_dir is specified then try to find it relative to the
executable path. */
/usr/share/qemu
if (!data_dir) {
data_dir = os_find_datadir(argv[0]);
}
/* If all else fails use the install path specified when building. */
if (!data_dir) {
data_dir = CONFIG_QEMU_DATADIR;
}对device、global选项进行默认驱动检查
qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, 0);
qemu_opts_foreach(qemu_find_opts("global"), default_driver_check, NULL, 0);(gdb) p display_type
$11 = DT_DEFAULT设定默认显示配置
if (display_type == DT_NOGRAPHIC) {
if (default_parallel)
add_device_config(DEV_PARALLEL, "null");
if (default_serial && default_monitor) {
add_device_config(DEV_SERIAL, "mon:stdio");
} else if (default_virtcon && default_monitor) {
add_device_config(DEV_VIRTCON, "mon:stdio");
} else {
if (default_serial)
add_device_config(DEV_SERIAL, "stdio");
if (default_virtcon)
add_device_config(DEV_VIRTCON, "stdio");
if (default_monitor)
monitor_parse("stdio", "readline");
}
} else {
if (default_serial)
add_device_config(DEV_SERIAL, "vc:80Cx24C");
if (default_parallel)
add_device_config(DEV_PARALLEL, "vc:80Cx24C");
if (default_monitor)
monitor_parse("vc:80Cx24C", "readline");
if (default_virtcon)
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
} if (default_vga)
vga_interface_type = VGA_CIRRUS;
socket初始化,linux直接返回0。
socket_init();
对字符设备初始化
if (qemu_opts_foreach(qemu_find_opts("chardev"), chardev_init_func, NULL, 1) != 0)
exit(1);
#ifdef CONFIG_VIRTFS
对文件系统设备进行初始化——没走进fsdev_init_func
if (qemu_opts_foreach(qemu_find_opts("fsdev"), fsdev_init_func, NULL, 1) != 0) {
exit(1);
}
#endif守护进程化
os_daemonize();
配置加速器
configure_accelerator();
for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
if (strcmp(accel_list[i].opt_name, buf) == 0) {
*(accel_list[i].allowed) = 1;
ret = accel_list[i].init(); kvm-all.c kvm_init
qemu初始化cpu循环
qemu_init_cpu_loop();
qemu初始化主循环
if (qemu_init_main_loop()) {
fprintf(stderr, "qemu_init_main_loop failed\n");
exit(1);
}
os设定行缓存区
os_set_line_buffering(); 初始化时钟告警
if (init_timer_alarm() < 0) {
fprintf(stderr, "could not initialize alarm timer\n");
exit(1);
}
配置icount,kvm或xen不允许配icount,直接返回。
configure_icount(icount_option);
初始化网络客户端
if (net_init_clients() < 0) {
exit(1);
} 初始化蓝牙世界
/* init the bluetooth world */
if (foreach_device_config(DEV_BT, bt_parse))
exit(1);
非xen的32位最多支持2GRAM的内存模拟。
if (!xen_enabled()) {
/* On 32-bit hosts, QEMU is limited by virtual address space */
if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
exit(1);
}
}cpu执行初始化(内存映射初始化、io内存初始化)
cpu_exec_init_all();
块设备初始化
bdrv_init_with_whitelist();blk_mig_init();
打开虚拟块设备
/* open the virtual block devices */
if (snapshot)
qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
exit(1); default_drive(default_cdrom, snapshot, machine->use_scsi,
IF_DEFAULT, 2, CDROM_OPTS);
default_drive(default_floppy, snapshot, machine->use_scsi,
IF_FLOPPY, 0, FD_OPTS);
default_drive(default_sdcard, snapshot, machine->use_scsi,
IF_SD, 0, SD_OPTS); register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
ram_load, NULL); 模块调用初始化(wdt_ib700_register_devices/ vmport_dev_register/ testdev_register_devices/ sga_register/ i440fx_register/ port92_register/ isa_qdev_register/ kvmclock_register_device/ kvm_tpr_opt_setup/ ivshmem_register_devices/ ioapic_register_devices/ pic_register/ pit_register/ pci_qdev_register/ debugcon_register_devices……
module_call_init(MODULE_INIT_DEVICE);机器初始化(pc_init_pci-> pc_init1 PC硬件初始化)
machine->init(ram_size, boot_devices,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);pc的cpu初始化
pc_cpus_init(cpu_model);
if (kvmclock_enabled) {
kvm时钟创建
kvmclock_create();
}
pci内存初始化
if (pci_enabled) {
pci_memory = g_new(MemoryRegion, 1);
memory_region_init(pci_memory, "pci", INT64_MAX);
rom_memory = pci_memory;
} else {
pci_memory = NULL;
rom_memory = system_memory;
}分配内存、加载rom/bios
/* allocate ram and load rom/bios */
if (!xen_enabled()) {
pc_memory_init(system_memory,
kernel_filename, kernel_cmdline, initrd_filename,
below_4g_mem_size, above_4g_mem_size,
pci_enabled ? rom_memory : system_memory, &ram_memory);
}gsi_state = g_malloc0(sizeof(*gsi_state));
qemu为gsi状态分配中断
gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);为cpu中断分配内存
if (!xen_enabled()) {
cpu_irq = pc_allocate_cpu_irq();
i8259 = i8259_init(cpu_irq[0]);
} else {
i8259 = xen_interrupt_controller_init();
}
ioapic初始化
if (pci_enabled) {
ioapic_init(gsi_state);
}
vga初始化
pc_vga_init(pci_enabled? pci_bus: NULL);虚拟机基本设备初始化
/* init basic PC hardware */
pc_basic_device_init(gsi, &rtc_state, &floppy, xen_enabled());
for(i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i]; if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
pc_init_ne2k_isa(nd);
else
网卡初始化
pci_nic_init_nofail(nd, "rtl8139", NULL);
}
if (pci_enabled) {
PCIDevice *dev;
if (xen_enabled()) {
dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
} else {
磁盘初始化
dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
}
声卡初始化
audio_init(gsi, pci_enabled ? pci_bus : NULL);cmos初始化
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
floppy, idebus[0], idebus[1], rtc_state);
if (pci_enabled && acpi_enabled) {
i2c_bus *smbus; if (!xen_enabled()) {
分配中断
cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
} else {
cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1);
}
piix4_pm初始化
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
gsi[9], *cmos_s3, *smi_irq,
kvm_enabled());
smbus_eeprom_init(smbus, 8, NULL, 0);
if (pci_enabled) {
pci设备初始化
pc_pci_device_init(pci_bus);
} cpu同步初始化
cpu_synchronize_all_post_init();
设定numa模式
set_numa_modes();
初始化usb设备
/* init USB devices */
if (usb_enabled) {
if (foreach_device_config(DEV_USB, usb_parse) < 0)
exit(1);
}
初始化通用设备
/* init generic devices */
if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
exit(1);
网络客户端检查
net_check_clients();
建立信号处理
os_setup_signal_handling();
#ifdef CONFIG_VNC
vnc显示初始化
/* init remote displays */
if (vnc_display) {
vnc_display_init(ds);
if (vnc_display_open(ds, vnc_display) < 0)
exit(1); if (show_vnc_port) {
printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
}
}
#endif显示配置
/* display setup */
dpy_resize(ds);
dcl = ds->listeners;
while (dcl != NULL) {
if (dcl->dpy_refresh != NULL) {
ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
break;
}
dcl = dcl->next;
}
文本控制台设定显示
text_consoles_set_display(ds);
初始化虚拟机设定完成
qdev_machine_creation_done();
只读内存加载
if (rom_load_all() != 0) {
fprintf(stderr, "rom loading failed\n");
exit(1);
}
寄存器重置
qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());qemu_run_machine_init_done_notifiers();
qemu系统重置
qemu_system_reset(VMRESET_SILENT);} else if (autostart) {
虚拟机启动
vm_start();
}
操作系统设定路标
os_setup_post();
恢复所有vcpu
resume_all_vcpus();
进入主循环
main_loop();
关闭块设备
bdrv_close_all();
暂停所有vcpu
pause_all_vcpus();
清理网络
net_cleanup();
寄存器释放
res_free();2013年5月24日
虚拟机查看mysql错误日志
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
上一篇:安装axios很卡
下一篇:linux 查看qemu 版本
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章