博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
qemu-sysbus
阅读量:4095 次
发布时间:2019-05-25

本文共 6980 字,大约阅读时间需要 23 分钟。

qemu系统总线——sysbus在实际的物理机器上,CPU与外接连接的总线被称之为Host Bus。即系统总线,SysBus。在qemu中,对sysbus总线进行了模拟,实现在hw/core/sysbus.c文件中。type_init(sysbus_register_types);static void sysbus_register_types(void){
type_register_static(&system_bus_info); type_register_static(&sysbus_device_type_info);}通过对type_init的分析可以知道,上边的代码是将struct TypeImpl结构体对象system_bus_info以及sysbus_device_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,}static const TypeInfo sysbus_device_type_info = {
.name = TYPE_SYS_BUS_DEVICE, .parent = TYPE_DEVICE, .instance_size = sizeof(SysBusDevice), .abstract = true, .class_size = sizeof(SysBusDeviceClass), .class_init = sysbus_device_class_init,};在qemu中,系统总线由全局变量main_system_bus来表示。main_system_bus的创建由main_system_bus_create函数来完成。如下:static BusState *main_system_bus;#define TYPE_SYSTEM_BUS "System"static void main_system_bus_create(void){
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结构体来抽象,如下:struct BusState {
Object obj; DeviceState *parent; char *name; HotPlugHandler *hotplug_handler; int max_index; bool realized; int num_children; QTAILQ_HEAD(, BusChild) children; QLIST_ENTRY(BusState) sibling; ResettableState reset;};typedef struct BusState BusState;创建总线的主要函数为qbus_create_inplace,如下:void qbus_create_inplace(void *bus, size_t size, const char *typename, DeviceState *parent, const char *name){
object_initialize(bus, size, typename); qbus_init(bus, parent, name);}上边代码主要完成了两部分的工作,一部分为main_system_bus所对应的BusClass的初始化过程;另外一部分为main_system_bus所对应的BusState的初始化过程。void object_initialize(void *data, size_t size, const char *typename){
TypeImpl *type = type_get_by_name(typename); //获取名为System的TypeImpl,即上边所定义的system_bus_info结构体对象 if (!type) {
error_report("missing object type '%s'", typename); abort(); } object_initialize_with_type(data, size, type); //根据system_bus_info结构体对象来初始化main_system_bus中的成员信息}static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type){
type_initialize(type); //该函数主要用来创建Object所需的 ObjectClass结构体对象,并调用type对象中所指向的class_init指针函数来对ObjectClass对象进行初始化。 g_assert(type->instance_size >= sizeof(Object)); g_assert(type->abstract == false); g_assert(size >= type->instance_size); memset(obj, 0, type->instance_size); obj->class = type->class; object_ref(obj); object_class_property_init_all(obj); obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, object_property_free); object_init_with_type(obj, type); object_post_init_with_type(obj, type);}BusClass的初始化中,主要对BusClass中print_dev以及get_fw_dev_path变量的赋值。注意,Object对象中的properties属性为哈希表指针,关于Object对象的所有属性都会以键值对的形式存放在该哈希表中。static void qbus_init(BusState *bus, DeviceState *parent, const char *name){
const char *typename = object_get_typename(OBJECT(bus)); //return Object->ObjectClass->TypeImpl->name; BusClass *bc; int i, bus_id; bus->parent = parent; if (name) {
bus->name = g_strdup(name); } else if (bus->parent && bus->parent->id) {
bus_id = bus->parent->num_child_bus; bus->name = g_strdup_printf("%s.%d", bus->parent->id, bus_id); } else {
bc = BUS_GET_CLASS(bus); bus_id = bc->automic_ids++; bus->name = g_strdup_printf("%s.%d", typename, bus_id); for (i = 0; bus->name[i]; i++) {
bus->name[i] = qemu_tolower(bus->name[i]); } } if (bus->parent) {
QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling); bus->parent->num_child_bus++; object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus)); object_unref(OBJECT(bus)); } else {
assert(bus == sysbus_get_default()); }}BusState的初始化,主要完成对变量name的赋值,以及将当前总线插入上级总线的子集链表中。qemu用ObjectProperty结构体来保存Object结构体对象的属性。ObjectProperty *object_property_add_child(Object *obj, const char *name, Object *child){
return object_property_try_add_child(obj, name, child, &error_abort);}ObjectProperty *object_property_try_add_child(Object *obj, const char *name, Object *child, Error *errp){
g_autofree char *type = NULL; ObjectProperty *op; assert(!child->parent); type = g_strdup_printf("child<%s>", object_get_typename(child)); op = object_property_try_add(obj, name, type, object_get_child_property, NULL, object_finalize_child_property, child, errp); //创建ObjectProperty结构体对象并存储信息 if (!op) {
return NULL; } op->resolve = object_resolve_child_property; object_ref(child); child->parent = obj; //设置子节点的父节点 return op;}ObjectProperty *object_property_try_add(Object *obj, const char *name, const char *type, ObjectPropertyAccessor *get, ObjectPropertyAccessor *set, ObjectPropertyRelease *release, void *opaque, Error **errp){
//假设当前添加的属性名为“sysbus” ObjectProperty *prop; size_t name_len = strlen(name); //name_len的长度此时为6。 if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) {
//此时的判断条件是不成立的,因此并不会进入该条件中执行操作 int i; ObjectProperty *ret; char *name_no_array = g_strdup(name); name_no_array[name_len - 3] = '\0'; for (i = 0; ; i++) {
char *full_name = g_strdup_printf("%s[%d]", name_no_array, i); ret = object_property_try_add(obj, full_name, type, get, set, release, opaque, NULL); g_free(full_name); if (ret) {
break; } } g_free(name_no_array); return ret; } if (object_property_find(obj, name, NULL) != NULL) {
//从Object对象中查找与name对应的属性 error_setg(errp, "attempt to add suplicate property '%s' to object (type '%s')", name, object_get_typename(obj)); return NULL; } prop = g_malloc0(sizeof(*prop)); //申请ObjectProperty结构体空间 prop->name = g_strdup(name); prop->type = g_strdup(type); prop->get = get; prop->set = set; prop->release = release; prop->opaque = opaque; //对该结构体进行赋值操作,前两步为字符操作,后三步为指针函数操作 g_hash_table_insert(obj->properties, prop->name, prop); //将该结构体对象插入obj->properties哈希表中 return prop;}ObjectProperty *object_property_find(Object *obj, const char *name, Error *errp){
ObjectProperty *prop; ObjectClass *klass = object_get_class(obj); //获取object对应的objectclass prop = object_class_property_find(klass, name, NULL); //获取ObjectProperty结构体对象 if (prop) {
return prop; } prop = g_hash_table_lookup(obj->properties, name); //查找name所对应的ObjectProperty结构体对象 if (prop) {
return prop; } error_setg(errp, "Property '.%s' not found", name); return NULL;}注意,上边的两次查找是不同的,第一次是从ObjectClass中查找,第二次是从Object中查找ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name, Error **errp){
ObjectProperty *prop; ObjectClass *parent_klass; parent_klass = object_class_get_parent(klass); if (parent_klass) {
prop = object_class_property_find(parent_klass, name, NULL); if (prop) {
return prop; } } prop = g_hash_table_lookup(klass->properties, name); //从ObjectClass中properties变量指向的哈希表中获取name所对应的ObjectProperty结构体对象 if (!prop) {
error_setg(errp, "Property '.%s' not found", name); } return prop;}

转载地址:http://jpxii.baihongyu.com/

你可能感兴趣的文章
(python版)《剑指Offer》JZ02:替换空格
查看>>
JSP/Servlet——MVC设计模式
查看>>
使用JSTL
查看>>
Java 8新特性:Stream API
查看>>
管理用户状态——Cookie与Session
查看>>
最受欢迎的前端框架Bootstrap 入门
查看>>
JavaScript编程简介:DOM、AJAX与Chrome调试器
查看>>
通过Maven管理项目依赖
查看>>
通过Spring Boot三分钟创建Spring Web项目
查看>>
Spring的IoC(依赖注入)原理
查看>>
Guava快速入门
查看>>
Java编程基础:static的用法
查看>>
Java编程基础:抽象类和接口
查看>>
Java编程基础:异常处理
查看>>
Java编程基础:了解面向对象
查看>>
新一代Java模板引擎Thymeleaf
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
Spring Boot构建简单的微博应用
查看>>
Spring处理表单提交
查看>>
Spring MVC异常处理
查看>>