/* 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 */ }
char* clickos_read_handler(int domid, char *elem, char *attr) { char *ctrlpath = NULL, *elempath = NULL; char *rpath = NULL, *wpath = NULL; char *value; int err; unsigned int len = 0; struct pollfd fds[1]; if (!xs) { xenstore_init(domid); } asprintf(&ctrlpath, "/local/domain/%d/clickos/0/control", domid); asprintf(&elempath, "/local/domain/%d/clickos/0/elements", domid); asprintf(&wpath, "%s/read/%s/%s", ctrlpath, elem, attr); asprintf(&rpath, "%s/%s/%s", elempath, elem, attr); th = xs_transaction_start(xs); xenstore_write(wpath, " "); xs_transaction_end(xs, th, 0); err = xs_watch(xs, rpath, "lock"); if (!err) { printf("Error setting a watch\n"); return NULL; } fds[0].fd = xs_fileno(xs); fds[0].events = (POLLIN); while (len <= 0) { if (poll(fds, 1, 1000) <= 0) { continue; } retry_wh: th = xs_transaction_start(xs); //value = xenstore_read(rpath); value = xs_read(xs, XBT_NULL, rpath, &len); //printf("read: len %d value %s\n", len, value); if (!xs_transaction_end(xs, th, 0)) { if (errno == EAGAIN) goto retry_wh; } usleep(5000); } err = xs_unwatch(xs, rpath, "lock"); th = xs_transaction_start(xs); xs_write(xs, th, rpath, "", 0); err = xs_transaction_end(xs, th, 0); return value; }
char* clickos_write_handler(int domid, char *elem, char *attr, char *value) { char *elempath = NULL; char *wpath = NULL; if (!xs) { xenstore_init(domid); } asprintf(&elempath, "/local/domain/%d/clickos/0/elements", domid); asprintf(&wpath, "%s/%s/%s", elempath, elem, attr); xenstore_write(wpath, value); return 0; }
int clickos_stop(int domid, int configid) { char *statuspath = NULL; if (!xs) { xenstore_init(domid); } asprintf(&statuspath, "/local/domain/%d/clickos/%d/status", domid, configid); retry_stop: th = xs_transaction_start(xs); xenstore_write(statuspath, "Halted"); if (!xs_transaction_end(xs, th, 0)) { if (errno == EAGAIN) goto retry_stop; } return 0; }
int main(int argc, char *argv[]) { int ret = 0; #ifndef RUN_STANDALONE openlog("xcpmd", 0, LOG_DAEMON); daemonize(); #endif xcpmd_log(LOG_INFO, "Starting XenClient power management daemon.\n"); //Initialize libevent library event_init(); //Initialize xenstore. if (xenstore_init() == -1) { xcpmd_log(LOG_ERR, "Unable to init xenstore\n"); return -1; } // Allow everyone to read from /pm/ in xenstore xenstore_rm("/pm"); xenstore_mkdir("/pm"); xenstore_chmod("r0", 1, "/pm"); initialize_platform_info(); xcpmd_log(LOG_INFO, "Starting DBUS server.\n"); if (xcpmd_dbus_initialize() == -1) { xcpmd_log(LOG_ERR, "Failed to initialize DBUS server\n"); goto xcpmd_err; } xcpmd_log(LOG_INFO, "Starting ACPI events monitor.\n"); if (acpi_events_initialize() == -1) { xcpmd_log(LOG_ERR, "Failed to initialize ACPI events monitor\n"); goto xcpmd_err; } // Load modules xcpmd_log(LOG_INFO, "Loading modules.\n"); if (init_modules() == -1) { xcpmd_log(LOG_ERR, "Failed to load all modules\n"); goto xcpmd_err; } //This relies on both acpi-events and acpi-module having been initialized xcpmd_log(LOG_INFO, "Initializing ACPI state.\n"); acpi_initialize_state(); // Load policy xcpmd_log(LOG_INFO, "Loading policy.\n"); if (load_policy_from_db() == -1) { xcpmd_log(LOG_WARNING, "Error loading policy from DB; continuing...\n"); } #ifdef POLICY_FILE_PATH if (load_policy_from_file(POLICY_FILE_PATH) == -1) { xcpmd_log(LOG_WARNING, "Error loading policy from file %s; continuing...\n", POLICY_FILE_PATH); } #endif #ifdef XCPMD_DEBUG xcpmd_log(LOG_DEBUG, "Rules loaded:\n"); print_rules(); #endif xcpmd_log(LOG_INFO, "Entering event loop.\n"); event_dispatch(); goto xcpmd_out; xcpmd_err: ret = -1; xcpmd_out: uninit_modules(); acpi_events_cleanup(); xcpmd_dbus_cleanup(); #ifndef RUN_STANDALONE closelog(); #endif return ret; }
int clickos_start(int domid, const char *name, const char *script) { const char *clickos_config_path_tail = "/config/"; char clickos_script_chunk[1501]; char *clickos_root_path = NULL; char *clickos_elem_path = NULL; char *clickos_ctl_path = NULL; char *clickos_config_name_path = NULL; char *clickos_config_path = NULL; char *clickos_status_path = NULL; char *clickos_router_path = NULL; int clickos_config_id = 0; default_domain_perms.id = domid; default_domain_perms.perms = XS_PERM_READ | XS_PERM_WRITE; if (!xs) { xenstore_init(domid); } retry_clickos: // Transaction for ClickOS th = xs_transaction_start(xs); asprintf(&domain_root_path, "/local/domain/%d", domid); do { asprintf(&clickos_root_path, "%s/clickos/%d", domain_root_path, clickos_config_id); clickos_router_path = xenstore_read(clickos_root_path); if (clickos_router_path) clickos_config_id++; } while (clickos_router_path != NULL); asprintf(&clickos_elem_path, "%s/elements", clickos_root_path); asprintf(&clickos_ctl_path, "%s/control", clickos_root_path); asprintf(&clickos_config_name_path, "%s/config_name", clickos_root_path); asprintf(&clickos_status_path, "%s/status", clickos_root_path); xenstore_write(clickos_elem_path, ""); xenstore_write(clickos_ctl_path, ""); xenstore_chmod(clickos_elem_path, &default_domain_perms); xenstore_chmod(clickos_ctl_path, &default_domain_perms); xenstore_write(clickos_config_name_path, name); // we need one character for each chunk int config_path_len = strlen(clickos_root_path) + strlen(clickos_config_path_tail) + 1; clickos_config_path = malloc(config_path_len + 1); int chunk = 0; int scriptSize = strlen(script); int remainingScriptSize = scriptSize; do { snprintf(clickos_config_path, config_path_len + 1, "%s%s%d", clickos_root_path, clickos_config_path_tail, chunk); int chunkSize = MAX_CHUNK_LENGTH; if (remainingScriptSize < MAX_CHUNK_LENGTH) { chunkSize = remainingScriptSize; } memcpy(clickos_script_chunk, script + (chunk * MAX_CHUNK_LENGTH), chunkSize); clickos_script_chunk[chunkSize] = '\0'; xenstore_write(clickos_config_path, clickos_script_chunk); chunk++; remainingScriptSize -= chunkSize; } while (remainingScriptSize > 0); if (!xs_transaction_end(xs, th, 0)) { if (errno == EAGAIN) goto retry_clickos; } retry_status: // Transaction for ClickOS state th = xs_transaction_start(xs); xenstore_write(clickos_status_path, "Running"); if (!xs_transaction_end(xs, th, 0)) { if (errno == EAGAIN) goto retry_status; } return 0; }
// 从汇编阶段,进入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 */ }