root/arch/alpha/boot/tools/build.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. die
  2. comp
  3. main

   1 /*
   2  * arch/alpha/boot/tools/build.c
   3  *
   4  * Build a bootable image from the vmlinux binary
   5  */
   6 #include <string.h>
   7 #include <stdio.h>
   8 #include <unistd.h>
   9 #include <fcntl.h>
  10 
  11 #include <a.out.h>
  12 
  13 #include <asm/system.h>
  14 
  15 #define MAXSECT 10
  16 #define MAXBUF 8192
  17 
  18 int verbose = 0;
  19 int pad = 0;
  20 char * program = "tools/build";
  21 char buffer[MAXBUF];
  22 unsigned long bootblock[64];
  23 struct filehdr fhdr;
  24 struct aouthdr ahdr;
  25 struct scnhdr  shdr[MAXSECT];
  26 
  27 char * usage = "'build [-b] system > secondary' or 'build > primary'";
  28 
  29 static void die(char * str)
     /* [<][>][^][v][top][bottom][index][help] */
  30 {
  31         fprintf(stderr,"%s: %s\n", program, str);
  32         exit(1);
  33 }
  34 
  35 static int comp(struct scnhdr * a, struct scnhdr * b)
     /* [<][>][^][v][top][bottom][index][help] */
  36 {
  37         return a->s_vaddr - b->s_vaddr;
  38 }
  39 
  40 int main(int argc, char ** argv)
     /* [<][>][^][v][top][bottom][index][help] */
  41 {
  42         int fd, i;
  43         unsigned long tmp, start;
  44         unsigned long system_start, system_size;
  45         char * infile = NULL;
  46 
  47         system_start = START_ADDR;
  48         system_size = START_SIZE;
  49         if (argc) {
  50                 program = *(argv++);
  51                 argc--;
  52         }
  53         while (argc > 0) {
  54                 if (**argv == '-') {
  55                         while (*++*argv) {
  56                                 switch (**argv) {
  57                                         case 'b':
  58                                                 system_start = BOOT_ADDR;
  59                                                 system_size = BOOT_SIZE;
  60                                                 pad = 1;
  61                                                 break;
  62                                         case 'v':
  63                                                 verbose++;
  64                                                 break;
  65                                         default:
  66                                                 die(usage);
  67                                 }
  68                         }
  69                 } else if (infile)
  70                         die(usage);
  71                 else
  72                         infile = *argv;
  73                 argv++;
  74                 argc--;
  75         }
  76         if (!infile) {
  77                 memcpy(bootblock, "Linux Test", 10);
  78                 bootblock[60] = BOOT_SIZE / 512;        /* count */
  79                 bootblock[61] = 1;                      /* starting LBM */
  80                 bootblock[62] = 0;                      /* flags */
  81                 tmp = 0;
  82                 for (i = 0 ; i < 63 ; i++)
  83                         tmp += bootblock[i];
  84                 bootblock[63] = tmp;
  85                 if (write(1, (char *) bootblock, 512) != 512) {
  86                         perror("bbwrite");
  87                         exit(1);
  88                 }
  89                 return 0;
  90         }
  91         fd = open(infile, O_RDONLY);
  92         if (fd < 0) {
  93                 perror(infile);
  94                 exit(1);
  95         }
  96         if (read(fd, &fhdr, sizeof(struct filehdr)) != sizeof(struct filehdr))
  97                 die("unable to read file header");
  98         if (fhdr.f_nscns > MAXSECT)
  99                 die("Too many sections");
 100         if (fhdr.f_opthdr != AOUTHSZ)
 101                 die("optional header doesn't look like a.out");
 102         if (read(fd, &ahdr, sizeof(struct aouthdr)) != sizeof(struct aouthdr))
 103                 die("unable to read a.out header");
 104         for (i = 0 ; i < fhdr.f_nscns ; i++) {
 105                 if (read(fd, i+shdr, sizeof(struct scnhdr)) != sizeof(struct scnhdr))
 106                         die("unable to read section header");
 107                 if (shdr[i].s_paddr != shdr[i].s_vaddr)
 108                         die("unable to handle different phys/virt addresses");
 109                 if (shdr[i].s_relptr)
 110                         die("Unable to handle relocation info");
 111                 if (verbose) {
 112                         fprintf(stderr, "section %d (%.8s):\t%lx - %lx (at %x)\n",
 113                                 i, shdr[i].s_name,
 114                                 shdr[i].s_vaddr,
 115                                 shdr[i].s_vaddr + shdr[i].s_size,
 116                                 shdr[i].s_scnptr);
 117                 }
 118         }
 119         qsort(shdr, fhdr.f_nscns, sizeof(shdr[1]), comp);
 120         start = system_start;
 121         for (i = 0 ; i < fhdr.f_nscns ; i++) {
 122                 unsigned long size, offset;
 123                 memset(buffer, 0, MAXBUF);
 124                 if (!strcmp(shdr[i].s_name, ".comment"))
 125                         continue;
 126                 if (shdr[i].s_vaddr != start)
 127                         die("Unordered or badly placed segments");
 128                 size = shdr[i].s_size;
 129                 start += size;
 130                 offset = shdr[i].s_scnptr;
 131                 if (lseek(fd, offset, SEEK_SET) != offset)
 132                         die("Unable to seek in in-file");
 133                 while (size > 0) {
 134                         unsigned long num = size;
 135                         if (num > MAXBUF)
 136                                 num = MAXBUF;
 137                         if (offset)
 138                                 if (read(fd, buffer, num) != num)
 139                                         die("partial read");
 140                         if (write(1, buffer, num) != num)
 141                                 die("partial write");
 142                         size -= num;
 143                 }
 144                 if (verbose) {
 145                         fprintf(stderr, "section %d (%.8s):\t%lx - %lx (at %x)\n",
 146                                 i, shdr[i].s_name,
 147                                 shdr[i].s_vaddr,
 148                                 shdr[i].s_vaddr + shdr[i].s_size,
 149                                 shdr[i].s_scnptr);
 150                 }
 151         }
 152         if (start > system_start + system_size) {
 153                 fprintf(stderr, "Boot image too large\n");
 154                 exit(1);
 155         }
 156         if (pad) {
 157                 unsigned long count = (system_start + system_size) - start;
 158                 memset(buffer, 0, MAXBUF);
 159                 while (count > 0) {
 160                         int i = MAXBUF;
 161                         if (i > count)
 162                                 i = count;
 163                         i = write(1, buffer, i);
 164                         if (i <= 0) {
 165                                 perror("pad write");
 166                                 exit(1);
 167                         }
 168                         count -= i;
 169                 }
 170         }
 171                 
 172         return 0;
 173 }

/* [<][>][^][v][top][bottom][index][help] */