[OpenBIOS] r581 - in trunk/openbios-devel: forth/debugging include/openbios modules
svn at openbios.org
svn at openbios.org
Sat Sep 19 23:44:05 CEST 2009
Author: laurent
Date: 2009-09-19 23:44:05 +0200 (Sat, 19 Sep 2009)
New Revision: 581
Added:
trunk/openbios-devel/include/openbios/xcoff.h
trunk/openbios-devel/modules/xcoff-loader.c
Modified:
trunk/openbios-devel/forth/debugging/client.fs
trunk/openbios-devel/modules/build.xml
trunk/openbios-devel/modules/init.c
trunk/openbios-devel/modules/modules.h
Log:
Implements XCOFF loader (to be able to boot Apple BootX bootloader)
Signed-off-by: Laurent Vivier <Laurent at vivier.eu>
Modified: trunk/openbios-devel/forth/debugging/client.fs
===================================================================
--- trunk/openbios-devel/forth/debugging/client.fs 2009-09-18 23:32:59 UTC (rev 580)
+++ trunk/openbios-devel/forth/debugging/client.fs 2009-09-19 21:44:05 UTC (rev 581)
@@ -180,6 +180,7 @@
;
variable elf-entry
+variable xcoff-entry
: init-program-elf
elf file-type !
@@ -302,9 +303,19 @@
elf file-type @ = if
[IFDEF] CONFIG_PPC
elf-entry @ " (go)" evaluate
+[ELSE]
+ ." go is not yet implemented"
[THEN]
else
- ." go is not yet implemented"
+ xcoff file-type @ = if
+[IFDEF] CONFIG_PPC
+ xcoff-entry @ " (go)" evaluate
+[ELSE]
+ ." go is not yet implemented"
+[THEN]
+ else
+ ." go is not yet implemented"
+ then
then
;
Added: trunk/openbios-devel/include/openbios/xcoff.h
===================================================================
--- trunk/openbios-devel/include/openbios/xcoff.h (rev 0)
+++ trunk/openbios-devel/include/openbios/xcoff.h 2009-09-19 21:44:05 UTC (rev 581)
@@ -0,0 +1,98 @@
+#ifndef XCOFF_H
+#define XCOFF_H
+
+/* XCOFF executable loader */
+
+typedef struct COFF_filehdr_t {
+ uint16_t f_magic; /* magic number */
+ uint16_t f_nscns; /* number of sections */
+ uint32_t f_timdat; /* time & date stamp */
+ uint32_t f_symptr; /* file pointer to symtab */
+ uint32_t f_nsyms; /* number of symtab entries */
+ uint16_t f_opthdr; /* sizeof(optional hdr) */
+ uint16_t f_flags; /* flags */
+} COFF_filehdr_t;
+
+/* IBM RS/6000 */
+
+#define U802WRMAGIC 0x02DA /* writeable text segments **chh** */
+#define U802ROMAGIC 0x02DF /* readonly sharable text segments */
+#define U802TOCMAGIC 0x02E1 /* readonly text segments and TOC */
+#define U802TOMAGIC 0x01DF
+
+/*
+ * Bits for f_flags:
+ *
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (i.e. no unresolved external
+ * references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_MINMAL this is a minimal object file (".m") output of fextract
+ * F_UPDATE this is a fully bound update file, output of ogen
+ * F_SWABD this file has had its bytes swabbed (in names)
+ * F_AR16WR this file has the byte ordering of an AR16WR
+ * (e.g. 11/70) machine
+ * F_AR32WR this file has the byte ordering of an AR32WR machine
+ * (e.g. vax and iNTEL 386)
+ * F_AR32W this file has the byte ordering of an AR32W machine
+ * (e.g. 3b,maxi)
+ * F_PATCH file contains "patch" list in optional header
+ * F_NODF (minimal file only) no decision functions for
+ * replaced functions
+ */
+
+#define COFF_F_RELFLG 0000001
+#define COFF_F_EXEC 0000002
+#define COFF_F_LNNO 0000004
+#define COFF_F_LSYMS 0000010
+#define COFF_F_MINMAL 0000020
+#define COFF_F_UPDATE 0000040
+#define COFF_F_SWABD 0000100
+#define COFF_F_AR16WR 0000200
+#define COFF_F_AR32WR 0000400
+#define COFF_F_AR32W 0001000
+#define COFF_F_PATCH 0002000
+#define COFF_F_NODF 0002000
+
+typedef struct COFF_aouthdr_t {
+ uint16_t magic; /* type of file */
+ uint16_t vstamp; /* version stamp */
+ uint32_t tsize; /* text size in bytes, padded to FW bdry */
+ uint32_t dsize; /* initialized data " " */
+ uint32_t bsize; /* uninitialized data " " */
+ uint32_t entry; /* entry pt. */
+ uint32_t text_start; /* base of text used for this file */
+ uint32_t data_start; /* base of data used for this file */
+ uint32_t o_toc; /* address of TOC */
+ uint16_t o_snentry; /* section number of entry point */
+ uint16_t o_sntext; /* section number of .text section */
+ uint16_t o_sndata; /* section number of .data section */
+ uint16_t o_sntoc; /* section number of TOC */
+ uint16_t o_snloader; /* section number of .loader section */
+ uint16_t o_snbss; /* section number of .bss section */
+ uint16_t o_algntext; /* .text alignment */
+ uint16_t o_algndata; /* .data alignment */
+ uint16_t o_modtype; /* module type (??) */
+ uint16_t o_cputype; /* cpu type */
+ uint32_t o_maxstack; /* max stack size (??) */
+ uint32_t o_maxdata; /* max data size (??) */
+ char o_resv2[12]; /* reserved */
+} COFF_aouthdr_t;
+
+#define AOUT_MAGIC 0x010b
+
+typedef struct COFF_scnhdr_t {
+ char s_name[8]; /* section name */
+ uint32_t s_paddr; /* physical address, aliased s_nlib */
+ uint32_t s_vaddr; /* virtual address */
+ uint32_t s_size; /* section size */
+ uint32_t s_scnptr; /* file ptr to raw data for section */
+ uint32_t s_relptr; /* file ptr to relocation */
+ uint32_t s_lnnoptr; /* file ptr to line numbers */
+ uint16_t s_nreloc; /* number of relocation entries */
+ uint16_t s_nlnno; /* number of line number entries */
+ uint32_t s_flags; /* flags */
+} COFF_scnhdr_t;
+
+#endif /* XCOFF_H */
Modified: trunk/openbios-devel/modules/build.xml
===================================================================
--- trunk/openbios-devel/modules/build.xml 2009-09-18 23:32:59 UTC (rev 580)
+++ trunk/openbios-devel/modules/build.xml 2009-09-19 21:44:05 UTC (rev 581)
@@ -25,6 +25,7 @@
<object source="font_8x16.c" condition="FONT_8X16"/>
<object source="ofmem_common.c" condition="OFMEM"/>
<object source="elf-loader.c" condition="PPC"/>
+ <object source="xcoff-loader.c" condition="PPC"/>
</library>
<dictionary name="openbios" target="forth">
Modified: trunk/openbios-devel/modules/init.c
===================================================================
--- trunk/openbios-devel/modules/init.c 2009-09-18 23:32:59 UTC (rev 580)
+++ trunk/openbios-devel/modules/init.c 2009-09-19 21:44:05 UTC (rev 581)
@@ -44,5 +44,6 @@
#endif
#ifdef CONFIG_PPC
elf_loader_init();
+ xcoff_loader_init();
#endif
}
Modified: trunk/openbios-devel/modules/modules.h
===================================================================
--- trunk/openbios-devel/modules/modules.h 2009-09-18 23:32:59 UTC (rev 580)
+++ trunk/openbios-devel/modules/modules.h 2009-09-19 21:44:05 UTC (rev 581)
@@ -25,5 +25,6 @@
extern void sunparts_init( void );
extern void cmdline_init( void );
extern void elf_loader_init( void );
+extern void xcoff_loader_init( void );
#endif /* _H_MODULES */
Added: trunk/openbios-devel/modules/xcoff-loader.c
===================================================================
--- trunk/openbios-devel/modules/xcoff-loader.c (rev 0)
+++ trunk/openbios-devel/modules/xcoff-loader.c 2009-09-19 21:44:05 UTC (rev 581)
@@ -0,0 +1,140 @@
+/*
+ *
+ * <xcoff-loader.c>
+ *
+ * XCOFF file loader
+ *
+ * Copyright (C) 2009 Laurent Vivier (Laurent at vivier.eu)
+ *
+ * from original XCOFF loader by Steven Noonan <steven at uplinklabs.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2
+ *
+ */
+
+#include "openbios/config.h"
+#include "openbios/bindings.h"
+#include "modules.h"
+#include "ofmem.h"
+
+#include "openbios/xcoff.h"
+
+//#define DEBUG_XCOFF
+
+#ifdef DEBUG_XCOFF
+#define DPRINTF(fmt, args...) \
+ do { printk("%s: " fmt, __func__ , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) \
+ do { } while (0)
+#endif
+
+DECLARE_NODE(xcoff_loader, INSTALL_OPEN, 0, "+/packages/xcoff-loader" );
+
+#ifdef CONFIG_PPC
+extern void flush_icache_range( char *start, char *stop );
+#endif
+
+static void
+xcoff_loader_init_program( void *dummy )
+{
+ char *base;
+ COFF_filehdr_t *fhdr;
+ COFF_aouthdr_t *ahdr;
+ COFF_scnhdr_t *shdr;
+ uint32_t offset;
+ int i;
+
+ feval("load-base");
+ base = (char*)POP();
+
+ fhdr = (COFF_filehdr_t*)base;
+
+ /* Is it an XCOFF file ? */
+
+ if (fhdr->f_magic != U802WRMAGIC &&
+ fhdr->f_magic != U802ROMAGIC &&
+ fhdr->f_magic != U802TOCMAGIC &&
+ fhdr->f_magic != U802TOMAGIC) {
+ DPRINTF("Not a XCOFF file %02x\n", fhdr->f_magic);
+ return;
+ }
+
+ /* Is it executable ? */
+
+ if (fhdr->f_magic != 0x01DF &&
+ (fhdr->f_flags & COFF_F_EXEC) == 0) {
+ DPRINTF("Not an executable XCOFF file %02x\n", fhdr->f_flags);
+ return;
+ }
+
+ /* Optional header is a.out ? */
+
+ if (fhdr->f_opthdr != sizeof(COFF_aouthdr_t)) {
+ DPRINTF("AOUT optional error size mismatch in XCOFF file\n");
+ return;
+ }
+
+ ahdr = (COFF_aouthdr_t*)(base + sizeof(COFF_filehdr_t));
+
+ /* check a.out magic number */
+
+ if (ahdr->magic != AOUT_MAGIC) {
+ DPRINTF("Invalid AOUT optional header\n");
+ return;
+ }
+
+ offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t);
+
+ DPRINTF("XCOFF file with %d sections\n", fhdr->f_nscns);
+
+ for (i = 0; i < fhdr->f_nscns; i++) {
+
+ DPRINTF("Read header at offset %0x\n", offset);
+
+ shdr = (COFF_scnhdr_t*)(base + offset);
+
+ DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n",
+ shdr->s_name, offset, shdr->s_scnptr,
+ shdr->s_vaddr, shdr->s_size);
+
+ if (strcmp(shdr->s_name, ".text") == 0) {
+
+ memcpy((char*)shdr->s_vaddr, base + shdr->s_scnptr,
+ shdr->s_size);
+#ifdef CONFIG_PPC
+ flush_icache_range((char*)shdr->s_vaddr,
+ (char*)(shdr->s_vaddr + shdr->s_size));
+#endif
+ } else if (strcmp(shdr->s_name, ".data") == 0) {
+
+ memcpy((char*)shdr->s_vaddr, base + shdr->s_scnptr,
+ shdr->s_size);
+
+ } else if (strcmp(shdr->s_name, ".bss") == 0) {
+
+ memset((void *)shdr->s_vaddr, 0, shdr->s_size);
+
+ } else {
+ DPRINTF(" Skip '%s' section\n", shdr->s_name);
+ }
+ offset += sizeof(COFF_scnhdr_t);
+ }
+
+ /* FIXME: should initialize saved-program-state. */
+
+ DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr->entry);
+ PUSH(*(uint32_t*)ahdr->entry);
+ feval("xcoff-entry !");
+}
+
+NODE_METHODS( xcoff_loader ) = {
+ { "init-program", xcoff_loader_init_program },
+};
+
+void xcoff_loader_init( void )
+{
+ REGISTER_NODE( xcoff_loader );
+}
More information about the OpenBIOS
mailing list