linux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: arcboot

To: linux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: arcboot
From: ths@linux-mips.org
Date: Sun, 06 Feb 2005 01:01:11 +0000
Reply-to: linux-mips@linux-mips.org
Sender: linux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    arcboot
Changes by:     ths@ftp.linux-mips.org  05/02/06 01:01:05

Modified files:
        common         : version.h 
        debian         : changelog 
        tip22          : tftpload.c 

Log message:
        Allow ELF64 kernels for tip22/tip32.

diff -urN arcboot/common/version.h arcboot/common/version.h
--- arcboot/common/version.h    2005/01/31 21:19:53     1.3
+++ arcboot/common/version.h    2005/02/06 01:01:05     1.4
@@ -1 +1 @@
-#define __ARCSBOOT_VERSION__ "0.3.8.5"
+#define __ARCSBOOT_VERSION__ "0.3.8.6"
diff -urN arcboot/debian/changelog arcboot/debian/changelog
--- arcboot/debian/changelog    2005/02/05 21:55:26     1.3
+++ arcboot/debian/changelog    2005/02/06 01:01:05     1.4
@@ -1,3 +1,9 @@
+arcboot (0.3.8.6) unstable; urgency=low
+
+  * Allow ELF64 kernels for tip22/tip32.
+
+ -- Thiemo Seufer <ths@debian.org>  Sun, 06 Feb 2005 01:51:01 +0100
+
 arcboot (0.3.8.5) unstable; urgency=low
 
   * Add da debconf translation by Morten Brix Pedersen, thanks
diff -urN arcboot/tip22/tftpload.c arcboot/tip22/tftpload.c
--- arcboot/tip22/tftpload.c    2004/11/29 10:52:21     1.2
+++ arcboot/tip22/tftpload.c    2005/02/06 01:01:05     1.3
@@ -124,7 +124,7 @@
 }
 
 /* copy program segments to the locations the kernel expects */
-static ULONG CopyProgramSegments(Elf32_Ehdr * header)
+static ULONG CopyProgramSegments32(Elf32_Ehdr * header)
 {
        int idx;
        Boolean loaded = False;
@@ -178,36 +178,105 @@
        return kernel_end;
 }
 
-static ULONG CopyKernel(ULONG* kernel_end)
+static ULONG CopyProgramSegments64(Elf64_Ehdr * header)
 {
-       Elf32_Ehdr *header = (Elf32_Ehdr*)offset2addr(0L);
+       int idx;
+       Boolean loaded = False;
+       Elf64_Phdr *segment, *segments;
+       size_t size = header->e_phentsize * header->e_phnum;
+       ULONG kernel_end=0L;
 
-       if (memcmp(&(header->e_ident[EI_MAG0]), ELFMAG, SELFMAG) != 0)
-               Fatal("Not an ELF file\n\r");
+       if (size <= 0)
+               Fatal("No program segments\n\r");
+
+       segments = malloc(size);
+       if (segments == NULL)
+               Fatal("Cannot allocate memory for segment headers\n\r");
+
+        segments = (Elf64_Phdr*)offset2addr(header->e_phoff);
+
+       segment = segments;
+       for (idx = 0; idx < header->e_phnum; idx++) {
+               if (segment->p_type == PT_LOAD) {
+                       printf("Loading program segment %u at 0x%x, size = 
0x%llx\n\r",
+                              idx + 1, KSEG0ADDR(segment->p_vaddr), 
segment->p_filesz);
 
-       if (header->e_ident[EI_CLASS] != ELFCLASS32)
-               Fatal("Not a 32-bit file\n\r");
+                       memcpy((void *)(long)(segment->p_vaddr), 
offset2addr(segment->p_offset), segment->p_filesz);
+                       /* determine the highest address used by the kernel's 
memory image */
+                       if( kernel_end < segment->p_vaddr + segment->p_memsz ) {
+                               kernel_end = segment->p_vaddr + 
segment->p_memsz;
+                       }
 
-       if (header->e_ident[EI_DATA] != ELFDATA2MSB)
-               Fatal("Not a big-endian file\n\r");
+                       size = segment->p_memsz - segment->p_filesz;
+                       if (size > 0) {
+                               printf
+                                   ("Zeroing memory at 0x%x, size = 0x%x\n\r",
+                                    (KSEG0ADDR(segment->p_vaddr +
+                                     segment->p_filesz)), size);
+                               memset((void *)
+                                      (KSEG0ADDR(segment->
+                                        p_vaddr + segment->p_filesz)), 0, 
size);
+                       }
+                       loaded = True;
+               }
+               segment =
+                   (Elf64_Phdr *) (((char *) segment) +
+                                   header->e_phentsize);
+       }
 
-       if (header->e_ident[EI_VERSION] != EV_CURRENT)
-               Fatal("Wrong ELF version\n\r");
+       if (!loaded)
+               Fatal("No loadable program segments found\n\r");
 
-       if (header->e_type != ET_EXEC)
-               Fatal("Not an executable file\n\r");
+       free(segments);
+       return kernel_end;
+}
 
-       if (header->e_machine != EM_MIPS)
-               Fatal("Unsupported machine type\n\r");
+static ULONG CopyKernel(ULONG* kernel_end)
+{
+       Elf32_Ehdr *header = (Elf32_Ehdr*)offset2addr(0L);
+       Elf64_Ehdr *header64 = (Elf64_Ehdr*)header;
 
-       if (header->e_version != EV_CURRENT)
-               Fatal("Wrong ELF version\n\r");
+       if (memcmp(&(header->e_ident[EI_MAG0]), ELFMAG, SELFMAG) != 0)
+               Fatal("Not an ELF file\n\r");
 
-       (*kernel_end) = CopyProgramSegments(header);
+       if (header->e_ident[EI_CLASS] == ELFCLASS32) {
+               if (header->e_ident[EI_DATA] != ELFDATA2MSB)
+                       Fatal("Not a big-endian file\n\r");
+               if (header->e_ident[EI_VERSION] != EV_CURRENT)
+                       Fatal("Wrong ELF version\n\r");
+               if (header->e_type != ET_EXEC)
+                       Fatal("Not an executable file\n\r");
+               if (header->e_machine != EM_MIPS)
+                       Fatal("Unsupported machine type\n\r");
+               if (header->e_version != EV_CURRENT)
+                       Fatal("Wrong ELF version\n\r");
+
+               (*kernel_end) = CopyProgramSegments32(header);
+
+               printf("Starting kernel; entry point = 0x%lx\n\r",
+                      ((ULONG) KSEG0ADDR(header->e_entry)));
+               return KSEG0ADDR(header->e_entry);
+       } else if (header->e_ident[EI_CLASS] == ELFCLASS64) {
+               if (header64->e_ident[EI_DATA] != ELFDATA2MSB)
+                       Fatal("Not a big-endian file\n\r");
+               if (header64->e_ident[EI_VERSION] != EV_CURRENT)
+                       Fatal("Wrong ELF version\n\r");
+               if (header64->e_type != ET_EXEC)
+                       Fatal("Not an executable file\n\r");
+               if (header64->e_machine != EM_MIPS)
+                       Fatal("Unsupported machine type\n\r");
+               if (header64->e_version != EV_CURRENT)
+                       Fatal("Wrong ELF version\n\r");
+
+               (*kernel_end) = CopyProgramSegments64(header64);
+
+               printf("Starting kernel; entry point = 0x%lx\n\r",
+                      ((ULONG) KSEG0ADDR(header64->e_entry)));
+               return KSEG0ADDR(header64->e_entry);
+       } else
+               Fatal("Neither an ELF32 nor an ELF64 kernel\n\r");
 
-       printf("Starting kernel; entry point = 0x%lx\n\r",
-              ((ULONG) KSEG0ADDR(header->e_entry)));
-       return KSEG0ADDR(header->e_entry);
+       return 0L;
 }
 
 static void copyRamdisk(void* rd_vaddr, void* rd_start, ULONG rd_size)
@@ -221,7 +290,7 @@
 {
        char* nargv[3];
        int nargc,i;
-       char argv_rd[128];      /* passed to the kernel on it's commandline */
+       char argv_rd[128];      /* passed to the kernel on its commandline */
        ULONG kernel_end = 0L;
        ULONG rd_size= ((char*)&__rd_end) - ((char*)&__rd_start);
        char* rd_vaddr=NULL;

<Prev in Thread] Current Thread [Next in Thread>