[OpenBIOS] r196 - openbios-devel/arch/sparc64

svn at openbios.org svn at openbios.org
Tue Jul 8 18:02:43 CEST 2008


Author: blueswirl
Date: 2008-07-08 18:02:43 +0200 (Tue, 08 Jul 2008)
New Revision: 196

Added:
   openbios-devel/arch/sparc64/aoutload.c
Modified:
   openbios-devel/arch/sparc64/boot.c
   openbios-devel/arch/sparc64/boot.h
   openbios-devel/arch/sparc64/build.xml
Log:
Add a.out support for SILO

Added: openbios-devel/arch/sparc64/aoutload.c
===================================================================
--- openbios-devel/arch/sparc64/aoutload.c	                        (rev 0)
+++ openbios-devel/arch/sparc64/aoutload.c	2008-07-08 16:02:43 UTC (rev 196)
@@ -0,0 +1,146 @@
+/* a.out boot loader
+ * As we have seek, this implementation can be straightforward.
+ * 2003-07 by SONE Takeshi
+ */
+
+#include "openbios/config.h"
+#include "openbios/kernel.h"
+#define CONFIG_SPARC64_PAGE_SIZE_8KB
+#include "a.out.h"
+#include "sys_info.h"
+#include "loadfs.h"
+#include "boot.h"
+#define printf printk
+#define debug printk
+
+#define addr_fixup(addr) ((addr) & 0x00ffffff)
+
+static char *image_name, *image_version;
+const char *program_name, *program_version;
+
+static int check_mem_ranges(struct sys_info *info,
+                            unsigned long start,
+                            unsigned long size)
+{
+    int j;
+    unsigned long end;
+    unsigned long prog_start, prog_end;
+    struct memrange *mem;
+
+    prog_start = virt_to_phys(&_start);
+    prog_end = virt_to_phys(&_end);
+
+    end = start + size;
+
+    if (start < prog_start && end > prog_start)
+        goto conflict;
+    if (start < prog_end && end > prog_end)
+        goto conflict;
+    mem = info->memrange;
+    for (j = 0; j < info->n_memranges; j++) {
+        if (mem[j].base <= start && mem[j].base + mem[j].size >= end)
+            break;
+    }
+    if (j >= info->n_memranges)
+        goto badseg;
+    return 1;
+
+ conflict:
+    printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end);
+
+ badseg:
+    printf("A.out file [%#lx-%#lx] doesn't fit into memory\n", start, end - 1);
+    return 0;
+}
+
+int aout_load(struct sys_info *info, const char *filename, const char *cmdline)
+{
+    int retval = -1;
+    int image_retval;
+    struct exec ehdr;
+    unsigned long start, size;
+    unsigned int offset;
+
+    image_name = image_version = 0;
+
+    if (!file_open(filename))
+	goto out;
+
+    for (offset = 0; offset < 16 * 512; offset += 512) {
+        file_seek(offset);
+        if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) {
+            debug("Can't read a.out header\n");
+            retval = LOADER_NOT_SUPPORT;
+            goto out;
+        }
+        if (!N_BADMAG(ehdr))
+            break;
+    }
+
+    if (N_BADMAG(ehdr)) {
+	debug("Not a bootable a.out image\n");
+	retval = LOADER_NOT_SUPPORT;
+	goto out;
+    }
+
+    if (ehdr.a_text == 0x30800007)
+	ehdr.a_text=64*1024;
+
+    if (N_MAGIC(ehdr) == NMAGIC) {
+        size = addr_fixup(N_DATADDR(ehdr)) + addr_fixup(ehdr.a_data);
+    } else {
+        size = addr_fixup(ehdr.a_text) + addr_fixup(ehdr.a_data);
+    }
+
+    if (size < 7680)
+        size = 7680;
+
+
+    start = 0x4000; // N_TXTADDR(ehdr);
+
+    if (!check_mem_ranges(info, start, size))
+	goto out;
+
+    printf("Loading a.out %s...\n", image_name ? image_name : "image");
+
+    file_seek(offset + N_TXTOFF(ehdr));
+
+    if (N_MAGIC(ehdr) == NMAGIC) {
+        if ((unsigned long)lfile_read((void *)start, ehdr.a_text) != ehdr.a_text) {
+            printf("Can't read program text segment (size 0x%lx)\n", ehdr.a_text);
+            goto out;
+        }
+        if ((unsigned long)lfile_read((void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) {
+            printf("Can't read program data segment (size 0x%lx)\n", ehdr.a_data);
+            goto out;
+        }
+    } else {
+        if ((unsigned long)lfile_read((void *)start, size) != size) {
+            printf("Can't read program (size 0x%lx)\n", size);
+            goto out;
+        }
+    }
+
+    debug("Loaded %lu bytes\n", size);
+
+    debug("entry point is %#lx\n", start);
+    printf("Jumping to entry point...\n");
+
+#if 1
+    {
+        int (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
+                      unsigned long p4, unsigned long p5);
+        extern int of_client_interface( int *params );
+
+        entry = (void *) addr_fixup(start);
+        image_retval = entry(0, 0, 0, 0, (unsigned long)&of_client_interface);
+    }
+#endif
+
+    printf("Image returned with return value %#x\n", image_retval);
+    retval = 0;
+
+out:
+    file_close();
+    return retval;
+}

Modified: openbios-devel/arch/sparc64/boot.c
===================================================================
--- openbios-devel/arch/sparc64/boot.c	2008-07-08 15:59:40 UTC (rev 195)
+++ openbios-devel/arch/sparc64/boot.c	2008-07-08 16:02:43 UTC (rev 196)
@@ -67,13 +67,15 @@
 
 
 	if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
-            if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) {
+            if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
+                if (aout_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) {
 
                     sprintf(altpath, "%s:d", path);
 
                     if (elf_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
                         if (linux_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
-                            printk("Unsupported image format\n");
+                            if (aout_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
+                                printk("Unsupported image format\n");
                 }
 
 	free(path);

Modified: openbios-devel/arch/sparc64/boot.h
===================================================================
--- openbios-devel/arch/sparc64/boot.h	2008-07-08 15:59:40 UTC (rev 195)
+++ openbios-devel/arch/sparc64/boot.h	2008-07-08 16:02:43 UTC (rev 196)
@@ -9,6 +9,7 @@
 int forth_load(struct sys_info *info, const char *filename, const char *cmdline);
 int elf_load(struct sys_info *info, const char *filename, const char *cmdline);
 int linux_load(struct sys_info *info, const char *file, const char *cmdline);
+int aout_load(struct sys_info *info, const char *filename, const char *cmdline);
 
 uint64_t start_elf(uint64_t entry_point, uint64_t param);
 

Modified: openbios-devel/arch/sparc64/build.xml
===================================================================
--- openbios-devel/arch/sparc64/build.xml	2008-07-08 15:59:40 UTC (rev 195)
+++ openbios-devel/arch/sparc64/build.xml	2008-07-08 16:02:43 UTC (rev 196)
@@ -15,6 +15,7 @@
   <object source="linux_load.c"/>
   <object source="sys_info.c"/>
   <object source="elfload.c"/>
+  <object source="aoutload.c"/>
   <object source="forthload.c"/>
   <object source="loadfs.c"/>
  </library>




More information about the OpenBIOS mailing list