Commit 681c774d authored by Olaf Hering's avatar Olaf Hering Committed by Paul Mackerras

[PATCH] ppc64 boot: remove sysmap from required filenames

A stripped vmlinux does not contain enough symbols to recreate the
System.map.  The System.map file is only used to determine the end of
the runtime memory size.  This is the same value (rounded up to
PAGE_SIZE) as ->memsiz in the ELF program header.

Also, the target vmlinux.initrd doesnt work in 2.6.14:

  arch/ppc64/boot/addRamDisk arch/ppc64/boot/ramdisk.image.gz vmlinux.strip arch/ppc64/boot/vmlinux.initrd
  Name of vmlinux output file missing.
Signed-off-by: default avatarOlaf Hering <olh@suse.de>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 58638bff
......@@ -5,11 +5,59 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <elf.h>
#define ElfHeaderSize (64 * 1024)
#define ElfPages (ElfHeaderSize / 4096)
#define KERNELBASE (0xc000000000000000)
#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
struct addr_range {
unsigned long long addr;
unsigned long memsize;
unsigned long offset;
};
static int check_elf64(void *p, int size, struct addr_range *r)
{
Elf64_Ehdr *elf64 = p;
Elf64_Phdr *elf64ph;
if (elf64->e_ident[EI_MAG0] != ELFMAG0 ||
elf64->e_ident[EI_MAG1] != ELFMAG1 ||
elf64->e_ident[EI_MAG2] != ELFMAG2 ||
elf64->e_ident[EI_MAG3] != ELFMAG3 ||
elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64)
return 0;
if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size)
return 0;
elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 +
(unsigned long)elf64->e_phoff);
r->memsize = (unsigned long)elf64ph->p_memsz;
r->offset = (unsigned long)elf64ph->p_offset;
r->addr = (unsigned long long)elf64ph->p_vaddr;
#ifdef DEBUG
printf("PPC64 ELF file, ph:\n");
printf("p_type 0x%08x\n", elf64ph->p_type);
printf("p_flags 0x%08x\n", elf64ph->p_flags);
printf("p_offset 0x%016llx\n", elf64ph->p_offset);
printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr);
printf("p_paddr 0x%016llx\n", elf64ph->p_paddr);
printf("p_filesz 0x%016llx\n", elf64ph->p_filesz);
printf("p_memsz 0x%016llx\n", elf64ph->p_memsz);
printf("p_align 0x%016llx\n", elf64ph->p_align);
printf("... skipping 0x%08lx bytes of ELF header\n",
(unsigned long)elf64ph->p_offset);
#endif
return 64;
}
void get4k(FILE *file, char *buf )
{
unsigned j;
......@@ -34,21 +82,17 @@ void death(const char *msg, FILE *fdesc, const char *fname)
int main(int argc, char **argv)
{
char inbuf[4096];
struct addr_range vmlinux;
FILE *ramDisk;
FILE *sysmap;
FILE *inputVmlinux;
FILE *outputVmlinux;
char *rd_name, *lx_name, *out_name;
unsigned i;
size_t i;
unsigned long ramFileLen;
unsigned long ramLen;
unsigned long roundR;
unsigned long sysmapFileLen;
unsigned long sysmapLen;
unsigned long sysmapPages;
char *ptr_end;
unsigned long offset_end;
unsigned long kernelLen;
......@@ -70,24 +114,19 @@ int main(int argc, char **argv)
fprintf(stderr, "Name of RAM disk file missing.\n");
exit(1);
}
rd_name = argv[1]
rd_name = argv[1];
if (argc < 3) {
fprintf(stderr, "Name of System Map input file is missing.\n");
exit(1);
}
if (argc < 4) {
fprintf(stderr, "Name of vmlinux file missing.\n");
exit(1);
}
lx_name = argv[3];
lx_name = argv[2];
if (argc < 5) {
if (argc < 4) {
fprintf(stderr, "Name of vmlinux output file missing.\n");
exit(1);
}
out_name = argv[4];
out_name = argv[3];
ramDisk = fopen(rd_name, "r");
......@@ -96,12 +135,6 @@ int main(int argc, char **argv)
exit(1);
}
sysmap = fopen(argv[2], "r");
if ( ! sysmap ) {
fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[2]);
exit(1);
}
inputVmlinux = fopen(lx_name, "r");
if ( ! inputVmlinux ) {
fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name);
......@@ -113,18 +146,24 @@ int main(int argc, char **argv)
fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name);
exit(1);
}
i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux);
if (i != sizeof(inbuf)) {
fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i);
exit(1);
}
i = check_elf64(inbuf, sizeof(inbuf), &vmlinux);
if (i == 0) {
fprintf(stderr, "You must have a linux kernel specified as argv[2]\n");
exit(1);
}
/* Input Vmlinux file */
fseek(inputVmlinux, 0, SEEK_END);
kernelLen = ftell(inputVmlinux);
fseek(inputVmlinux, 0, SEEK_SET);
printf("kernel file size = %d\n", kernelLen);
if ( kernelLen == 0 ) {
fprintf(stderr, "You must have a linux kernel specified as argv[3]\n");
exit(1);
}
actualKernelLen = kernelLen - ElfHeaderSize;
......@@ -138,39 +177,7 @@ int main(int argc, char **argv)
roundedKernelPages = roundedKernelLen / 4096;
printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
/* Input System Map file */
/* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
fseek(sysmap, 0, SEEK_END);
sysmapFileLen = ftell(sysmap);
fseek(sysmap, 0, SEEK_SET);
printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
sysmapLen = sysmapFileLen;
roundR = 4096 - (sysmapLen % 4096);
if (roundR) {
printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
sysmapLen += roundR;
}
printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
/* Process the Sysmap file to determine where _end is */
sysmapPages = sysmapLen / 4096;
/* read the whole file line by line, expect that it doesn't fail */
while ( fgets(inbuf, 4096, sysmap) ) ;
/* search for _end in the last page of the system map */
ptr_end = strstr(inbuf, " _end");
if (!ptr_end) {
fprintf(stderr, "Unable to find _end in the sysmap file \n");
fprintf(stderr, "inbuf: \n");
fprintf(stderr, "%s \n", inbuf);
exit(1);
}
printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
/* convert address of _end in system map to hex offset. */
offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16);
offset_end = _ALIGN_UP(vmlinux.memsize, 4096);
/* calc how many pages we need to insert between the vmlinux and the start of the ram disk */
padPages = offset_end/4096 - roundedKernelPages;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment