qemu-kvm设备初始化
来源:互联网 发布:安装淘宝还要旺信吗 编辑:程序博客网 时间:2024/05/22 07:58
1. vm_config_groups是一个数组,数组每一个成员是一个链表表头,这些链表包含了qemu-kvm的各种启动参数,device链表是链表数组中的一个链表。
2. QemuOptsList类型的device链表中的成员是QemuOpts类型,一个QemuOpts变量代表一个qemu-kvm中的“-device参数”,device链表中QemuOpts的数量就等于“-device”的数量,初始化时,会循环为每一个QemuOpts变量调用device_init_func函数。
3. 因为“-device”参数还有子参数(如virtio-scsi-pci.hotplug=on/off),所以QemuOptsList也引导一个链表,链表节点是QemuOpt类型,链表的每一个节点就对应“-device”的一个子参数。
4.device链表中每一个QemuOptsList节点对应一个“-device”参数,QemuOptsList链表中的每一个节点对应该“-device”的一个子参数。这些信息都是从qemu-kvm的启动参数初始化而来的。该函数完成工作就是 在vm_config_groups中找到device链表成员并返回。
main()
{
...
/* init generic devices */
if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
exit(1);
...
}
/*
该函数完成工作就是 在vm_config_groups中找到device链表成员并返回。
*/
QemuOptsList *qemu_find_opts(const char *group)
{
QemuOptsList *ret;
Error *local_err = NULL;
ret = find_list(vm_config_groups, group, &local_err);
if (error_is_set(&local_err)) {
error_report("%s\n", error_get_pretty(local_err));
error_free(local_err);
}
return ret;
}
/*
“-device”参数初始化函数,qemu-kvm启动参数中定义的每一个“-device”都在device链表中,依次为这些“-device”调用device_init_func函数初始化它们。
*/
static int device_init_func(QemuOpts *opts, void *opaque)
{
DeviceState *dev;
dev = qdev_device_add(opts);
if (!dev)
return -1;
return 0;
}
/*
每一个“-device”对应一个QemuOpts结构体变量,“-device”实际上是指定使用某一驱动,因此这个结构体变量用来保存驱动的名字以及该驱动的各种启动参数(即“-device”后面的子参数), qdev_device_add函数初始化该驱动。
*/
DeviceState *qdev_device_add(QemuOpts *opts)
{
ObjectClass *obj;
DeviceClass *k;
const char *driver, *path, *id;
DeviceState *qdev;
BusState *bus;
/* 找到“-device”中指定的驱动的名字,opts中成员"driver"的值就是设备对应驱动的名字 */
driver = qemu_opt_get(opts, "driver");
if (!driver) {
qerror_report(QERR_MISSING_PARAMETER, "driver");
return NULL;
}
/* find driver */
obj = object_class_by_name(driver);
if (!obj) {
const char *typename = find_typename_by_alias(driver);
if (typename) {
driver = typename;
obj = object_class_by_name(driver);
}
}
if (!obj) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
return NULL;
}
k = DEVICE_CLASS(obj);
/* find bus */
path = qemu_opt_get(opts, "bus");
if (path != NULL) {
bus = qbus_find(path);
if (!bus) {
return NULL;
}
if (strcmp(object_get_typename(OBJECT(bus)), k->bus_type) != 0) {
qerror_report(QERR_BAD_BUS_FOR_DEVICE,
driver, object_get_typename(OBJECT(bus)));
return NULL;
}
} else {
bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
if (!bus) {
qerror_report(QERR_NO_BUS_FOR_DEVICE,
driver, k->bus_type);
return NULL;
}
}
if (qdev_hotplug && !bus->allow_hotplug) {
qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
return NULL;
}
if (!bus) {
bus = sysbus_get_default();
}
/* create device, set properties */
qdev = DEVICE(object_new(driver));
qdev_set_parent_bus(qdev, bus);
id = qemu_opts_id(opts);
if (id) {
qdev->id = id;
}
if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
qdev_free(qdev);
return NULL;
}
if (qdev->id) {
object_property_add_child(qdev_get_peripheral(), qdev->id,
OBJECT(qdev), NULL);
} else {
static int anon_count;
gchar *name = g_strdup_printf("device[%d]", anon_count++);
object_property_add_child(qdev_get_peripheral_anon(), name,
OBJECT(qdev), NULL);
g_free(name);
}
if (qdev_init(qdev) < 0) {
qerror_report(QERR_DEVICE_INIT_FAILED, driver);
return NULL;
}
qdev->opts = opts;
return qdev;
}
2. QemuOptsList类型的device链表中的成员是QemuOpts类型,一个QemuOpts变量代表一个qemu-kvm中的“-device参数”,device链表中QemuOpts的数量就等于“-device”的数量,初始化时,会循环为每一个QemuOpts变量调用device_init_func函数。
3. 因为“-device”参数还有子参数(如virtio-scsi-pci.hotplug=on/off),所以QemuOptsList也引导一个链表,链表节点是QemuOpt类型,链表的每一个节点就对应“-device”的一个子参数。
4.device链表中每一个QemuOptsList节点对应一个“-device”参数,QemuOptsList链表中的每一个节点对应该“-device”的一个子参数。这些信息都是从qemu-kvm的启动参数初始化而来的。该函数完成工作就是 在vm_config_groups中找到device链表成员并返回。
main()
{
...
/* init generic devices */
if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
exit(1);
...
}
/*
该函数完成工作就是 在vm_config_groups中找到device链表成员并返回。
*/
QemuOptsList *qemu_find_opts(const char *group)
{
QemuOptsList *ret;
Error *local_err = NULL;
ret = find_list(vm_config_groups, group, &local_err);
if (error_is_set(&local_err)) {
error_report("%s\n", error_get_pretty(local_err));
error_free(local_err);
}
return ret;
}
/*
“-device”参数初始化函数,qemu-kvm启动参数中定义的每一个“-device”都在device链表中,依次为这些“-device”调用device_init_func函数初始化它们。
*/
static int device_init_func(QemuOpts *opts, void *opaque)
{
DeviceState *dev;
dev = qdev_device_add(opts);
if (!dev)
return -1;
return 0;
}
/*
每一个“-device”对应一个QemuOpts结构体变量,“-device”实际上是指定使用某一驱动,因此这个结构体变量用来保存驱动的名字以及该驱动的各种启动参数(即“-device”后面的子参数), qdev_device_add函数初始化该驱动。
*/
DeviceState *qdev_device_add(QemuOpts *opts)
{
ObjectClass *obj;
DeviceClass *k;
const char *driver, *path, *id;
DeviceState *qdev;
BusState *bus;
/* 找到“-device”中指定的驱动的名字,opts中成员"driver"的值就是设备对应驱动的名字 */
driver = qemu_opt_get(opts, "driver");
if (!driver) {
qerror_report(QERR_MISSING_PARAMETER, "driver");
return NULL;
}
/* find driver */
obj = object_class_by_name(driver);
if (!obj) {
const char *typename = find_typename_by_alias(driver);
if (typename) {
driver = typename;
obj = object_class_by_name(driver);
}
}
if (!obj) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
return NULL;
}
k = DEVICE_CLASS(obj);
/* find bus */
path = qemu_opt_get(opts, "bus");
if (path != NULL) {
bus = qbus_find(path);
if (!bus) {
return NULL;
}
if (strcmp(object_get_typename(OBJECT(bus)), k->bus_type) != 0) {
qerror_report(QERR_BAD_BUS_FOR_DEVICE,
driver, object_get_typename(OBJECT(bus)));
return NULL;
}
} else {
bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
if (!bus) {
qerror_report(QERR_NO_BUS_FOR_DEVICE,
driver, k->bus_type);
return NULL;
}
}
if (qdev_hotplug && !bus->allow_hotplug) {
qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
return NULL;
}
if (!bus) {
bus = sysbus_get_default();
}
/* create device, set properties */
qdev = DEVICE(object_new(driver));
qdev_set_parent_bus(qdev, bus);
id = qemu_opts_id(opts);
if (id) {
qdev->id = id;
}
if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
qdev_free(qdev);
return NULL;
}
if (qdev->id) {
object_property_add_child(qdev_get_peripheral(), qdev->id,
OBJECT(qdev), NULL);
} else {
static int anon_count;
gchar *name = g_strdup_printf("device[%d]", anon_count++);
object_property_add_child(qdev_get_peripheral_anon(), name,
OBJECT(qdev), NULL);
g_free(name);
}
if (qdev_init(qdev) < 0) {
qerror_report(QERR_DEVICE_INIT_FAILED, driver);
return NULL;
}
qdev->opts = opts;
return qdev;
}
- qemu-kvm设备初始化
- qemu-kvm virtio 虚拟化-----Linux客户机 virtio设备初始化
- qemu-kvm virtio 虚拟化-----Linux客户机 virtio设备初始化
- qemu-kvm virtio 虚拟化-----Linux客户机 virtio设备初始化 (基于Qemu2.0.0 & kernel 3.10.0)
- Qemu创建KVM虚拟机内存初始化流程
- android qemu-kvm i8254 pit虚拟设备
- kvm+qemu
- QEMU KVM
- QEMU-KVM
- Kvm-Qemu
- qemu, kvm和qemu-kvm
- QEMU-KVM的初始化与客户系统的执行
- KVM(qemu--kvm)
- QEMU KVM Libvirt手册(8): 半虚拟化设备virtio
- android qemu-kvm i8259 中断控制器虚拟设备
- qemu中KVM硬件虚拟化的初始化分析 (tcg、xen、kvm、qtest)(转)
- QEMU 与QEMU-KVM区别
- QEMU 与QEMU-KVM区别
- 建立框架窗口并输出语句
- 我的学习计划1
- error: expected declaration specifiers before ‘return’
- 使用 HOOK 实现 Outlook Express 工具条
- 查询存储过程,数据库对象的创建历史
- qemu-kvm设备初始化
- 要考研,先要做到不比钱
- 高效遍历HashMap
- C#中Invoke与BeginInvoke在线程中的执行解析
- nginx 301跳转到带www域名方法rewrite
- jhjh
- cocos2d-x游戏开发(十三)细说回调函数
- qemu-type-object-initialize
- HDU 2795 Billboard