[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