diff options
Diffstat (limited to 'kexec/arch')
-rw-r--r-- | kexec/arch/i386/crashdump-x86.c | 68 | ||||
-rw-r--r-- | kexec/arch/x86_64/kexec-x86_64.c | 4 |
2 files changed, 55 insertions, 17 deletions
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c index 40f989a..ef4a6f6 100644 --- a/kexec/arch/i386/crashdump-x86.c +++ b/kexec/arch/i386/crashdump-x86.c @@ -200,15 +200,6 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, return -1; } - /* First entry is for first 640K region. Different bios report first - * 640K in different manner hence hardcoding it */ - if (!(kexec_flags & KEXEC_PRESERVE_CONTEXT)) { - crash_memory_range[0].start = 0x00000000; - crash_memory_range[0].end = 0x0009ffff; - crash_memory_range[0].type = RANGE_RAM; - memory_ranges++; - } - while(fgets(line, sizeof(line), fp) != 0) { char *str; int type, consumed, count; @@ -254,10 +245,6 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, continue; } - /* First 640K already registered */ - if (end <= 0x0009ffff) - continue; - crash_memory_range[memory_ranges].start = start; crash_memory_range[memory_ranges].end = end; crash_memory_range[memory_ranges].type = type; @@ -678,6 +665,49 @@ static int cmdline_add_memmap_acpi(char *cmdline, unsigned long start, return 0; } +static void get_backup_area(unsigned long *start, unsigned long *end) +{ + const char *iomem = proc_iomem(); + char line[MAX_LINE]; + FILE *fp; + + fp = fopen(iomem, "r"); + if (!fp) { + fprintf(stderr, "Cannot open %s: %s\n", + iomem, strerror(errno)); + return; + } + + while(fgets(line, sizeof(line), fp) != 0) { + char *str; + int count, consumed; + unsigned long mstart, mend; + + count = sscanf(line, "%lx-%lx : %n", + &mstart, &mend, &consumed); + if (count != 2) + continue; + str = line + consumed; +#ifdef DEBUG + printf("%016lx-%016lx : %s", + mstart, mend, str); +#endif + /* Hopefully there is only one RAM region in the first 640K */ + if (memcmp(str, "System RAM\n", 11) == 0 && mend <= 0xa0000 ) { +#ifdef DEBUG + printf("%s: %016lx-%016lx : %s", __func__, mstart, mend, str); +#endif + *start = mstart; + *end = mend; + fclose(fp); + return; + } + } + *start = BACKUP_SRC_START; + *end = BACKUP_SRC_END; + fclose(fp); +} + /* Loads additional segments in case of a panic kernel is being loaded. * One segment for backup region, another segment for storing elf headers * for crash memory image. @@ -695,8 +725,10 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, /* Constant parts of the elf_info */ elf_info.data = ELFDATA2LSB; - elf_info.backup_src_start = BACKUP_SRC_START; - elf_info.backup_src_end = BACKUP_SRC_END; + get_backup_area(&elf_info.backup_src_start, &elf_info.backup_src_end); + info->backup_src_start = elf_info.backup_src_start; + info->backup_src_size = elf_info.backup_src_end + - elf_info.backup_src_start + 1; /* Get the elf architecture of the running kernel */ if ((info->kexec_flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_X86_64) { @@ -739,13 +771,15 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, sz = (sizeof(struct memory_range) * (KEXEC_MAX_SEGMENTS + 1)); memmap_p = xmalloc(sz); memset(memmap_p, 0, sz); - add_memmap(memmap_p, BACKUP_SRC_START, BACKUP_SRC_SIZE); + add_memmap(memmap_p, elf_info.backup_src_start, + elf_info.backup_src_end - elf_info.backup_src_start + 1); sz = crash_reserved_mem.end - crash_reserved_mem.start +1; add_memmap(memmap_p, crash_reserved_mem.start, sz); /* Create a backup region segment to store backup data*/ if (!(info->kexec_flags & KEXEC_PRESERVE_CONTEXT)) { - sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1); + sz = (elf_info.backup_src_end - elf_info.backup_src_start + align) + & ~(align - 1); tmp = xmalloc(sz); memset(tmp, 0, sz); info->backup_start = add_buffer(info, tmp, sz, sz, align, diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c index c34fd92..6c42c32 100644 --- a/kexec/arch/x86_64/kexec-x86_64.c +++ b/kexec/arch/x86_64/kexec-x86_64.c @@ -157,6 +157,10 @@ void arch_update_purgatory(struct kexec_info *info) &arch_options.console_vga, sizeof(arch_options.console_vga)); elf_rel_set_symbol(&info->rhdr, "console_serial", &arch_options.console_serial, sizeof(arch_options.console_serial)); + elf_rel_set_symbol(&info->rhdr, "backup_src_start", + &info->backup_src_start, sizeof(info->backup_src_start)); + elf_rel_set_symbol(&info->rhdr, "backup_src_size", + &info->backup_src_size, sizeof(info->backup_src_size)); if (info->kexec_flags & KEXEC_ON_CRASH) { panic_kernel = 1; |