hva的创建过程
?其創建流程如下圖所示:
?ppc架構的處理器的在mac_newworld.c文件中ppc_core99_init函數中調用memory_region_allocate_system_memory函數創建ram,ram屬于實體MemoryRegion,有自己的內存(從QEMU進程的中分配內存空間)。源代碼分析如下:
memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,const char *name,uint64_t ram_size) {uint64_t addr = 0;int i;if (nb_numa_nodes == 0 || !have_memdevs) {allocate_system_memory_nonnuma(mr, owner, name, ram_size);//hva內存的創建通過該函數完 //成,對于其它代碼不做解析return;}…… }?在下面函數中可以從文件恢復hva內存,也可以直接分配hva內存,memory_region_init_ram_from_file函數用于從文件恢復,而memory_region_init_ram_nomigrate用于分配內存。
static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,const char *name,uint64_t ram_size) {if (mem_path) { #ifdef __linux__Error *err = NULL;memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, 0,mem_path, &err); //從文件中恢復hvaif (err) {error_report_err(err);if (mem_prealloc) {exit(1);}error_report("falling back to regular RAM allocation.");/* Legacy behavior: if allocation failed, fall back to* regular RAM allocation.*/mem_path = NULL;memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal);} #elsefprintf(stderr, "-mem-path not supported on this host\n");exit(1); #endif} else {memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal);//分配hva內存}vmstate_register_ram_global(mr); }?以下主要分析memory_region_init_ram_nomigrate函數分配內存
void memory_region_init_ram_nomigrate(MemoryRegion *mr,Object *owner,const char *name,uint64_t size,Error **errp) {memory_region_init_ram_shared_nomigrate(mr, owner, name, size, false, errp); } void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,Object *owner,const char *name,uint64_t size,bool share,Error **errp) {Error *err = NULL;memory_region_init(mr, owner, name, size);//創建RAM的memoryregion(QOM的創建過程)mr->ram = true; //完成MemoryRegion的成員變量的初始化mr->terminates = true;mr->destructor = memory_region_destructor_ram;mr->ram_block = qemu_ram_alloc(size, share, mr, &err);//hva內存的分配通過該函數完成mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;if (err) {mr->size = int128_zero();object_unparent(OBJECT(mr));error_propagate(errp, err);} } RAMBlock *qemu_ram_alloc(ram_addr_t size, bool share,MemoryRegion *mr, Error **errp) {return qemu_ram_alloc_internal(size, size, NULL, NULL, false,share, mr, errp); }?創建RamBlock,并完成Ram的MemoryRegion與RamBlock的連接
static RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,void (*resized)(const char*,uint64_t length,void *host),void *host, bool resizeable, bool share,MemoryRegion *mr, Error **errp) {RAMBlock *new_block;Error *local_err = NULL;size = HOST_PAGE_ALIGN(size);max_size = HOST_PAGE_ALIGN(max_size);new_block = g_malloc0(sizeof(*new_block));//動態創建RAMBlocknew_block->mr = mr; //完成各個元素的初始化new_block->resized = resized;new_block->used_length = size;new_block->max_length = max_size;assert(max_size >= size);new_block->fd = -1;new_block->page_size = getpagesize(); //獲取系統的頁大小new_block->host = host;if (host) {new_block->flags |= RAM_PREALLOC;}if (resizeable) {new_block->flags |= RAM_RESIZEABLE;}ram_block_add(new_block, &local_err, share);//通過該函數完成hva的分配if (local_err) {g_free(new_block);error_propagate(errp, local_err);return NULL;}return new_block; } static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared) {RAMBlock *block;RAMBlock *last_block = NULL;ram_addr_t old_ram_size, new_ram_size;Error *err = NULL;old_ram_size = last_ram_page();qemu_mutex_lock_ramlist();new_block->offset = find_ram_offset(new_block->max_length);if (!new_block->host) {if (xen_enabled()) {xen_ram_alloc(new_block->offset, new_block->max_length,new_block->mr, &err);if (err) {error_propagate(errp, err);qemu_mutex_unlock_ramlist();return;}} else {new_block->host = phys_mem_alloc(new_block->max_length,&new_block->mr->align, shared);//該函數完成 //hva的創建…… }?phys_mem_alloc函數在exec.c文件中指向qemu_anon_ram_alloc函數,該函數調用系統函數VirtualAlloc在進程中創建內存。
?
?
?
?
總結
- 上一篇: iptable命令参数详解
- 下一篇: 【译】Unity3D Shader 新手