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 + -
显示快捷键?