示例#1
0
int construct_guest_dom(struct domain *d,
			unsigned long guest_size,
			unsigned long image_start, unsigned long image_size,
			unsigned long initrd_start, unsigned long initrd_size,
			char *cmdline)
{
	char    *p = NULL;
	int     i;
	int     rc;

	unsigned long nr_pages;
	unsigned long nr_pt_pages;
	unsigned long map_track;
	unsigned long phys_offset;

	struct page_info *page = NULL; 
	struct start_info *si  = NULL;
	struct domain_setup_info dsi;
	struct vcpu *v         = NULL;

	uint32_t domain_features_supported[XENFEAT_NR_SUBMAPS] = { 0 };
	uint32_t domain_features_required[XENFEAT_NR_SUBMAPS] = { 0 };

	BUG_ON(d == NULL);

	BUG_ON(d->domain_id <= 0);
	BUG_ON(d->vcpu[0] == NULL);

	v = d->vcpu[0];

	printk("Image Start = 0x%x\n", image_start);

	/* Guest partition should be aligned to 1MB boundary */
	ASSERT((guest_size & 0xFFFFF) == 0);

	BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));

	write_ptbase(idle_domain->vcpu[0]);

	memset(&dsi, 0, sizeof(struct domain_setup_info));

	dsi.image_addr = image_start;
	dsi.image_len  = image_size;

	printk("*** LOADING DOMAIN : %d ***\n", (int)d->domain_id);

	d->max_pages = ~0U;

	rc = parseelfimage(&dsi);
	if (rc != 0) {
        local_irq_enable();
		return rc;
	}


	if (dsi.xen_section_string == NULL) {
		printk("Not a Xen-ELF image: '__xen_guest' section not found.\n");
        local_irq_enable();
		return -EINVAL;
	}

	if ((p = strstr(dsi.xen_section_string, "FEATURES=")) != NULL) {
		parse_features(p + strlen("FEATURES="),
			domain_features_supported,
			domain_features_required);

		printk("Guest kernel supports features = { %08x }.\n",
			domain_features_supported[0]);
		printk("Guest kernel requires features = { %08x }.\n",
                        domain_features_required[0]);

		if (domain_features_required[0]) {
			printk("Guest kernel requires an unsupported hypervisor feature.\n");
			local_irq_enable();
			return -EINVAL;
		}
	}

	page = (struct page_info *) pages_u_alloc(d,
                                             get_order_from_bytes(guest_size),
                                             ~ALLOC_DOM_DMA);
	if (page == NULL) {
		printk("Not enough RAM for domain %d allocation.\n", d->domain_id);
		return -ENOMEM;
	}

	dsi.p_start = page_to_phys(page);
	dsi.p_end   = dsi.p_start + guest_size;
	printk("Guest physical: 0x%x-0x%x\n", dsi.p_start, dsi.p_end);

	dsi.v_start &= (~(0xFFFFF));

	nr_pt_pages = build_guest_tables(v, &dsi);

	write_ptbase(current);

	rc = inspect_guest_tables(v);
	if(!rc) {
		panic("Wrong guest table found\n");
	}

	nr_pages = guest_size >> PAGE_SHIFT;

	if (d->tot_pages < nr_pages)
		printk(" (%lu pages to be allocated)", nr_pages - d->tot_pages);

	for (i = 0; i < MAX_VIRT_CPUS; i++)
		d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;

	for (i = 1; i < num_online_cpus(); i++)
		(void)alloc_vcpu(d, i, i);

	write_ptbase(v);

	phys_offset = v->arch.guest_pstart - v->arch.guest_vstart;
	dsi.image_addr -= phys_offset;

	/* Copy the OS image and free temporary buffer. */
	(void)loadelfimage(&dsi);

	map_track = round_pgup((unsigned long)(v->arch.guest_vtable) + (PAGE_SIZE * nr_pt_pages));
	si = (start_info_t *)map_track;
	memset(si, 0, PAGE_SIZE);

	si->nr_pages	 = nr_pages;
#if 0
	si->shared_info  = virt_to_phys(d->shared_info);
#endif
	si->shared_info  = d->shared_info;
	si->flags        = 0;
	si->pt_base      = (unsigned long)v->arch.guest_vtable;
	si->nr_pt_frames = nr_pt_pages;
	si->mfn_list     = NULL;
	si->min_mfn      = dsi.p_start >> PAGE_SHIFT;

	map_track += PAGE_SIZE;

	if (initrd_size != 0) {
		si->mod_start = map_track;
		si->mod_len = initrd_size;

		printk("Initrd len 0x%lx, start at 0x%lx\n", si->mod_len, si->mod_start);

		memcpy((void *)map_track, (const void *)(initrd_start - phys_offset), initrd_size);

		map_track = round_pgup(map_track + initrd_size);
	}

	memset(map_track, 0, (PAGE_SIZE * 2));

	si->store_mfn = (map_track + phys_offset) >> PAGE_SHIFT;
	si->store_evtchn = d->store_port;
	
	map_track += PAGE_SIZE;

	si->console_mfn = (map_track + phys_offset) >> PAGE_SHIFT;
	si->console_evtchn = d->console_port;

	map_track += PAGE_SIZE;

	d->console_mfn = si->console_mfn;
	d->store_mfn = si->store_mfn;

	memset(si->cmd_line, 0, sizeof(si->cmd_line));
	if (cmdline != NULL)
		strncpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line)-1);

#if 0
	/* setup shared info table which is specified each domain */
	rc = setup_shared_info_mapping(d, NULL);

	if (rc != 0) {
		return rc;
	}
#endif
	write_ptbase(current);

	//init_domain_time(d);

	set_bit(_VCPUF_initialised, &v->vcpu_flags);

	new_thread(v, dsi.v_kernentry, map_track + PAGE_SIZE, (unsigned long)si);

	i = 0;

	BUG_ON(i != 0);

	return 0;
}
示例#2
0
int main(int argc, char **argv) {
	struct eeprom_dev *dev;
	int ch;
	int writing = 0;
	char *tmp;

	struct novena_eeprom_data_v2 newrom;

	int newdata = 0;
	int update_mac = 0;
	int update_features = 0;
	int update_serial = 0;
	int update_oops_start = 0;
	int update_oops_length = 0;
	int update_page_size = 0;
	int update_total_size = 0;
	int update_lvds1 = 0;
	int update_lvds2 = 0;
	int update_hdmi = 0;

	dev = eeprom_open(I2C_BUS, EEPROM_ADDRESS);
	if (!dev)
		return 1;

	while ((ch = getopt(argc, argv, "hm:s:f:wo:p:l:1:2:d:e:i:")) != -1) {
		switch(ch) {

		/* MAC address */
		case 'm':
			if (parse_mac(optarg, newrom.mac))
				return 1;
			update_mac = 1;
			break;

		/* Serial number */
		case 's':
			newrom.serial = strtoul(optarg, NULL, 0);
			update_serial = 1;
			break;

		/* Featuresset */
		case 'f':
			newrom.features = parse_features(optarg);
			if (newrom.features == -1)
				return 1;
			update_features = 1;
			break;

		case 'o':
			newrom.eepromoops_offset = strtoul(optarg, &tmp, 0);
			update_oops_start = 1;
			if (tmp && *tmp) {
				newrom.eepromoops_length = strtoul(tmp + 1,
								    NULL, 0);
				update_oops_length = 1;
			}
			break;

		case 'p':
			newrom.page_size = strtoul(optarg, NULL, 0);
			update_page_size = 1;
			break;

		case 'l':
			newrom.eeprom_size = strtoul(optarg, NULL, 0);
			update_total_size = 1;
			break;

		case '1':
			if (parse_modesetting(&newrom.lvds1, optarg))
				return 1;
			update_lvds1 = 1;
			break;

		case '2':
			if (parse_modesetting(&newrom.lvds2, optarg))
				return 1;
			update_lvds2 = 1;
			break;

		case 'd':
			if (parse_modesetting(&newrom.hdmi, optarg))
				return 1;
			update_hdmi = 1;
			break;

		case 'e':
			return eeprom_export(dev, optarg);

		case 'i':
			if (eeprom_import(dev, optarg))
				return 1;
			newdata = 1;
			break;

		/* Write data */
		case 'w':
			writing = 1;
			break;

		case 'h':
			print_usage(argv[0]);
			return 1;

		default:
			printf("Unrecognized option: %c\n", ch);
			print_usage(argv[0]);
			return 1;
		}
	}

	argc -= optind;
	argv += optind;

	if (update_mac || update_serial || update_features ||
		update_oops_start || update_oops_length ||
		update_page_size || update_total_size ||
		update_lvds1 || update_lvds2 || update_hdmi)
		newdata = 1;

	if (argc)
		print_usage(argv[0]);
	else if (!writing) {
		if (newdata)
			printf("Not writing data, as -w was not specified\n");
		printf("Current EEPROM settings:\n");
		print_eeprom_data(dev);
	}
	else {
		int ret;
		ret = eeprom_read(dev);
		if (ret)
			return 1;
		if (dev->data.v1.version == 1) {
			printf("Updating v1 EEPROM to v2...\n");
			eeprom_upgrade_v1_to_v2(dev);
		}
		else if (dev->data.v1.version == 2) {
			/* Ignore v2 */;
		}
		else {
			if (memcmp(dev->data.v2.signature, NOVENA_SIGNATURE,
					sizeof(dev->data.v2.signature)))
				printf("Blank EEPROM found, "
					"setting defaults...\n");
			else
				fprintf(stderr,
					"Unrecognized EEPROM version found "
					"(v%d), overwriting with v2\n",
					dev->data.v1.version);
			eeprom_get_defaults(dev);
		}

		if (update_mac)
			memcpy(&dev->data.v2.mac, newrom.mac, sizeof(newrom.mac));
		if (update_serial)
			dev->data.v2.serial = newrom.serial;
		if (update_features)
			dev->data.v2.features = newrom.features;
		if (update_oops_start)
			dev->data.v2.eepromoops_offset = newrom.eepromoops_offset;
		if (update_oops_length)
			dev->data.v2.eepromoops_length = newrom.eepromoops_length;
		if (update_page_size)
			dev->data.v2.page_size = newrom.page_size;
		if (update_total_size)
			dev->data.v2.eeprom_size = newrom.eeprom_size;
		if (update_lvds1)
			memcpy(&dev->data.v2.lvds1, &newrom.lvds1,
				sizeof(dev->data.v2.lvds1));
		if (update_lvds2)
			memcpy(&dev->data.v2.lvds2, &newrom.lvds2,
				sizeof(dev->data.v2.lvds2));
		if (update_hdmi)
			memcpy(&dev->data.v2.hdmi, &newrom.hdmi,
				sizeof(dev->data.v2.hdmi));
		memcpy(&dev->data.v2.signature,
				NOVENA_SIGNATURE,
				sizeof(dev->data.v2.signature));

		dev->data.v2.version = 2;

		ret = eeprom_write(dev);
		if (ret) {
			printf("EEPROM write failed\n");
			return 1;
		}

		printf("Updated EEPROM.  New values:\n");
		print_eeprom_data(dev);
	}

	eeprom_close(&dev);

	return 0;
}