summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Damm <magnus@valinux.co.jp>2006-11-22 00:02:11 +0900
committerSimon Horman <horms@verge.net.au>2006-11-27 12:25:13 +0900
commitf038d30bff8510a1df1e72af08db1766581d1f2c (patch)
tree20dc3d1419dd24f19774b5f60c27513d92cb841f
parent5800c9bd01ded5ddc7651a67d338d559c0681219 (diff)
kexec-tools: Make use of crash_create_elf64_headers() (ia64) V2
kexec-tools: Make use of crash_create_elf64_headers() (ia64) V2 Use the new function provided by crashdump-elf.c instead of duplicating the same functionality in prepare_crash_memory_elf64_headers(). This patch also makes the code create a separate kernel program header - just like x86_64 does. This may or may not be correct, but making the architectures behave as similar as possible is probably a good thing. On top of that the patch contains a bugfix for the fact that space for crash note program headers are never allocated... Version 2 of this patch removes alignment and the callback from elf_info. This together with a cosmetic crashdum -> crashdump fix. I'm not 100% sure if the removal of the alignment is correct though. Signed-off-by: Magnus Damm <magnus@valinux.co.jp> Removed trailing whitespace Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/arch/ia64/crashdump-ia64.c128
1 files changed, 25 insertions, 103 deletions
diff --git a/kexec/arch/ia64/crashdump-ia64.c b/kexec/arch/ia64/crashdump-ia64.c
index eadc975..01600d5 100644
--- a/kexec/arch/ia64/crashdump-ia64.c
+++ b/kexec/arch/ia64/crashdump-ia64.c
@@ -1,5 +1,5 @@
/*
- * kexec: crashdum support
+ * kexec: crashdump support
* Copyright (C) 2005-2006 Zou Nan hai <nanhai.zou@intel.com> Intel Corp
*
* This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,17 @@
#include "crashdump-ia64.h"
int memory_ranges = 0;
-#define LOAD_OFFSET (0xa000000000000000UL + 0x100000000UL - kernel_code_start)
+#define LOAD_OFFSET (0xa000000000000000UL + 0x100000000UL)
+
+static struct crash_elf_info elf_info =
+{
+ class: ELFCLASS64,
+ data: ELFDATA2LSB,
+ machine: EM_IA_64,
+ page_offset: PAGE_OFFSET,
+};
+
+
#define MAX_LINE 160
/* Stores a sorted list of RAM memory ranges for which to create elf headers.
* A separate program header is created for backup region */
@@ -37,6 +47,7 @@ static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
static struct memory_range crash_reserved_mem;
unsigned long elfcorehdr;
static unsigned long kernel_code_start;
+static unsigned long kernel_code_end;
struct loaded_segment {
unsigned long start;
unsigned long end;
@@ -129,100 +140,6 @@ static int exclude_crash_reserve_region(int *nr_ranges)
return 0;
}
-static int prepare_crash_memory_elf64_headers(struct kexec_info *info,
- void *buf, unsigned long size)
-{
- Elf64_Ehdr *elf;
- Elf64_Phdr *phdr;
- int i;
- long int nr_cpus = 0;
- char *bufp = buf;
- unsigned long notes_addr, notes_offset, notes_len;
-
- /* Setup ELF Header*/
- elf = (Elf64_Ehdr *) bufp;
- bufp += sizeof(Elf64_Ehdr);
- memcpy(elf->e_ident, ELFMAG, SELFMAG);
- elf->e_ident[EI_CLASS] = ELFCLASS64;
- elf->e_ident[EI_DATA] = ELFDATA2LSB;
- elf->e_ident[EI_VERSION]= EV_CURRENT;
- elf->e_ident[EI_OSABI] = ELFOSABI_NONE;
- memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
- elf->e_type = ET_CORE;
- elf->e_machine = EM_IA_64;
- elf->e_version = EV_CURRENT;
- elf->e_entry = 0;
- elf->e_phoff = sizeof(Elf64_Ehdr);
- elf->e_shoff = 0;
- elf->e_flags = 0;
- elf->e_ehsize = sizeof(Elf64_Ehdr);
- elf->e_phentsize= sizeof(Elf64_Phdr);
- elf->e_phnum = 0;
- elf->e_shentsize= 0;
- elf->e_shnum = 0;
- elf->e_shstrndx = 0;
-
- /* PT_NOTE program headers. One per cpu*/
- nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
- if (nr_cpus < 0) {
- return -1;
- }
-
- for (i = 0; i < nr_cpus; i++) {
- if (get_crash_notes_per_cpu(i, &notes_addr, &notes_len) < 0) {
- /* This cpu is not present. Skip it. */
- continue;
- }
-
- notes_offset = notes_addr;
- phdr = (Elf64_Phdr *) bufp;
- bufp += sizeof(Elf64_Phdr);
- phdr->p_type = PT_NOTE;
- phdr->p_flags = 0;
- phdr->p_offset = notes_offset;
- phdr->p_vaddr = phdr->p_paddr = notes_offset;
- phdr->p_filesz = phdr->p_memsz = notes_len;
- /* Do we need any alignment of segments? */
- phdr->p_align = 0;
-
- /* Increment number of program headers. */
- (elf->e_phnum)++;
- }
-
- for (i = 0; i < memory_ranges; i++) {
- unsigned long mstart, mend;
- mstart = crash_memory_range[i].start;
- mend = crash_memory_range[i].end;
- if (!mstart && !mend)
- break;
- phdr = (Elf64_Phdr *) bufp;
- bufp += sizeof(Elf64_Phdr);
- phdr->p_type = PT_LOAD;
- phdr->p_flags = PF_R|PF_W|PF_X;
- phdr->p_offset = mstart;
- /*add region 5 mapping for kernel*/
- if (kernel_code_start >= mstart && kernel_code_start < mend) {
- phdr->p_vaddr = mstart + LOAD_OFFSET;
- phdr->p_paddr = mstart;
- phdr->p_filesz = phdr->p_memsz = mend - mstart + 1;
- phdr->p_align = 0;
- (elf->e_phnum)++;
-
- phdr = (Elf64_Phdr *) bufp;
- bufp += sizeof(Elf64_Phdr);
- phdr->p_type = PT_LOAD;
- phdr->p_flags = PF_R|PF_W|PF_X;
- phdr->p_offset = mstart;
- }
- phdr->p_vaddr = mstart + PAGE_OFFSET;
- phdr->p_paddr = mstart;
- phdr->p_filesz = phdr->p_memsz = mend - mstart + 1;
- phdr->p_align = 0;
- (elf->e_phnum)++;
- }
- return 0;
-}
-
static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
{
const char iomem[]= "/proc/iomem";
@@ -259,6 +176,7 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
}
else if (memcmp(str, "Kernel code\n", 12) == 0) {
kernel_code_start = start;
+ kernel_code_end = end;
continue;
}else
continue;
@@ -294,18 +212,22 @@ int load_crashdump_segments(struct kexec_info *info, struct mem_ehdr *ehdr,
//struct memory_range *mem_range, *memmap_p;
struct memory_range *mem_range;
int nr_ranges;
+ unsigned long sz;
size_t size;
void *tmp;
if (info->kexec_flags & KEXEC_ON_CRASH ) {
if (get_crash_memory_ranges(&mem_range, &nr_ranges) == 0) {
- size = sizeof(Elf64_Ehdr) +
- (nr_ranges + 1) * sizeof(Elf64_Phdr);
- size = (size + EFI_PAGE_SIZE - 1) & ~(EFI_PAGE_SIZE - 1);
- tmp = xmalloc(size);
- memset(tmp, 0, size);
- if (prepare_crash_memory_elf64_headers(info, tmp, size) < 0)
+
+ info->kern_paddr_start = kernel_code_start;
+ info->kern_vaddr_start = LOAD_OFFSET;
+ info->kern_size = kernel_code_end - kernel_code_start + 1;
+ if (crash_create_elf64_headers(info, &elf_info,
+ crash_memory_range,
+ nr_ranges,
+ &tmp, &sz) < 0)
return -1;
- elfcorehdr = add_buffer(info, tmp, size, size, EFI_PAGE_SIZE, min_base,
+
+ elfcorehdr = add_buffer(info, tmp, sz, sz, EFI_PAGE_SIZE, min_base,
max_addr, -1);
loaded_segments[loaded_segments_num].start = elfcorehdr;
loaded_segments[loaded_segments_num].end = elfcorehdr + size;