summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tsbogend@alpha.franken.de>1999-03-13 12:36:50 +0000
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>1999-03-13 12:36:50 +0000
commit7b2037ffa9bf8e4b6c9364a1af6a88ce81b390c8 (patch)
tree3a4c734af572d17f4d64c99a7092e2cb5eaef9a5
parentf02f774aaa8e21f2bc841fe136b0abd9036220bb (diff)
added addinitrd, a utility to generate kernels combined with a initrd image
-rw-r--r--arch/mips/boot/Makefile10
-rw-r--r--arch/mips/boot/addinitrd.c112
-rw-r--r--arch/mips/boot/ecoff.h62
-rw-r--r--arch/mips/boot/elf2ecoff.c64
4 files changed, 181 insertions, 67 deletions
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index 64a242a38..65217c2c5 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.6 1999/02/25 21:44:46 tsbogend Exp $
+# $Id: Makefile,v 1.7 1999/03/09 21:33:21 tsbogend Exp $
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
@@ -21,15 +21,17 @@ OBJS = milo.o a.out.o
drop-sections = .reginfo .mdebug
strip-flags = $(addprefix --remove-section=,$(drop-sections))
-#
-# Fake compressed boot
-#
+all: vmlinux.ecoff addinitrd
+
vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff
elf2ecoff: elf2ecoff.c
$(HOSTCC) -o $@ $^
+addinitrd: addinitrd.c
+ $(HOSTCC) -o $@ $^
+
# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
diff --git a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c
new file mode 100644
index 000000000..0ddaf39f0
--- /dev/null
+++ b/arch/mips/boot/addinitrd.c
@@ -0,0 +1,112 @@
+/*
+ * addinitrd - program to add a initrd image to an ecoff kernel
+ *
+ * (C) 1999 Thomas Bogendoerfer
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "ecoff.h"
+
+#define MIPS_PAGE_SIZE 4096
+#define MIPS_PAGE_MASK (MIPS_PAGE_SIZE-1)
+
+#define swab16(x) \
+ ((unsigned short)( \
+ (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+ (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
+
+#define swab32(x) \
+ ((unsigned int)( \
+ (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+ (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
+ (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
+ (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
+
+#define SWAB(a) (swab ? swab32(a) : (a))
+
+void die (char *s)
+{
+ perror (s);
+ exit (1);
+}
+
+int main (int argc, char *argv[])
+{
+ int fd_vmlinux,fd_initrd,fd_outfile;
+ FILHDR efile;
+ AOUTHDR eaout;
+ SCNHDR esecs[3];
+ struct stat st;
+ char buf[1024];
+ unsigned long loadaddr;
+ unsigned long initrd_header[2];
+ int i;
+ int swab = 0;
+
+ if (argc != 4) {
+ printf ("Usage: %s <vmlinux> <initrd> <outfile>\n",argv[0]);
+ exit (1);
+ }
+
+ if ((fd_vmlinux = open (argv[1],O_RDWR)) < 0)
+ die ("open vmlinux");
+ if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
+ die ("read file header");
+ if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
+ die ("read aout header");
+ if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
+ die ("read section headers");
+
+ /*
+ * check whether the file is good for us
+ */
+ /* TBD */
+
+ /*
+ * check, if we have to swab words
+ */
+ if (ntohs(0xaa55) == 0xaa55) {
+ if (efile.f_magic == swab16(MIPSELMAGIC))
+ swab = 1;
+ } else {
+ if (efile.f_magic == swab16(MIPSEBMAGIC))
+ swab = 1;
+ }
+
+ if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
+ die ("open initrd");
+ if (fstat (fd_initrd, &st) < 0)
+ die ("fstat initrd");
+ loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
+ + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
+ if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
+ loadaddr += MIPS_PAGE_SIZE;
+ initrd_header[0] = SWAB(0x494E5244);
+ initrd_header[1] = SWAB(st.st_size);
+ eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
+ eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
+
+ if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC,0666)) < 0)
+ die ("open outfile");
+ if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
+ die ("write file header");
+ if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
+ die ("write aout header");
+ if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
+ die ("write section headers");
+ while ((i = read (fd_vmlinux, buf, sizeof buf)) > 0)
+ if (write (fd_outfile, buf, i) != i)
+ die ("write vmlinux");
+ if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
+ die ("write initrd header");
+ while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
+ if (write (fd_outfile, buf, i) != i)
+ die ("write initrd");
+ close (fd_vmlinux);
+ close (fd_initrd);
+ return 0;
+}
diff --git a/arch/mips/boot/ecoff.h b/arch/mips/boot/ecoff.h
new file mode 100644
index 000000000..8c3eed287
--- /dev/null
+++ b/arch/mips/boot/ecoff.h
@@ -0,0 +1,62 @@
+/*
+ * Some ECOFF definitions.
+ */
+typedef struct filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ long f_symptr; /* file pointer to symbolic header */
+ long f_nsyms; /* sizeof(symbolic hdr) */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+} FILHDR;
+#define FILHSZ sizeof(FILHDR)
+
+#define OMAGIC 0407
+#define MIPSEBMAGIC 0x160
+#define MIPSELMAGIC 0x162
+
+typedef struct scnhdr {
+ char s_name[8]; /* section name */
+ long s_paddr; /* physical address, aliased s_nlib */
+ long s_vaddr; /* virtual address */
+ long s_size; /* section size */
+ long s_scnptr; /* file ptr to raw data for section */
+ long s_relptr; /* file ptr to relocation */
+ long s_lnnoptr; /* file ptr to gp histogram */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of gp histogram entries */
+ long s_flags; /* flags */
+} SCNHDR;
+#define SCNHSZ sizeof(SCNHDR)
+#define SCNROUND ((long)16)
+
+typedef struct aouthdr {
+ short magic; /* see above */
+ short vstamp; /* version stamp */
+ long tsize; /* text size in bytes, padded to DW bdry*/
+ long dsize; /* initialized data " " */
+ long bsize; /* uninitialized data " " */
+ long entry; /* entry pt. */
+ long text_start; /* base of text used for this file */
+ long data_start; /* base of data used for this file */
+ long bss_start; /* base of bss used for this file */
+ long gprmask; /* general purpose register mask */
+ long cprmask[4]; /* co-processor register masks */
+ long gp_value; /* the gp value used for this object */
+} AOUTHDR;
+#define AOUTHSZ sizeof(AOUTHDR)
+
+#define OMAGIC 0407
+#define NMAGIC 0410
+#define ZMAGIC 0413
+#define SMAGIC 0411
+#define LIBMAGIC 0443
+
+#define N_TXTOFF(f, a) \
+ ((a).magic == ZMAGIC || (a).magic == LIBMAGIC ? 0 : \
+ ((a).vstamp < 23 ? \
+ ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + 7) & 0xfffffff8) : \
+ ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + SCNROUND-1) & ~(SCNROUND-1)) ) )
+#define N_DATOFF(f, a) \
+ N_TXTOFF(f, a) + (a).tsize;
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
index 0dbe97004..d33aec395 100644
--- a/arch/mips/boot/elf2ecoff.c
+++ b/arch/mips/boot/elf2ecoff.c
@@ -41,71 +41,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
-//#include <sys/exec_ecoff.h>
#include <limits.h>
-/*
- * Some ECOFF definitions. Just enough to compile this program.
- */
-typedef struct filehdr {
- unsigned short f_magic; /* magic number */
- unsigned short f_nscns; /* number of sections */
- long f_timdat; /* time & date stamp */
- long f_symptr; /* file pointer to symbolic header */
- long f_nsyms; /* sizeof(symbolic hdr) */
- unsigned short f_opthdr; /* sizeof(optional hdr) */
- unsigned short f_flags; /* flags */
-} FILHDR;
-#define FILHSZ sizeof(FILHDR)
-
-#define OMAGIC 0407
-#define MIPSEBMAGIC 0x160
-#define MIPSELMAGIC 0x162
-
-typedef struct scnhdr {
- char s_name[8]; /* section name */
- long s_paddr; /* physical address, aliased s_nlib */
- long s_vaddr; /* virtual address */
- long s_size; /* section size */
- long s_scnptr; /* file ptr to raw data for section */
- long s_relptr; /* file ptr to relocation */
- long s_lnnoptr; /* file ptr to gp histogram */
- unsigned short s_nreloc; /* number of relocation entries */
- unsigned short s_nlnno; /* number of gp histogram entries */
- long s_flags; /* flags */
-} SCNHDR;
-#define SCNHSZ sizeof(SCNHDR)
-#define SCNROUND ((long)16)
-
-typedef struct aouthdr {
- short magic; /* see above */
- short vstamp; /* version stamp */
- long tsize; /* text size in bytes, padded to DW bdry*/
- long dsize; /* initialized data " " */
- long bsize; /* uninitialized data " " */
- long entry; /* entry pt. */
- long text_start; /* base of text used for this file */
- long data_start; /* base of data used for this file */
- long bss_start; /* base of bss used for this file */
- long gprmask; /* general purpose register mask */
- long cprmask[4]; /* co-processor register masks */
- long gp_value; /* the gp value used for this object */
-} AOUTHDR;
-#define AOUTHSZ sizeof(AOUTHDR)
-
-#define OMAGIC 0407
-#define NMAGIC 0410
-#define ZMAGIC 0413
-#define SMAGIC 0411
-#define LIBMAGIC 0443
-
-#define N_TXTOFF(f, a) \
- ((a).magic == ZMAGIC || (a).magic == LIBMAGIC ? 0 : \
- ((a).vstamp < 23 ? \
- ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + 7) & 0xfffffff8) : \
- ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + SCNROUND-1) & ~(SCNROUND-1)) ) )
-#define N_DATOFF(f, a) \
- N_TXTOFF(f, a) + (a).tsize;
+#include "ecoff.h"
/*
* Some extra ELF definitions