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;
|