summaryrefslogtreecommitdiff
path: root/kexec/arch/ppc64/crashdump-ppc64.c
diff options
context:
space:
mode:
authorR Sharada <sharada@in.ibm.com>2006-07-27 10:47:33 -0600
committerEric W. Biederman <ebiederm@xmission.com>2006-07-27 10:47:33 -0600
commit9768c7e89f1a5cb4933d2ea996321d8ec7e162bd (patch)
treeec05bde128c61deb85692c67f6ad681e01f5c57b /kexec/arch/ppc64/crashdump-ppc64.c
parent17fa73d36cfca33c7b287d7e354961bcff5fa170 (diff)
ppc64 kdump elf hdr generation
This patch implements the elf core header generation - creates elf core headers as 64 bit elf code headers - includes required #defines Signed-off-by: R Sharada <sharada@in.ibm.com> Signed-off-by: Maneesh Soni <maneesh@in.ibm.com>
Diffstat (limited to 'kexec/arch/ppc64/crashdump-ppc64.c')
-rw-r--r--kexec/arch/ppc64/crashdump-ppc64.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c
index e949198..a213166 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -257,6 +257,101 @@ static int add_cmdline_param(char *cmdline, unsigned long addr,
return 0;
}
+/* Prepares the crash memory elf64 headers and stores in supplied buffer. */
+static int prepare_crash_memory_elf64_headers(struct kexec_info *info,
+ void *buf, unsigned long size)
+{
+ Elf64_Ehdr *elf;
+ Elf64_Phdr *phdr;
+ int i;
+ char *bufp;
+ long int nr_cpus = 0;
+ unsigned long notes_addr;
+
+ bufp = (char*) buf;
+
+ /* 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] = ELFDATA2MSB;
+ 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_PPC64;
+ 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;
+
+ /* Need to find a better way to determine per cpu notes section size. */
+#define MAX_NOTE_BYTES 1024
+ for (i = 0; i < nr_cpus; i++) {
+ if (get_crash_notes_per_cpu(i, &notes_addr) < 0) {
+ /* This cpu is not present. Skip it. */
+ continue;
+ }
+ phdr = (Elf64_Phdr *) bufp;
+ bufp += sizeof(Elf64_Phdr);
+ phdr->p_type = PT_NOTE;
+ phdr->p_flags = 0;
+ phdr->p_offset = phdr->p_paddr = notes_addr;
+ phdr->p_vaddr = 0;
+ phdr->p_filesz = phdr->p_memsz = MAX_NOTE_BYTES;
+ /* Do we need any alignment of segments? */
+ phdr->p_align = 0;
+
+ /* Increment number of program headers. */
+ (elf->e_phnum)++;
+ }
+
+ /* Setup PT_LOAD type program header for every system RAM chunk.
+ * A seprate program header for Backup Region
+ */
+ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) {
+ unsigned long 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;
+ if (mstart == BACKUP_START && mend == BACKUP_END)
+ phdr->p_offset = info->backup_start;
+ else
+ phdr->p_offset = mstart;
+ /* Handle linearly mapped region.*/
+ if (mend <= (MAXMEM - 1))
+ phdr->p_vaddr = mstart + PAGE_OFFSET;
+ else
+ phdr->p_vaddr = -1ULL;
+ phdr->p_paddr = mstart;
+ phdr->p_filesz = phdr->p_memsz = mend - mstart;
+ /* Do we need any alignment of segments? */
+ phdr->p_align = 0;
+
+ /* Increment number of program headers. */
+ (elf->e_phnum)++;
+ }
+ return 0;
+}
+
/* 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.