xensetup.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 743 行 · 第 1/2 页
C
743 行
/* Be sure the struct shared_info size is <= XSI_SIZE. */ BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE); /* Kernel may be relocated by EFI loader */ xen_pstart = ia64_tpa(KERNEL_START); running_on_sim = is_platform_hp_ski(); early_setup_arch(&cmdline); /* We initialise the serial devices very early so we can get debugging. */ if (running_on_sim) hpsim_serial_init(); else { ns16550_init(0, &ns16550_com1); ns16550_init(1, &ns16550_com2); } serial_init_preirq();#ifdef CONFIG_VGA /* Plug in a default VGA mode */ vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3; vga_console_info.u.text_mode_3.font_height = 16; /* generic VGA? */ vga_console_info.u.text_mode_3.cursor_x = ia64_boot_param->console_info.orig_x; vga_console_info.u.text_mode_3.cursor_y = ia64_boot_param->console_info.orig_y; vga_console_info.u.text_mode_3.rows = ia64_boot_param->console_info.num_rows; vga_console_info.u.text_mode_3.columns = ia64_boot_param->console_info.num_cols;#endif init_console(); if (running_on_sim || ia64_boot_param->domain_start == 0 || ia64_boot_param->domain_size == 0) { /* This is possible only with the old elilo, which does not support a vmm. Fix now, and continue without initrd. */ printk ("Your elilo is not Xen-aware. Bootparams fixed\n"); ia64_boot_param->domain_start = ia64_boot_param->initrd_start; ia64_boot_param->domain_size = ia64_boot_param->initrd_size; ia64_boot_param->initrd_start = 0; ia64_boot_param->initrd_size = 0; } printk("Xen command line: %s\n", saved_command_line); /* * Test if the boot allocator bitmap will overflow xenheap_size. If * so, continue to bump it up until we have at least a minimum space * for the actual xenheap. */ max_page = efi_get_max_addr() >> PAGE_SHIFT; while ((max_page >> 3) > xenheap_size - (XENHEAP_MEGABYTES_MIN << 20)) xenheap_size <<= 1; BUG_ON(xenheap_size > (XENHEAP_MEGABYTES_MAX << 20)); xenheap_phys_end = xen_pstart + xenheap_size; printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n", xen_pstart, xenheap_phys_end); xen_patch_kernel(); kern_md = md = efi_get_md(xen_pstart); md_end = __pa(ia64_imva(&_end)); relo_start = xenheap_phys_end; /* * Scan through the memory descriptors after the kernel * image to make sure we have enough room for the xenheap * area, pushing out whatever may already be there. */ while (relo_start + relo_size >= md_end) { md = efi_get_md(md_end); if (md == NULL) { printk("no room to move loader data. skip moving loader data\n"); goto skip_move; } md_end = MD_END(md); if (relo_start < md->phys_addr) relo_start = md->phys_addr; if (!is_xenheap_usable_memory(md)) { /* Skip this area */ if (md_end > relo_start) relo_start = md_end; continue; } /* * The dom0 kernel or initrd could overlap, reserve space * at the end to relocate them later. */ if (md->type == EFI_LOADER_DATA) { /* Test for ranges we're not prepared to move */ if (!md_overlap_with_boot_param(md)) relo_size += MD_SIZE(md); /* If range overlaps the end, push out the relocation start */ if (md_end > relo_start) relo_start = md_end; } } last_md = md; relo_start = md_end - relo_size; relo_end = relo_start + relo_size; md_end = __pa(ia64_imva(&_end)); /* * Move any relocated data out into the previously found relocation * area. Any extra memory descriptrs are moved out to the end * and set to zero pages. */ for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) { md_end = MD_END(md); if (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) { unsigned long relo_offset; if (md_overlaps(md, ia64_boot_param->domain_start)) { relo_offset = ia64_boot_param->domain_start - md->phys_addr; printk("Moving Dom0 kernel image: 0x%lx -> 0x%lx (%ld KiB)\n", ia64_boot_param->domain_start, relo_start + relo_offset, ia64_boot_param->domain_size >> 10); ia64_boot_param->domain_start = relo_start + relo_offset; } if (ia64_boot_param->initrd_size && md_overlaps(md, ia64_boot_param->initrd_start)) { relo_offset = ia64_boot_param->initrd_start - md->phys_addr; printk("Moving Dom0 initrd image: 0x%lx -> 0x%lx (%ld KiB)\n", ia64_boot_param->initrd_start, relo_start + relo_offset, ia64_boot_param->initrd_size >> 10); ia64_boot_param->initrd_start = relo_start + relo_offset; } memcpy(__va(relo_start), __va(md->phys_addr), MD_SIZE(md)); relo_start += MD_SIZE(md); } if (md == last_md) break; } /* Trim the last entry */ md->num_pages -= (relo_size >> EFI_PAGE_SHIFT);skip_move: reserve_memory(); /* first find highest page frame number */ max_page = 0; efi_memmap_walk(find_max_pfn, &max_page); printk("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page); efi_print(); /* * later [__init_begin, __init_end) will be freed up as xen heap * so that struct domain might be allocated from the init area * which is < xen_heap_start. so we can't simply set * xen_pickle_offset = xen_heap_start. */ xen_pickle_offset = ia64_imva(__init_begin); xen_heap_start = memguard_init(ia64_imva(&_end)); printk("Before xen_heap_start: %p\n", xen_heap_start); xen_heap_start = __va(init_boot_allocator(__pa(xen_heap_start))); printk("After xen_heap_start: %p\n", xen_heap_start); efi_memmap_walk(filter_rsvd_memory, init_boot_pages); efi_memmap_walk(xen_count_pages, &nr_pages); printk("System RAM: %luMB (%lukB)\n", nr_pages >> (20 - PAGE_SHIFT), nr_pages << (PAGE_SHIFT - 10)); total_pages = nr_pages; init_frametable(); trap_init(); /* process SAL system table */ /* must be before any pal/sal call */ BUG_ON(efi.sal_systab == EFI_INVALID_TABLE_ADDR); ia64_sal_init(__va(efi.sal_systab)); /* early_setup_arch() maps PAL code. */ identify_vmx_feature(); /* If vmx feature is on, do necessary initialization for vmx */ if (vmx_enabled) xen_heap_start = vmx_init_env(xen_heap_start, xenheap_phys_end); /* allocate memory for percpu area * per_cpu_init() called from late_set_arch() is called after * end_boot_allocate(). It's too late to allocate memory in * xenva. */ xen_heap_start = per_cpu_allocate(xen_heap_start, xenheap_phys_end); heap_desc.xen_heap_start = xen_heap_start; heap_desc.xenheap_phys_end = xenheap_phys_end; heap_desc.kern_md = kern_md; efi_memmap_walk(&init_xenheap_mds, &heap_desc); printk("Xen heap: %luMB (%lukB)\n", (xenheap_phys_end-__pa(xen_heap_start)) >> 20, (xenheap_phys_end-__pa(xen_heap_start)) >> 10); end_boot_allocator(); softirq_init(); late_setup_arch(&cmdline); scheduler_init(); idle_vcpu[0] = (struct vcpu*) ia64_r13; idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0); if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) ) BUG(); alloc_dom_xen_and_dom_io(); setup_per_cpu_areas(); mem_init(); local_irq_disable(); init_IRQ (); init_xen_time(); /* initialise the time */ timer_init(); rcu_init();#ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);#endif#ifdef CONFIG_SMP if ( opt_nosmp ) { max_cpus = 0; smp_num_siblings = 1; //boot_cpu_data.x86_num_cores = 1; } /* A vcpu is created for the idle domain on every physical cpu. Limit the number of cpus to the maximum number of vcpus. */ if (max_cpus > MAX_VIRT_CPUS) max_cpus = MAX_VIRT_CPUS; smp_prepare_cpus(max_cpus); /* We aren't hotplug-capable yet. */ for_each_cpu ( i ) cpu_set(i, cpu_present_map); /* Enable IRQ to receive IPI (needed for ITC sync). */ local_irq_enable();printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus); for_each_present_cpu ( i ) { if ( num_online_cpus() >= max_cpus ) break; if ( !cpu_online(i) ) { rcu_online_cpu(i); __cpu_up(i); } } local_irq_disable(); printk("Brought up %ld CPUs\n", (long)num_online_cpus()); smp_cpus_done(max_cpus);#endif initialise_gdb(); /* could be moved earlier */ do_initcalls(); sort_main_extable(); init_rid_allocator (); local_irq_enable(); if (opt_xencons) { initialize_keytable(); if (ns16550_com1_gsi) { if (opt_xencons_poll || iosapic_register_intr(ns16550_com1_gsi, ns16550_com1_polarity, ns16550_com1_trigger) < 0) { ns16550_com1.irq = 0; ns16550_init(0, &ns16550_com1); } } serial_init_postirq(); } expose_p2m_init(); /* Create initial domain 0. */ dom0 = domain_create(0, 0, DOM0_SSIDREF); if (dom0 == NULL) panic("Error creating domain 0\n"); domain_set_vhpt_size(dom0, dom0_vhpt_size_log2); dom0_vcpu0 = alloc_vcpu(dom0, 0, 0); if (dom0_vcpu0 == NULL || vcpu_late_initialise(dom0_vcpu0) != 0) panic("Cannot allocate dom0 vcpu 0\n"); dom0->is_privileged = 1; dom0->target = NULL; /* * We're going to setup domain0 using the module(s) that we stashed safely * above our heap. The second module, if present, is an initrd ramdisk. */ dom0_memory_start = (unsigned long) __va(ia64_boot_param->domain_start); dom0_memory_size = ia64_boot_param->domain_size; dom0_initrd_start = (unsigned long) __va(ia64_boot_param->initrd_start); dom0_initrd_size = ia64_boot_param->initrd_size; if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size, dom0_initrd_start,dom0_initrd_size, 0) != 0) panic("Could not set up DOM0 guest OS\n"); if (!running_on_sim && !IS_MEDUSA()) // slow on ski and pages are pre-initialized to zero scrub_heap_pages(); init_trace_bufs(); if (opt_xencons) { console_endboot(); serial_endboot(); } domain0_ready = 1; domain_unpause_by_systemcontroller(dom0); init_done();}void arch_get_xen_caps(xen_capabilities_info_t *info){ /* Interface name is always xen-3.0-* for Xen-3.x. */ int major = 3, minor = 0; char s[32]; (*info)[0] = '\0'; snprintf(s, sizeof(s), "xen-%d.%d-ia64 ", major, minor); safe_strcat(*info, s); snprintf(s, sizeof(s), "xen-%d.%d-ia64be ", major, minor); safe_strcat(*info, s); if (vmx_enabled) { snprintf(s, sizeof(s), "hvm-%d.%d-ia64 ", major, minor); safe_strcat(*info, s); snprintf(s, sizeof(s), "hvm-%d.%d-ia64-sioemu ", major, minor); safe_strcat(*info, s); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?