示例#1
0
static
int atag_arm_load(struct kexec_info *info, unsigned long base,
	const char *command_line, off_t command_line_len,
	const char *initrd, off_t initrd_len)
{
	struct tag *saved_tags = atag_read_tags();
	char *buf, *cmdline_buf;
	off_t len, cmdline_len = 0;
	struct tag *params;
	uint32_t *initrd_start;
	int i;

	buf = xmalloc(getpagesize());
	if (!buf) {
		fprintf(stderr, "Compiling ATAGs: out of memory\n");
		return -1;
	}

	cmdline_buf = xmalloc(COMMAND_LINE_SIZE);
	if (!cmdline_buf) {
		fprintf(stderr, "Compiling Command line: out of memory\n");
		return -1;
	}

	memset(buf, 0xff, getpagesize());
        memset((void *)cmdline_buf, 0, COMMAND_LINE_SIZE);
	params = (struct tag *)buf;
	if (saved_tags) {
		// Copy tags
		saved_tags = (struct tag *) saved_tags;
		while(byte_size(saved_tags)) {
			switch (saved_tags->hdr.tag) {
			case ATAG_INITRD:
			case ATAG_INITRD2:
			case ATAG_NONE:
				// skip these tags
				break;
			case ATAG_CMDLINE:
                                cmdline_len = strlen(saved_tags->u.cmdline.cmdline) + 1;
                                if(cmdline_len > COMMAND_LINE_SIZE)
                                    die("Command line overflow\n");
                                strncpy(cmdline_buf, saved_tags->u.cmdline.cmdline, COMMAND_LINE_SIZE);
                                cmdline_buf[COMMAND_LINE_SIZE - 1] = '\0';
                                break;
			default:
				// copy all other tags
				memcpy(params, saved_tags, byte_size(saved_tags));
				params = tag_next(params);
			}
			saved_tags = tag_next(saved_tags);
		}
	} else {
		params->hdr.size = 2;
		params->hdr.tag = ATAG_CORE;
		params = tag_next(params);
	}

	if (initrd) {
		params->hdr.size = tag_size(tag_initrd);
		params->hdr.tag = ATAG_INITRD2;
		initrd_start = &params->u.initrd.start;
		params->u.initrd.size = initrd_len;
		params = tag_next(params);
	}

	if (command_line) {
                command_line_len = command_line_len + cmdline_len -1;
                if(command_line_len > COMMAND_LINE_SIZE)
                    die("Command line overflow\n");
                strncat(cmdline_buf, command_line, COMMAND_LINE_SIZE - 1);
		params->hdr.size = (sizeof(struct tag_header) + command_line_len + 3) >> 2;
		params->hdr.tag = ATAG_CMDLINE;
		memcpy(params->u.cmdline.cmdline, cmdline_buf,
			command_line_len);
		params->u.cmdline.cmdline[command_line_len - 1] = '\0';
		params = tag_next(params);
	}

	params->hdr.size = 0;
	params->hdr.tag = ATAG_NONE;
	len = ((char *)params - buf) + sizeof(struct tag_header);

	add_segment(info, buf, len, base, len);

	if (initrd) {
		struct memory_range *range;
		int ranges;
		get_memory_ranges(&range, &ranges, info->kexec_flags);
		for (i=0; range[i].start; i++) {
			printf("Memory Ranges: range[%d].start = 0x%x\n", 
							i, range[i].start);
		}

		//*initrd_start = locate_hole(info, initrd_len, getpagesize(), range[0].start + 0x800000, ULONG_MAX, INT_MAX);
		/* Allocate memory from 0x400000 offset from start of capture kernel*/
		if (range[ranges-1].start > 0)
			*initrd_start = range[ranges-1].start +  0x400000;

		printf("*initrd_start = %p\n", *initrd_start);
		if (*initrd_start == ULONG_MAX)
			return -1;
		add_segment(info, initrd, initrd_len, *initrd_start, initrd_len);
	}

	return 0;
}
static
int atag_arm_load(struct kexec_info *info, unsigned long base,
	const char *command_line, off_t command_line_len,
	const char *initrd, off_t initrd_len, off_t initrd_off)
{
	struct tag *saved_tags = atag_read_tags();
	char *buf = NULL;
	size_t buf_size = 0;
	struct tag *params, *tag;
	uint32_t *initrd_start = NULL;

	params = xmalloc(getpagesize());
	if (!params) {
		fprintf(stderr, "Compiling ATAGs: out of memory\n");
		free(saved_tags);
		return -1;
	}
	memset(params, 0xff, getpagesize());

	if (saved_tags) {
		// Copy tags
		tag = saved_tags;
		while(byte_size(tag)) {
			switch (tag->hdr.tag) {
			case ATAG_INITRD:
			case ATAG_INITRD2:
			case ATAG_CMDLINE:
			case ATAG_NONE:
				// skip these tags
				break;
			default:
				// copy all other tags
				tag_buf_add(tag, &buf, &buf_size);
				break;
			}
			tag = tag_next(tag);
		}
		free(saved_tags);
	} else {
		params->hdr.size = 2;
		params->hdr.tag = ATAG_CORE;
		tag_buf_add(params, &buf, &buf_size);
		memset(params, 0xff, byte_size(params));
	}

	if (initrd) {
		params->hdr.size = tag_size(tag_initrd);
		params->hdr.tag = ATAG_INITRD2;
		params->u.initrd.size = initrd_len;

		tag_buf_add(params, &buf, &buf_size);
		memset(params, 0xff, byte_size(params));
	}

	if (command_line) {
		params->hdr.size = (sizeof(struct tag_header) + command_line_len + 3) >> 2;
		params->hdr.tag = ATAG_CMDLINE;
		memcpy(params->u.cmdline.cmdline, command_line,
			command_line_len);
		params->u.cmdline.cmdline[command_line_len - 1] = '\0';

		tag_buf_add(params, &buf, &buf_size);
		memset(params, 0xff, byte_size(params));
	}

	params->hdr.size = 0;
	params->hdr.tag = ATAG_NONE;
	tag_buf_add(params, &buf, &buf_size);

	free(params);

	add_segment(info, buf, buf_size, base, buf_size);

	if (initrd) {
		initrd_start = tag_buf_find_initrd_start((struct tag *)buf);
		if(!initrd_start)
		{
			fprintf(stderr, "Failed to find initrd start!\n");
			return -1;
		}

		*initrd_start = locate_hole(info, initrd_len, getpagesize(),
				initrd_off, ULONG_MAX, INT_MAX);
		if (*initrd_start == ULONG_MAX)
			return -1;
		add_segment(info, initrd, initrd_len, *initrd_start, initrd_len);
	}

	return 0;
}
static
int atag_arm_load(struct kexec_info *info, unsigned long base,
	const char *command_line, off_t command_line_len,
	const char *initrd, off_t initrd_len, off_t initrd_off)
{
	struct tag *saved_tags = atag_read_tags();
	char *buf;
	off_t len;
	struct tag *params;
	uint32_t *initrd_start = NULL;
	
	buf = xmalloc(getpagesize());
	if (!buf) {
		fprintf(stderr, "Compiling ATAGs: out of memory\n");
		return -1;
	}

	memset(buf, 0xff, getpagesize());
	params = (struct tag *)buf;

	if (saved_tags) {
		// Copy tags
		saved_tags = (struct tag *) saved_tags;
		while(byte_size(saved_tags)) {
			switch (saved_tags->hdr.tag) {
			case ATAG_INITRD:
			case ATAG_INITRD2:
			case ATAG_CMDLINE:
			case ATAG_NONE:
				// skip these tags
				break;
			default:
				// copy all other tags
				memcpy(params, saved_tags, byte_size(saved_tags));
				params = tag_next(params);
			}
			saved_tags = tag_next(saved_tags);
		}
	} else {
		params->hdr.size = 2;
		params->hdr.tag = ATAG_CORE;
		params = tag_next(params);
	}

	if (initrd) {
		params->hdr.size = tag_size(tag_initrd);
		params->hdr.tag = ATAG_INITRD2;
		initrd_start = &params->u.initrd.start;
		params->u.initrd.size = initrd_len;
		params = tag_next(params);
	}

	if (command_line) {
		params->hdr.size = (sizeof(struct tag_header) + command_line_len + 3) >> 2;
		params->hdr.tag = ATAG_CMDLINE;
		memcpy(params->u.cmdline.cmdline, command_line,
			command_line_len);
		params->u.cmdline.cmdline[command_line_len - 1] = '\0';
		params = tag_next(params);
	}

	params->hdr.size = 0;
	params->hdr.tag = ATAG_NONE;

	len = ((char *)params - buf) + sizeof(struct tag_header);

	add_segment(info, buf, len, base, len);

	if (initrd) {
		*initrd_start = locate_hole(info, initrd_len, getpagesize(),
				initrd_off, ULONG_MAX, INT_MAX);
		if (*initrd_start == ULONG_MAX)
			return -1;
		add_segment(info, initrd, initrd_len, *initrd_start, initrd_len);
	}

	return 0;
}