Subject: Re: DS5k/240 refuses to boot
To: Ulrich Teichert <ut@netsurf.de>
From: Simon Burge <simonb@netbsd.org>
List: port-pmax
Date: 12/31/1999 10:18:12
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <18558.946595822.1@balrog>

Ulrich Teichert wrote:

> >As I understand it, ecoff file headers can be different between
> >architectures.  Look at ECOFF_PAD in the ecoff_aouthdr struct in
> >sys/exec_ecoff.h.  I wonder if any Alphas can boot via mop?
> 
> According to file.c from the mopd-package, yes:
> [del]
> case IHD_C_ALPHA:		/* ALPHA system image	     */
> [deleted supported system file header hackery]
> 
> >Ideally, I should teach mopd to read NetBSD/pmax ELF kernels but I got
> >lazy - it was much easier to hack support in for ECOFF.  Another day...
> 
> The code of mopd looks straight forward for me, so I think I'll gonna
> give it a try - I'm on holiday until the 3rd of January ;-)

Hmm, it looks like I did a token effort at pmax-only ECOFF support by
using a local header file for ECOFF info.  I don't think I've taken host
byte-order into account, so it probably won't work at the moment using a
sun, 68k or powerpc box as a host.

Here's what I have at the moment (in yucky MIME format - hope I got it
right!).

Simon.


------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <18558.946595822.2@balrog>
Content-Description: mopd patch

? common/mop_ecoff.h
Index: common/file.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mopd/common/file.c,v
retrieving revision 1.6
diff -p -u -r1.6 file.c
--- file.c	1998/07/25 06:01:13	1.6
+++ file.c	1999/12/30 23:11:02
@@ -54,6 +54,17 @@ __RCSID("$NetBSD: file.c,v 1.6 1998/07/2
 #endif
 #endif
 
+#ifndef NOECOFF
+#if defined(__NetBSD__)
+#include "mop_ecoff.h"
+#if !defined(MID_ECOFF)
+#define MID_PMAX_ECOFF 9999
+#endif
+#else
+#define NOECOFF
+#endif
+#endif
+
 int	getCLBYTES __P((int));
 int	getMID __P((int, int));
 
@@ -666,6 +677,102 @@ GetAOutFileInfo(fd, load, xfr, a_text, a
 }
 
 int
+CheckECOFFFile(fd)
+	int	fd;
+{
+#ifdef NOECOFF
+	return(-1);
+#else
+	struct ecoff_exechdr coff, coff_swap;
+	int	mid = -1;
+
+	if (read(fd, (char *)&coff, sizeof(coff)) != sizeof(coff))
+		return(-1);
+
+	(void)lseek(fd, (off_t) 0, SEEK_SET);
+	
+	if (read(fd, (char *)&coff_swap, sizeof(coff_swap)) != sizeof(coff_swap))
+		return(-1);
+
+	(void)lseek(fd, (off_t) 0, SEEK_SET);
+	
+/* XXX - make either endian, can't assume sys/exec_ecoff.h !!! */
+	if (!ECOFF_BADMAG(&coff))
+		mid = 0;
+/* XXX - end */
+	return(mid);
+#endif NOECOFF
+}
+
+int
+GetECOFFFileInfo(fd, load, xfr, a_text, a_text_fill,
+		 a_data, a_data_fill, a_bss, a_bss_fill, aout)
+	int		 fd;
+	u_int32_t	*load, *xfr, *a_text, *a_text_fill;
+	u_int32_t	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
+	int		 *aout;
+{
+#ifdef NOECOFF
+	return(-1);
+#else
+	struct ecoff_exechdr coff, coff_swap;
+
+	if (read(fd, (char *)&coff, sizeof(coff)) != sizeof(coff))
+		return(-1);
+
+	(void)lseek(fd, (off_t) 0, SEEK_SET);
+
+	if (read(fd, (char *)&coff_swap, sizeof(coff_swap)) != sizeof(coff_swap))
+		return(-1);
+
+	(void)lseek(fd, ECOFF_TXTOFF(&coff), SEEK_SET);
+
+	printf("Size of text:       %08lx\n", (long)coff.a.tsize);
+	printf("Size of data:       %08lx\n", (long)coff.a.dsize);
+	printf("Size of bss:        %08lx\n", (long)coff.a.bsize);
+	printf("Transfer Address:   %08lx\n", (long)coff.a.entry);
+
+	if (load != NULL) {
+		*load   = coff.a.text_start;
+	}
+
+	if (xfr != NULL) {
+		*xfr    = coff.a.entry;
+	}
+
+	if (a_text != NULL) {
+		*a_text = coff.a.tsize;
+	}
+
+	if (a_text_fill != NULL) {
+		*a_text_fill = 0;
+	}
+
+	if (a_data != NULL) {
+		*a_data = coff.a.dsize;
+	}
+
+	if (a_data_fill != NULL) {
+		*a_data_fill = 0;
+	}
+
+	if (a_bss != NULL) {
+		*a_bss  = coff.a.bsize;
+	}
+
+	if (a_bss_fill != NULL) {
+		*a_bss_fill = 0;
+	}
+
+	if (aout != NULL) {
+		*aout = MID_PMAX_ECOFF;
+	}
+
+	return(0);
+#endif NOECOFF
+}
+
+int
 GetFileInfo(fd, load, xfr, aout,
 	    a_text, a_text_fill, a_data, a_data_fill, a_bss, a_bss_fill)
 	int	fd, *aout;
@@ -675,31 +782,37 @@ GetFileInfo(fd, load, xfr, aout,
 	int	err;
 
 	err = CheckAOutFile(fd);
-
 	if (err == 0) {
 		err = GetAOutFileInfo(fd, load, xfr,
 				      a_text, a_text_fill,
 				      a_data, a_data_fill,
 				      a_bss, a_bss_fill,
 				      aout);
+		return(err != 0 ? -1 : 0);
+	}
+
+	err = CheckECOFFFile(fd);
+	if (err == 0) {
+		err = GetECOFFFileInfo(fd, load, xfr,
+				       a_text, a_text_fill,
+				       a_data, a_data_fill,
+				       a_bss, a_bss_fill,
+				       aout);
+		if (err == 0)
+			*aout = MID_PMAX_ECOFF;
+		return(err != 0 ? -1 : 0);
+	}
+
+	err = CheckMopFile(fd);
+	if (err == 0) {
+		err = GetMopFileInfo(fd, load, xfr);
 		if (err != 0) {
 			return(-1);
-		}
-	} else {
-		err = CheckMopFile(fd);
-		
-		if (err == 0) {
-			err = GetMopFileInfo(fd, load, xfr);
-			if (err != 0) {
-				return(-1);
-			}
-			*aout = -1;
-		} else {
-			return(-1);
 		}
+		*aout = -1;
+		return(0);
 	}
-
-	return(0);
+	return(-1);
 }
 
 ssize_t
Index: common/file.h
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mopd/common/file.h,v
retrieving revision 1.3
diff -p -u -r1.3 file.h
--- file.h	1997/10/16 23:24:37	1.3
+++ file.h	1999/12/30 23:11:02
@@ -48,6 +48,10 @@ int		CheckAOutFile __P((int));
 int		GetAOutFileInfo __P((int, u_int32_t *, u_int32_t *,
 		    u_int32_t *, u_int32_t *, u_int32_t *, u_int32_t *,
 		    u_int32_t *, u_int32_t *, int *));
+int		CheckECOFFFile __P((int));
+int		GetECOFFFileInfo __P((int, u_int32_t *, u_int32_t *,
+		    u_int32_t *, u_int32_t *, u_int32_t *, u_int32_t *,
+		    u_int32_t *, u_int32_t *, int *));
 int		GetFileInfo __P((int, u_int32_t *, u_int32_t *, int *,
 		     u_int32_t *, u_int32_t *, u_int32_t *, u_int32_t *,
 		     u_int32_t *, u_int32_t *));

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <18558.946595822.3@balrog>
Content-Description: common/mop_ecoff.h

#define ECOFF_MAGIC_MIPSEL      0x0162  /* mips1, little-endian */

#define ECOFF_HDR_SIZE (sizeof(struct ecoff_exechdr))

#define ECOFF_ZMAGIC 0413

#define ECOFF_ROUND(value, by) \
        (((value) + (by) - 1) & ~((by) - 1))

#define ECOFF_TXTOFF(ep) \
        ((ep)->a.magic == ECOFF_ZMAGIC ? 0 : \
         ECOFF_ROUND(ECOFF_HDR_SIZE + (ep)->f.f_nscns * \
                     sizeof(struct ecoff_scnhdr), ECOFF_SEGMENT_ALIGNMENT(ep)))

#define ECOFF_DATOFF(ep) \
        (ECOFF_BLOCK_ALIGN((ep), ECOFF_TXTOFF(ep) + (ep)->a.tsize))

#define ECOFF_SEGMENT_ALIGN(ep, value) \
        (ECOFF_ROUND((value), ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_LDPGSZ : \
         ECOFF_SEGMENT_ALIGNMENT(ep))))

#define ECOFF_SEGMENT_ALIGNMENT(ep) ((ep)->a.vstamp < 23 ? 8 : 16)

#define ECOFF_BADMAG(ep) (!((ep)->f.f_magic == ECOFF_MAGIC_MIPSEL))

struct ecoff_filehdr {
        u_int16_t  f_magic;        /* magic number */
        u_int16_t  f_nscns;        /* # of sections */
        u_int32_t  f_timdat;       /* time and date stamp */
        u_int32_t  f_symptr;       /* file offset of symbol table */
        u_int32_t  f_nsyms;        /* # of symbol table entries */
        u_int16_t  f_opthdr;       /* sizeof the optional header */
        u_int16_t  f_flags;        /* flags??? */
};

struct ecoff_aouthdr {
        u_int16_t  magic;
        u_int16_t  vstamp;
        u_int32_t  tsize;
        u_int32_t  dsize;
        u_int32_t  bsize;
        u_int32_t  entry;
        u_int32_t  text_start;
        u_int32_t  data_start;
        u_int32_t  bss_start;
        u_int32_t  gprmask;
        u_int32_t  cprmask[4];
        u_int32_t  gp_value;
};

struct ecoff_scnhdr {              /* needed for size info */
        char       s_name[8];      /* name */
        u_int32_t  s_paddr;        /* physical addr? for ROMing?*/
        u_int32_t  s_vaddr;        /* virtual addr? */
        u_int32_t  s_size;         /* size */
        u_int32_t  s_scnptr;       /* file offset of raw data */
        u_int32_t  s_relptr;       /* file offset of reloc data */
        u_int32_t  s_lnnoptr;      /* file offset of line data */
        u_int16_t  s_nreloc;       /* # of relocation entries */
        u_int16_t  s_nlnno;        /* # of line entries */
        u_int32_t  s_flags;        /* flags */
};

struct ecoff_exechdr {
        struct ecoff_filehdr f;
        struct ecoff_aouthdr a;
};

------- =_aaaaaaaaaa0--