linux/arch/cris/boot/tools/build.c
<<
>>
Prefs
   1/*
   2 *  linux/tools/build.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 */
   6
   7/*
   8 * This file builds a disk-image from three different files:
   9 *
  10 * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
  11 * - setup: 8086 machine code, sets up system parm
  12 * - system: 80386 code for actual system
  13 *
  14 * It does some checking that all files are of the correct type, and
  15 * just writes the result to stdout, removing headers and padding to
  16 * the right amount. It also writes some system data to stderr.
  17 */
  18
  19/*
  20 * Changes by tytso to allow root device specification
  21 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  22 * Cross compiling fixes by Gertjan van Wingerde, July 1996
  23 */
  24
  25#include <stdio.h>      /* fprintf */
  26#include <string.h>
  27#include <stdlib.h>     /* contains exit */
  28#include <sys/types.h>  /* unistd.h needs this */
  29#include <sys/stat.h>
  30#include <sys/sysmacros.h>
  31#include <unistd.h>     /* contains read/write */
  32#include <fcntl.h>
  33#include <errno.h>
  34
  35#define MINIX_HEADER 32
  36
  37#define N_MAGIC_OFFSET 1024
  38#ifndef __BFD__
  39static int GCC_HEADER = sizeof(struct exec);
  40#endif
  41
  42#ifdef __BIG_KERNEL__
  43#define SYS_SIZE 0xffff
  44#else
  45#define SYS_SIZE DEF_SYSSIZE
  46#endif
  47
  48#define DEFAULT_MAJOR_ROOT 0
  49#define DEFAULT_MINOR_ROOT 0
  50
  51/* max nr of sectors of setup: don't change unless you also change
  52 * bootsect etc */
  53#define SETUP_SECTS 4
  54
  55#define STRINGIFY(x) #x
  56
  57typedef union {
  58        int i;
  59        long l;
  60        short s[2];
  61        char b[4];
  62} conv;
  63
  64long intel_long(long l)
  65{
  66        conv t;
  67
  68        t.b[0] = l & 0xff; l >>= 8;
  69        t.b[1] = l & 0xff; l >>= 8;
  70        t.b[2] = l & 0xff; l >>= 8;
  71        t.b[3] = l & 0xff; l >>= 8;
  72        return t.l;
  73}
  74
  75int intel_int(int i)
  76{
  77        conv t;
  78
  79        t.b[0] = i & 0xff; i >>= 8;
  80        t.b[1] = i & 0xff; i >>= 8;
  81        t.b[2] = i & 0xff; i >>= 8;
  82        t.b[3] = i & 0xff; i >>= 8;
  83        return t.i;
  84}
  85
  86short intel_short(short l)
  87{
  88        conv t;
  89
  90        t.b[0] = l & 0xff; l >>= 8;
  91        t.b[1] = l & 0xff; l >>= 8;
  92        return t.s[0];
  93}
  94
  95void die(const char * str)
  96{
  97        fprintf(stderr,"%s\n",str);
  98        exit(1);
  99}
 100
 101void usage(void)
 102{
 103        die("Usage: build bootsect setup system [rootdev] [> image]");
 104}
 105
 106int main(int argc, char ** argv)
 107{
 108        int i,c,id,sz,tmp_int;
 109        unsigned long sys_size, tmp_long;
 110        char buf[1024];
 111#ifndef __BFD__
 112        struct exec *ex = (struct exec *)buf;
 113#endif
 114        char major_root, minor_root;
 115        struct stat sb;
 116        unsigned char setup_sectors;
 117
 118        if ((argc < 4) || (argc > 5))
 119                usage();
 120        if (argc > 4) {
 121                if (!strcmp(argv[4], "CURRENT")) {
 122                        if (stat("/", &sb)) {
 123                                perror("/");
 124                                die("Couldn't stat /");
 125                        }
 126                        major_root = major(sb.st_dev);
 127                        minor_root = minor(sb.st_dev);
 128                } else if (strcmp(argv[4], "FLOPPY")) {
 129                        if (stat(argv[4], &sb)) {
 130                                perror(argv[4]);
 131                                die("Couldn't stat root device.");
 132                        }
 133                        major_root = major(sb.st_rdev);
 134                        minor_root = minor(sb.st_rdev);
 135                } else {
 136                        major_root = 0;
 137                        minor_root = 0;
 138                }
 139        } else {
 140                major_root = DEFAULT_MAJOR_ROOT;
 141                minor_root = DEFAULT_MINOR_ROOT;
 142        }
 143        fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
 144        for (i=0;i<sizeof buf; i++) buf[i]=0;
 145        if ((id=open(argv[1],O_RDONLY,0))<0)
 146                die("Unable to open 'boot'");
 147        if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
 148                die("Unable to read header of 'boot'");
 149        if (((long *) buf)[0]!=intel_long(0x04100301))
 150                die("Non-Minix header of 'boot'");
 151        if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
 152                die("Non-Minix header of 'boot'");
 153        if (((long *) buf)[3] != 0)
 154                die("Illegal data segment in 'boot'");
 155        if (((long *) buf)[4] != 0)
 156                die("Illegal bss in 'boot'");
 157        if (((long *) buf)[5] != 0)
 158                die("Non-Minix header of 'boot'");
 159        if (((long *) buf)[7] != 0)
 160                die("Illegal symbol table in 'boot'");
 161        i=read(id,buf,sizeof buf);
 162        fprintf(stderr,"Boot sector %d bytes.\n",i);
 163        if (i != 512)
 164                die("Boot block must be exactly 512 bytes");
 165        if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
 166                die("Boot block hasn't got boot flag (0xAA55)");
 167        buf[508] = (char) minor_root;
 168        buf[509] = (char) major_root;   
 169        i=write(1,buf,512);
 170        if (i!=512)
 171                die("Write call failed");
 172        close (id);
 173        
 174        if ((id=open(argv[2],O_RDONLY,0))<0)
 175                die("Unable to open 'setup'");
 176        if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
 177                die("Unable to read header of 'setup'");
 178        if (((long *) buf)[0]!=intel_long(0x04100301))
 179                die("Non-Minix header of 'setup'");
 180        if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
 181                die("Non-Minix header of 'setup'");
 182        if (((long *) buf)[3] != 0)
 183                die("Illegal data segment in 'setup'");
 184        if (((long *) buf)[4] != 0)
 185                die("Illegal bss in 'setup'");
 186        if (((long *) buf)[5] != 0)
 187                die("Non-Minix header of 'setup'");
 188        if (((long *) buf)[7] != 0)
 189                die("Illegal symbol table in 'setup'");
 190        for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
 191#ifdef __BIG_KERNEL__
 192        {
 193                if (!i) {
 194                        /* Working with memcpy because of alignment constraints
 195                           on Sparc - Gertjan */
 196                        memcpy(&tmp_long, &buf[2], sizeof(long));
 197                        if (tmp_long != intel_long(0x53726448) )
 198                                die("Wrong magic in loader header of 'setup'");
 199                        memcpy(&tmp_int, &buf[6], sizeof(int));
 200                        if (tmp_int < intel_int(0x200))
 201                                die("Wrong version of loader header of 'setup'");
 202                        buf[0x11] = 1; /* LOADED_HIGH */
 203                        tmp_long = intel_long(0x100000);
 204                        memcpy(&buf[0x14], &tmp_long, sizeof(long));  /* code32_start */
 205                }
 206#endif
 207                if (write(1,buf,c)!=c)
 208                        die("Write call failed");
 209#ifdef __BIG_KERNEL__
 210        }
 211#endif
 212        if (c != 0)
 213                die("read-error on 'setup'");
 214        close (id);
 215        setup_sectors = (unsigned char)((i + 511) / 512);
 216        /* for compatibility with LILO */
 217        if (setup_sectors < SETUP_SECTS)
 218                setup_sectors = SETUP_SECTS;
 219        fprintf(stderr,"Setup is %d bytes.\n",i);
 220        for (c=0 ; c<sizeof(buf) ; c++)
 221                buf[c] = '\0';
 222        while (i < setup_sectors * 512) {
 223                c = setup_sectors * 512 - i;
 224                if (c > sizeof(buf))
 225                        c = sizeof(buf);
 226                if (write(1,buf,c) != c)
 227                        die("Write call failed");
 228                i += c;
 229        }
 230        
 231        if ((id=open(argv[3],O_RDONLY,0))<0)
 232                die("Unable to open 'system'");
 233#ifndef __BFD__
 234        if (read(id,buf,GCC_HEADER) != GCC_HEADER)
 235                die("Unable to read header of 'system'");
 236        if (N_MAGIC(*ex) == ZMAGIC) {
 237                GCC_HEADER = N_MAGIC_OFFSET;
 238                lseek(id, GCC_HEADER, SEEK_SET);
 239        } else if (N_MAGIC(*ex) != QMAGIC)
 240                die("Non-GCC header of 'system'");
 241        fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
 242                (ex->a_text+ex->a_data+ex->a_bss)/1024,
 243                ex->a_text /1024,
 244                ex->a_data /1024,
 245                ex->a_bss  /1024);
 246        sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
 247#else
 248        if (fstat (id, &sb)) {
 249          perror ("fstat");
 250          die ("Unable to stat 'system'");
 251        }
 252        sz = sb.st_size;
 253        fprintf (stderr, "System is %d kB\n", sz/1024);
 254#endif
 255        sys_size = (sz + 15) / 16;
 256        if (sys_size > SYS_SIZE)
 257                die("System is too big");
 258        while (sz > 0) {
 259                int l, n;
 260
 261                l = sz;
 262                if (l > sizeof(buf))
 263                        l = sizeof(buf);
 264                if ((n=read(id, buf, l)) != l) {
 265                        if (n == -1) 
 266                                perror(argv[1]);
 267                        else
 268                                fprintf(stderr, "Unexpected EOF\n");
 269                        die("Can't read 'system'");
 270                }
 271                if (write(1, buf, l) != l)
 272                        die("Write failed");
 273                sz -= l;
 274        }
 275        close(id);
 276        if (lseek(1, 497, 0) == 497) {
 277                if (write(1, &setup_sectors, 1) != 1)
 278                        die("Write of setup sectors failed");
 279        }
 280        if (lseek(1,500,0) == 500) {
 281                buf[0] = (sys_size & 0xff);
 282                buf[1] = ((sys_size >> 8) & 0xff);
 283                if (write(1, buf, 2) != 2)
 284                        die("Write failed");
 285        }
 286        return(0);
 287}
 288