Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 13699
b: refs/heads/master
c: 681c774
h: refs/heads/master
i:
  13697: 9d2228a
  13695: 38637e5
v: v3
  • Loading branch information
Olaf Hering authored and Paul Mackerras committed Nov 10, 2005
1 parent 52e26f0 commit a746a1d
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 63 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 58638bffe3d594ed3a902824ea40a4196c745bbd
refs/heads/master: 681c774d0fb59c9b9525c2879d1cfae29c2f7866
131 changes: 69 additions & 62 deletions trunk/arch/ppc64/boot/addRamDisk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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");
Expand All @@ -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);
Expand All @@ -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;

Expand All @@ -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;

Expand Down

0 comments on commit a746a1d

Please sign in to comment.