Beispiel #1
0
/* put all properties (files) in the property structure */
static void putprops(char *fn, struct dirent **nlist, int numlist)
{
	struct dirent *dp;
	int i = 0, fd;
	off_t len;
	off_t slen;
	struct stat statbuf;

	for (i = 0; i < numlist; i++) {
		dp = nlist[i];
		strcpy(fn, dp->d_name);

		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
                        continue;

		/* Empirically, this seems to need to be ecluded.
		 * Observed on ARM with 3.6-rc2 kernel
		 */
		if (!strcmp(dp->d_name, "name"))
                        continue;

		if (lstat(pathname, &statbuf))
			die("unrecoverable error: could not stat \"%s\": %s\n",
			    pathname, strerror(errno));

		if (!crash_param && !strcmp(fn,"linux,crashkernel-base"))
			continue;

		if (!crash_param && !strcmp(fn,"linux,crashkernel-size"))
			continue;

		/*
		 * This property will be created for each node during kexec
		 * boot. So, ignore it.
		 */
		if (!strcmp(dp->d_name, "linux,pci-domain") ||
			!strcmp(dp->d_name, "linux,htab-base") ||
			!strcmp(dp->d_name, "linux,htab-size") ||
			!strcmp(dp->d_name, "linux,kernel-end"))
				continue;

		/* This property will be created/modified later in putnode()
		 * So ignore it, unless we are reusing the initrd.
		 */
		if ((!strcmp(dp->d_name, "linux,initrd-start") ||
		     !strcmp(dp->d_name, "linux,initrd-end")) &&
		    !reuse_initrd)
				continue;

		/* This property will be created later in putnode() So
		 * ignore it now.
		 */
		if (!strcmp(dp->d_name, "bootargs"))
			continue;

		if (! S_ISREG(statbuf.st_mode))
			continue;

		len = statbuf.st_size;

		dt_reserve(&dt, 4+((len + 3)/4));
		*dt++ = cpu_to_be32(3);
		*dt++ = cpu_to_be32(len);
		*dt++ = cpu_to_be32(propnum(fn));
		pad_structure_block(len);

		if (len) {
			char *buf;

			buf = slurp_file_len(pathname, len, &slen);
			if (slen != len)
				die("unrecoverable error: short read from\"%s\"\n",
				    pathname);

			memcpy(dt, buf, slen);
			free(buf);
		}

		checkprop(fn, dt, len);

		dt += (len + 3)/4;

		fd = open(pathname, O_RDONLY);
		if (fd == -1)
			die("unrecoverable error: could not open \"%s\": %s\n",
			    pathname, strerror(errno));

		if (!strcmp(dp->d_name, "reg") && usablemem_rgns.size)
			add_usable_mem_property(fd, len);
		add_dyn_reconf_usable_mem_property(dp, fd);
		close(fd);
	}

	fn[0] = '\0';
	checkprop(pathname, NULL, 0);
}
static int get_kernel_vaddr_and_size(struct kexec_info *info)
{
	int result;
	const char kcore[] = "/proc/kcore";
	char *buf;
	struct mem_ehdr ehdr;
	struct mem_phdr *phdr, *end_phdr;
	int align;
	unsigned long size;
	uint32_t elf_flags = 0;

	if (xen_present()) /* Kernel not entity mapped under Xen */
		return 0;

	align = getpagesize();
	size = KCORE_ELF_HEADERS_SIZE;
	buf = slurp_file_len(kcore, size);
	if (!buf) {
		fprintf(stderr, "Cannot read %s: %s\n", kcore, strerror(errno));
		return -1;
	}

	/* Don't perform checks to make sure stated phdrs and shdrs are
	 * actually present in the core file. It is not practical
	 * to read the GB size file into a user space buffer, Given the
	 * fact that we don't use any info from that.
	 */
	elf_flags |= ELF_SKIP_FILESZ_CHECK;
	result = build_elf_core_info(buf, size, &ehdr, elf_flags);
	if (result < 0) {
		fprintf(stderr, "ELF core (kcore) parse failed\n");
		return -1;
	}

	/* Traverse through the Elf headers and find the region where
	 * kernel is mapped. */
	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
	for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
		if (phdr->p_type == PT_LOAD) {
			unsigned long saddr = phdr->p_vaddr;
			unsigned long eaddr = phdr->p_vaddr + phdr->p_memsz;
			unsigned long size;

			/* Look for kernel text mapping header. */
			if ((saddr >= __START_KERNEL_map) &&
			    (eaddr <= __START_KERNEL_map + KERNEL_TEXT_SIZE)) {
				saddr = (saddr) & (~(KERN_VADDR_ALIGN - 1));
				info->kern_vaddr_start = saddr;
				size = eaddr - saddr;
				/* Align size to page size boundary. */
				size = (size + align - 1) & (~(align - 1));
				info->kern_size = size;
#ifdef DEBUG
			printf("kernel vaddr = 0x%lx size = 0x%lx\n",
					saddr, size);
#endif
				return 0;
			}
		}
	}
	fprintf(stderr, "Can't find kernel text map area from kcore\n");
	return -1;
}