/* 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; }