void arch_init(start_info_t *si) { /* Copy the start_info struct to a globally-accessible area. */ /* WARN: don't do printk before here, it uses information from shared_info. Use xprintk instead. */ memcpy(&start_info, si, sizeof(*si)); /* set up minimal memory infos */ phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; /* Grab the shared_info pointer and put it in a safe place. */ HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); /* Set up event and failsafe callback addresses. */ #ifdef __i386__ HYPERVISOR_set_callbacks( __KERNEL_CS, (unsigned long)hypervisor_callback, __KERNEL_CS, (unsigned long)failsafe_callback); #else HYPERVISOR_set_callbacks( (unsigned long)hypervisor_callback, (unsigned long)failsafe_callback, 0); #endif }
void arch_fini(void) { #ifdef __i386__ HYPERVISOR_set_callbacks(0, 0, 0, 0); #else HYPERVISOR_set_callbacks(0, 0, 0); #endif }
void __init xen_arch_setup(void) { int ret; static const struct callback_register __initconst event = { .type = CALLBACKTYPE_event, .address = CALLBACK_ADDR(hypervisor_callback) }; static const struct callback_register __initconst failsafe = { .type = CALLBACKTYPE_failsafe, .address = CALLBACK_ADDR(failsafe_callback) }; #ifdef CONFIG_X86_64 static const struct callback_register __initconst syscall = { .type = CALLBACKTYPE_syscall, .address = CALLBACK_ADDR(system_call) }; #endif static const struct callback_register __initconst nmi_cb = { .type = CALLBACKTYPE_nmi, .address = CALLBACK_ADDR(nmi) }; ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event); if (ret == 0) ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); #ifdef CONFIG_X86_64 if (ret == 0) ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall); #endif #if CONFIG_XEN_COMPAT <= 0x030002 #ifdef CONFIG_X86_32 if (ret == -ENOSYS) ret = HYPERVISOR_set_callbacks( event.address.cs, event.address.eip, failsafe.address.cs, failsafe.address.eip); #else ret = HYPERVISOR_set_callbacks( event.address, failsafe.address, syscall.address); #endif #endif BUG_ON(ret); ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb); #if CONFIG_XEN_COMPAT <= 0x030002 if (ret == -ENOSYS) { static struct xennmi_callback __initdata cb = { .handler_address = (unsigned long)nmi }; HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); } #endif }
/* Main kernel entry point, called by trampoline */ void start_kernel(start_info_t * start_info) { /* Define hypervisor upcall entry points */ HYPERVISOR_set_callbacks( FLAT_KERNEL_CS, (unsigned long)hypervisor_callback, FLAT_KERNEL_CS, (unsigned long)failsafe_callback); /* Map the shared info page */ HYPERVISOR_update_va_mapping((unsigned long) shared_info, __pte(start_info->shared_info), UVMF_INVLPG); /* Initialise the console */ console_init(start_info); /* Write a message to check that it worked */ console_write("Hello world!\n\r"); console_write("Xen magic string: "); console_write(start_info->magic); console_write("\n\r"); /* Set up the XenStore driver */ xenstore_init(start_info); /* Test the store */ xenstore_test(); /* Flush the console buffer */ console_flush(); /* Exit, since we don't know how to do anything else */ }
/* Initialise the event handlers */ void init_events(void) { /* Set the event delivery callbacks */ #ifdef __i386__ HYPERVISOR_set_callbacks( FLAT_KERNEL_CS, (unsigned long)hypervisor_callback, FLAT_KERNEL_CS, (unsigned long)failsafe_callback); #elif defined (__x86_64__) HYPERVISOR_set_callbacks( (unsigned long)hypervisor_callback, (unsigned long)failsafe_callback, 0); #else #error "Unsupported architecture" #endif /* Set all handlers to ignore, and mask them */ for(unsigned int i=0 ; i<NUM_CHANNELS ; i++) { handlers[i] = EVT_IGN; SET_BIT(i,shared_info.evtchn_mask[0]); } /* Allow upcalls. */ shared_info.vcpu_info[0].evtchn_upcall_mask = 0; }
CAMLprim value stub_hypervisor_suspend(value unit) { CAMLparam0(); int cancelled; printk("WARNING: stub_hypervisor_suspend not yet implemented\n"); cancelled = 1; #if 0 /* Turn the store and console mfns to pfns - required because xc_domain_restore uses these values */ start_info.store_mfn = mfn_to_pfn(start_info.store_mfn); start_info.console.domU.mfn = mfn_to_pfn(start_info.console.domU.mfn); /* canonicalize_pagetables can't cope with pagetable entries that are outside of the guest's mfns, so we must unmap anything outside of our space */ unmap_shared_info(); /* Actually do the suspend. When this function returns 0, we've been resumed */ cancelled = HYPERVISOR_suspend(virt_to_mfn(&start_info)); if(cancelled) { start_info.store_mfn = pfn_to_mfn(start_info.store_mfn); start_info.console.domU.mfn = pfn_to_mfn(start_info.console.domU.mfn); } /* Reinitialise several things */ trap_init(); init_events(); /* ENABLE EVENT DELIVERY. This is disabled at start of day. */ local_irq_enable(); setup_xen_features(); HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); /* Set up event and failsafe callback addresses. */ HYPERVISOR_set_callbacks( (unsigned long)hypervisor_callback, (unsigned long)failsafe_callback, 0); init_time(); arch_rebuild_p2m(); unmask_evtchn(start_info.console.domU.evtchn); unmask_evtchn(start_info.store_evtchn); #endif CAMLreturn(Val_int(cancelled)); }
void xen_dbglow_init() { start_info_t *si; #if 0 int i; #endif si = &xen_start_info; HYPERVISOR_set_callbacks( __KERNEL_CS, (unsigned long)hypervisor_callback, __KERNEL_CS, (unsigned long)failsafe_callback); trap_init(); /* __sti(); */ /* print out some useful information */ printk(version); printk("start_info: %p\n", si); printk(" nr_pages: %lu", si->nr_pages); printk(" shared_inf: %p (was %p)\n", HYPERVISOR_shared_info, si->shared_info); printk(" pt_base: %p", (void *)si->pt_base); printk(" mod_start: 0x%lx\n", si->mod_start); printk(" mod_len: %lu\n", si->mod_len); #if 0 printk(" net_rings: "); for (i = 0; i < MAX_DOMAIN_VIFS; i++) { if (si->net_rings[i] == 0) break; printk(" %lx", si->net_rings[i]); }; printk("\n"); printk(" blk_ring: 0x%lx\n", si->blk_ring); #endif printk(" dom_id: %d\n", si->dom_id); printk(" flags: 0x%lx\n", si->flags); printk(" cmd_line: %s\n", si->cmd_line ? (const char *)si->cmd_line : "NULL"); }
void __init xen_arch_setup(void) { struct physdev_set_iopl set_iopl; int rc; HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); if (!xen_feature(XENFEAT_auto_translated_physmap)) HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3); HYPERVISOR_set_callbacks(__KERNEL_CS, (unsigned long)xen_hypervisor_callback, __KERNEL_CS, (unsigned long)xen_failsafe_callback); set_iopl.iopl = 1; rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl); if (rc != 0) printk(KERN_INFO "physdev_op failed %d\n", rc); #ifdef CONFIG_ACPI if (!(xen_start_info->flags & SIF_INITDOMAIN)) { printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); disable_acpi(); } #endif memcpy(boot_command_line, xen_start_info->cmd_line, MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ? COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE); pm_idle = xen_idle; #ifdef CONFIG_SMP /* fill cpus_possible with all available cpus */ xen_fill_possible_map(); #endif paravirt_disable_iospace(); fiddle_vdso(); }
// 从汇编阶段,进入C语言的阶段,传承了Unix的典型思想 // 汇编只负责引导和必要的硬件打交道的阶段 void start_ling(start_info_t *si) { //-------- init phase 1 -------- // //start_info包含的是xen的初始化信息 //是xen在启动GuestOS的时候,放在特定的地方 memcpy(&start_info, si, sizeof(*si)); phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; HYPERVISOR_update_va_mapping((unsigned long)&shared_info, __pte(start_info.shared_info | 7), UVMF_INVLPG); HYPERVISOR_shared_info = &shared_info; //进行时钟初始化 time_init(); // sets start_of_day_wall_clock // use the time value to seed PRNG mt_seed(start_of_day_wall_clock); #if defined(__x86_64__) HYPERVISOR_set_callbacks(0, 0, 0); #else /* __x86_64__ */ HYPERVISOR_set_callbacks(0, 0, 0, 0); #endif mm_init(start_info.nr_pages, start_info.pt_base, start_info.nr_pt_frames); nalloc_init(); events_init(); grants_init(); console_init(mfn_to_virt(start_info.console.domU.mfn), start_info.console.domU.evtchn); xenstore_init(mfn_to_virt(start_info.store_mfn), start_info.store_evtchn); xenstore_read("name", my_domain_name, sizeof(my_domain_name)); //print_xenstore_values(); if (disk_vbd_is_present()) disk_init(); lwip_init(); netfe_init(); //-------- init phase 2 -------- // if (nalloc_no_memory()) fatal_error("init phase 2: no memory"); sys_stats_init(); atoms_init(); embed_init(); code_base_init(); scheduler_init(); ets_init(); pcre_init(); counters_init(); //print_start_info(); //print_xenmem_info(); //run_alloc_tests(); //run_mm_tests(); //print_xenstore_values(); //run_bignum_tests(); //printk("\r\nLing %s is here\r\n", quote_and_expand(LING_VER)); proc_main(0); // preliminary run spawn_init_start(start_info.cmd_line); //while (1) // HYPERVISOR_sched_op(SCHEDOP_block, 0); /* UNREACHABLE */ }