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

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

/* [previous][next][first][last][top][bottom][index][help] */