⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!CO_OK(rc)) {		num_pages = i;		scan_address = address;		for (i=0; i < num_pages; i++) {			co_monitor_free_and_unmap_page(cmon, scan_address);			scan_address += CO_ARCH_PAGE_SIZE;		}	}	return rc;}static void incoming_message(co_monitor_t *cmon, co_message_t *message){	co_manager_open_desc_t opened;	co_rc_t rc;	if (message->to == CO_MODULE_CONET0)		co_debug_lvl(network, 14, "message received: %p %p", cmon, message);		co_os_mutex_acquire(cmon->connected_modules_write_lock);	opened = cmon->connected_modules[message->to];	if (opened != NULL)		rc = co_manager_open_ref(opened);	else		rc = CO_RC(ERROR);	co_os_mutex_release(cmon->connected_modules_write_lock);		if (CO_OK(rc)) {		co_manager_send(cmon->manager, opened, message);		co_manager_close(cmon->manager, opened);	}	if (message->to == CO_MODULE_CONET0)		co_debug_lvl(network, 14, "message received end: %p %p", cmon, message);	switch (message->to) {	case CO_MODULE_CONSOLE:		if (message->from == CO_MODULE_LINUX) {			co_console_op(cmon->console, (co_console_message_t *)message->data);		}		break;	default:		break;	}}co_rc_t co_monitor_message_from_user(co_monitor_t *monitor, co_manager_open_desc_t opened, co_message_t *message){	co_rc_t rc = CO_RC(OK);	if (message->to == CO_MODULE_LINUX) {		co_os_mutex_acquire(monitor->linux_message_queue_mutex);		rc = co_message_dup_to_queue(message, &monitor->linux_message_queue);		co_os_mutex_release(monitor->linux_message_queue_mutex);		co_os_wait_wakeup(monitor->idle_wait);	} else {		rc = CO_RC(ERROR);	}	return rc;}/* * iteration - returning PTRUE means that the driver will return  * immediately to Linux instead of returning to the host's  * userspace and only then to Linux. */static bool_t iteration(co_monitor_t *cmon){	switch (co_passage_page->operation) {	case CO_OPERATION_FORWARD_INTERRUPT: 	case CO_OPERATION_IDLE: 		callback_return(cmon);		break;	}	co_debug_lvl(context_switch, 14, "switching to linux (%ld)", co_passage_page->operation);	co_host_switch_wrapper(cmon);	if (co_passage_page->operation == CO_OPERATION_FORWARD_INTERRUPT)		co_monitor_arch_real_hardware_interrupt(cmon);	else		co_monitor_arch_enable_interrupts();	switch (co_passage_page->operation) {	case CO_OPERATION_FREE_PAGES: {		co_free_pages(cmon, co_passage_page->params[0], co_passage_page->params[1]);		return PTRUE;	}	case CO_OPERATION_ALLOC_PAGES: {		co_rc_t rc;		rc = co_alloc_pages(cmon, co_passage_page->params[0], co_passage_page->params[1]);		co_passage_page->params[4] = (unsigned long)(rc);		return PTRUE;	}	case CO_OPERATION_FORWARD_INTERRUPT: {		co_debug_lvl(context_switch, 15, "switching from linux (CO_OPERATION_FORWARD_INTERRUPT), %d",			     cmon->timer_interrupt);		if (cmon->timer_interrupt) {			cmon->timer_interrupt = PFALSE;			/* Return to userspace once in a while */			return PFALSE;		}		return PTRUE;	}	case CO_OPERATION_TERMINATE: 		return co_terminate(cmon);	case CO_OPERATION_IDLE:		return co_idle(cmon);	case CO_OPERATION_MESSAGE_TO_MONITOR: {		co_message_t *message;				co_debug_lvl(context_switch, 14, "switching from linux (CO_OPERATION_MESSAGE_TO_MONITOR)");		message = (co_message_t *)cmon->io_buffer->buffer;		if (message  &&  message->to < CO_MONITOR_MODULES_COUNT)			incoming_message(cmon, message);		cmon->io_buffer->messages_waiting = 0;		return PTRUE;	}	case CO_OPERATION_PRINTK: {		unsigned long size = co_passage_page->params[0];		char *ptr = (char *)&co_passage_page->params[1];		co_message_t *co_message;		if (size > 200) 			size = 200; /* sanity, see co_terminal_printv */		co_message = co_os_malloc(1 + size + sizeof(*co_message));		if (co_message) {			co_message->from = CO_MODULE_LINUX;			co_message->to = CO_MODULE_PRINTK;			co_message->priority = CO_PRIORITY_DISCARDABLE;			co_message->type = CO_MESSAGE_TYPE_STRING;			co_message->size = size + 1; 			co_memcpy(co_message->data, ptr, size + 1);			incoming_message(cmon, co_message);			co_os_free(co_message);		}		return PTRUE;	}	case CO_OPERATION_DEVICE: {		unsigned long device = co_passage_page->params[0];		co_debug_lvl(context_switch, 14, "switching from linux (CO_OPERATION_DEVICE)");		return device_request(cmon, device, &co_passage_page->params[1]);	}	case CO_OPERATION_GET_TIME: {		co_debug_lvl(context_switch, 14, "switching from linux (CO_OPERATION_GET_TIME)");		co_passage_page->params[0] = co_os_get_time();		return PTRUE;	}	case CO_OPERATION_GET_HIGH_PREC_TIME: {		co_os_get_timestamp_freq((co_timestamp_t *)&co_passage_page->params[0],					 (co_timestamp_t *)&co_passage_page->params[2]);		return PTRUE;	}        case CO_OPERATION_DEBUG_LINE:         case CO_OPERATION_TRACE_POINT:                 return PTRUE;	default:		co_debug_lvl(context_switch, 5, "unknown operation %ld not handled", co_passage_page->operation);		return PFALSE;	}		return PTRUE;}static void free_file_blockdevice(co_monitor_t *cmon, co_block_dev_t *dev){	co_monitor_file_block_dev_t *fdev = (co_monitor_file_block_dev_t *)dev;	co_monitor_file_block_shutdown(fdev);	co_monitor_free(cmon, dev);}static co_rc_t load_configuration(co_monitor_t *cmon){	co_rc_t rc = CO_RC_OK; 	unsigned int i;	for (i=0; i < CO_MODULE_MAX_COBD; i++) {		co_monitor_file_block_dev_t *dev;		co_block_dev_desc_t *conf_dev = &cmon->config.block_devs[i];		if (!conf_dev->enabled)			continue;		rc = co_monitor_malloc(cmon, sizeof(co_monitor_file_block_dev_t), (void **)&dev);		if (!CO_OK(rc))			goto error_1;		rc = co_monitor_file_block_init(dev, &conf_dev->pathname);		if (CO_OK(rc)) {			dev->dev.conf = conf_dev;			co_debug("cobd%d: enabled (%p)", i, dev);			co_monitor_block_register_device(cmon, i, (co_block_dev_t *)dev);			dev->dev.free = free_file_blockdevice;		} else {			co_monitor_free(cmon, dev);			co_debug_error("cobd%d: cannot enable (%08x)", i, (int)rc);			goto error_1;		}	}	for (i = 0; i < CO_MODULE_MAX_COFS; i++) {		co_cofsdev_desc_t *desc = &cmon->config.cofs_devs[i];		if (!desc->enabled)			continue;		rc = co_monitor_file_system_init(cmon, i, desc);		if (!CO_OK(rc))			goto error_2;	}	return rc;error_2:	co_monitor_unregister_filesystems(cmon);error_1:	co_monitor_unregister_and_free_block_devices(cmon);	return rc;}static void timer_callback(void *data){        co_monitor_t *cmon = (co_monitor_t *)data;        cmon->timer_interrupt = PTRUE;	co_os_wait_wakeup(cmon->idle_wait);}static void free_pseudo_physical_memory(co_monitor_t *monitor){	int i, j;	if (!monitor->pp_pfns) 		return;	co_debug("freeing page frames for pseudo physical RAM");	for (i=0; i < PTRS_PER_PGD; i++) {		if (!monitor->pp_pfns[i])			continue;		for (j=0; j < PTRS_PER_PTE; j++)			if (monitor->pp_pfns[i][j] != 0)				co_os_put_page(monitor->manager, monitor->pp_pfns[i][j]);		co_monitor_free(monitor, monitor->pp_pfns[i]);	}	co_monitor_free(monitor, monitor->pp_pfns);	monitor->pp_pfns = NULL;	co_debug("done freeing");}static co_rc_t alloc_pp_ram_mapping(co_monitor_t *monitor){	co_rc_t rc;	unsigned long full_page_tables_size;	unsigned long partial_page_table_size;	co_debug("allocating page frames for pseudo physical RAM");	rc = co_monitor_malloc(monitor, sizeof(co_pfn_t *)*PTRS_PER_PGD, (void **)&monitor->pp_pfns);	if (!CO_OK(rc))		return rc;	co_memset(monitor->pp_pfns, 0, sizeof(co_pfn_t *)*PTRS_PER_PGD);	full_page_tables_size = CO_ARCH_PAGE_SIZE * (monitor->memory_size >> CO_ARCH_PMD_SHIFT);	partial_page_table_size = sizeof(unsigned long) *		((monitor->memory_size & ~CO_ARCH_PMD_MASK) >> (CO_ARCH_PAGE_SHIFT));	rc = co_monitor_scan_and_create_pfns(		monitor, 		CO_VPTR_PSEUDO_RAM_PAGE_TABLES, 		full_page_tables_size);	if (CO_OK(rc)) {		if (partial_page_table_size) {			rc = co_monitor_scan_and_create_pfns(				monitor, 				CO_VPTR_PSEUDO_RAM_PAGE_TABLES + full_page_tables_size, 				partial_page_table_size);		}	}		if (!CO_OK(rc)) {		free_pseudo_physical_memory(monitor);	}	return rc;}static co_rc_t alloc_shared_page(co_monitor_t *cmon){	co_rc_t rc = CO_RC_OK;		cmon->shared = co_os_alloc_pages(1);	if (!cmon->shared)		return CO_RC(ERROR);	rc = co_os_userspace_map(cmon->shared, 1, &cmon->shared_user_address, &cmon->shared_handle);	if (!CO_OK(rc)) {		co_os_free_pages(cmon->shared, 1);		return rc;	}	return rc;}static void free_shared_page(co_monitor_t *cmon){	if (cmon->shared_user_address) {		co_os_userspace_unmap(cmon->shared_user_address, cmon->shared_handle, 1);	}	co_os_free_pages(cmon->shared, 1);}static co_rc_t load_section(co_monitor_t *cmon, co_monitor_ioctl_load_section_t *params){	co_rc_t rc = CO_RC(OK);	if (cmon->state != CO_MONITOR_STATE_INITIALIZED)		return CO_RC(ERROR);	if (params->user_ptr) {		co_debug("loading section at 0x%lx (0x%lx bytes)", params->address, params->size);		rc = co_monitor_copy_region(cmon, params->address, params->size, params->buf);	} else {		rc = co_monitor_copy_region(cmon, params->address, params->size, NULL);	}	return rc;}static co_rc_t load_initrd(co_monitor_t *cmon, co_monitor_ioctl_load_initrd_t *params){	co_rc_t rc = CO_RC(OK);	unsigned long address, pages;	if (cmon->state != CO_MONITOR_STATE_INITIALIZED)		return CO_RC(ERROR);	pages = ((params->size + CO_ARCH_PAGE_SIZE) >> CO_ARCH_PAGE_SHIFT);        /*	 * Put initrd at the end of the address space.	 */	address = CO_ARCH_KERNEL_OFFSET + cmon->memory_size - (pages << CO_ARCH_PAGE_SHIFT);		co_debug("initrd address: %lx (0x%lx pages)", address, pages);	if (address <= cmon->core_end + 0x100000) {		co_debug_error("initrd is too close to the kernel code, not enough memory)");		/* We are too close to the kernel code, not enough memory */		return CO_RC(ERROR);	}	rc = co_monitor_copy_region(cmon, address, params->size, params->buf);	if (!CO_OK(rc)) {		co_debug_error("initrd copy failed (%x)", (int)rc);		return rc;	}	cmon->initrd_address = address;	cmon->initrd_size = params->size;	return rc;}static co_rc_t start(co_monitor_t *cmon){	co_rc_t rc;	co_boot_params_t *params;	if (cmon->state != CO_MONITOR_STATE_INITIALIZED) {		co_debug_error("invalid state");		return CO_RC(ERROR);	}			rc = guest_address_space_init(cmon);	if (!CO_OK(rc)) {		co_debug_error("error %08x initializing coLinux context", (int)rc);		return rc;	}	co_os_get_timestamp_freq(&cmon->timestamp, &cmon->timestamp_freq);	co_os_timer_activate(cmon->timer);	co_passage_page->operation = CO_OPERATION_START;	params = (co_boot_params_t *)co_passage_page->params;	params->co_core_end	= cmon->core_end;	params->co_memory_size	= cmon->memory_size;	params->co_initrd 	= (void *)cmon->initrd_address;	params->co_initrd_size	= cmon->initrd_size;	params->co_cpu_khz	= co_os_get_cpu_khz();	co_memcpy(&params->co_boot_parameters,		cmon->config.boot_parameters_line,		sizeof(cmon->config.boot_parameters_line));	cmon->state = CO_MONITOR_STATE_STARTED;	return CO_RC(OK);}static co_rc_t run(co_monitor_t *cmon,		   co_monitor_ioctl_run_t *params,		   unsigned long out_size,		   unsigned long *return_size)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -