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@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@vivier.eu) + * + * from original XCOFF loader by Steven Noonan steven@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 ); +}