linux/arch/mips/boot/addinitrd.c
<<
>>
Prefs
   1/*
   2 * addinitrd - program to add a initrd image to an ecoff kernel
   3 *
   4 * (C) 1999 Thomas Bogendoerfer
   5 * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
   6 * further cleanup: Maciej W. Rozycki
   7 */
   8
   9#include <sys/types.h>
  10#include <sys/stat.h>
  11#include <fcntl.h>
  12#include <unistd.h>
  13#include <stdio.h>
  14#include <netinet/in.h>
  15
  16#include "ecoff.h"
  17
  18#define MIPS_PAGE_SIZE  4096
  19#define MIPS_PAGE_MASK  (MIPS_PAGE_SIZE-1)
  20
  21#define swab16(x) \
  22        ((unsigned short)( \
  23                (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
  24                (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
  25
  26#define swab32(x) \
  27        ((unsigned int)( \
  28                (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
  29                (((unsigned int)(x) & (unsigned int)0x0000ff00UL) <<  8) | \
  30                (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
  31                (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
  32
  33#define SWAB(a) (swab ? swab32(a) : (a))
  34
  35void die(char *s)
  36{
  37        perror(s);
  38        exit(1);
  39}
  40
  41int main(int argc, char *argv[])
  42{
  43        int fd_vmlinux, fd_initrd, fd_outfile;
  44        FILHDR efile;
  45        AOUTHDR eaout;
  46        SCNHDR esecs[3];
  47        struct stat st;
  48        char buf[1024];
  49        unsigned long loadaddr;
  50        unsigned long initrd_header[2];
  51        int i, cnt;
  52        int swab = 0;
  53
  54        if (argc != 4) {
  55                printf("Usage: %s <vmlinux> <initrd> <outfile>\n", argv[0]);
  56                exit(1);
  57        }
  58
  59        if ((fd_vmlinux = open (argv[1], O_RDONLY)) < 0)
  60                 die("open vmlinux");
  61        if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
  62                die("read file header");
  63        if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
  64                die("read aout header");
  65        if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
  66                die("read section headers");
  67        /*
  68         * check whether the file is good for us
  69         */
  70        /* TBD */
  71
  72        /*
  73         * check, if we have to swab words
  74         */
  75        if (ntohs(0xaa55) == 0xaa55) {
  76                if (efile.f_magic == swab16(MIPSELMAGIC))
  77                        swab = 1;
  78        } else {
  79                if (efile.f_magic == swab16(MIPSEBMAGIC))
  80                        swab = 1;
  81        }
  82
  83        /* make sure we have an empty data segment for the initrd */
  84        if (eaout.dsize || esecs[1].s_size) {
  85                fprintf(stderr, "Data segment not empty. Giving up!\n");
  86                exit(1);
  87        }
  88        if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
  89                die("open initrd");
  90        if (fstat (fd_initrd, &st) < 0)
  91                die("fstat initrd");
  92        loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
  93                        + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
  94        if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
  95                loadaddr += MIPS_PAGE_SIZE;
  96        initrd_header[0] = SWAB(0x494E5244);
  97        initrd_header[1] = SWAB(st.st_size);
  98        eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
  99        eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
 100
 101        if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
 102                die("open outfile");
 103        if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
 104                die("write file header");
 105        if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
 106                die("write aout header");
 107        if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
 108                die("write section headers");
 109        /* skip padding */
 110        if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
 111                die("lseek vmlinux");
 112        if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
 113                die("lseek outfile");
 114        /* copy text segment */
 115        cnt = SWAB(eaout.tsize);
 116        while (cnt) {
 117                if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
 118                        die("read vmlinux");
 119                if (write (fd_outfile, buf, i) != i)
 120                        die("write vmlinux");
 121                cnt -= i;
 122        }
 123        if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
 124                die("write initrd header");
 125        while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
 126                if (write (fd_outfile, buf, i) != i)
 127                        die("write initrd");
 128        close(fd_vmlinux);
 129        close(fd_initrd);
 130        return 0;
 131}
 132