linux/arch/mn10300/boot/tools/build.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 1991, 1992  Linus Torvalds
   3 *  Copyright (C) 1997 Martin Mares
   4 */
   5
   6/*
   7 * This file builds a disk-image from three different files:
   8 *
   9 * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
  10 * - setup: 8086 machine code, sets up system parm
  11 * - system: 80386 code for actual system
  12 *
  13 * It does some checking that all files are of the correct type, and
  14 * just writes the result to stdout, removing headers and padding to
  15 * the right amount. It also writes some system data to stderr.
  16 */
  17
  18/*
  19 * Changes by tytso to allow root device specification
  20 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  21 * Cross compiling fixes by Gertjan van Wingerde, July 1996
  22 * Rewritten by Martin Mares, April 1997
  23 */
  24
  25#include <stdio.h>
  26#include <string.h>
  27#include <stdlib.h>
  28#include <stdarg.h>
  29#include <sys/types.h>
  30#include <sys/stat.h>
  31#include <sys/sysmacros.h>
  32#include <unistd.h>
  33#include <fcntl.h>
  34#include <asm/boot.h>
  35
  36#define DEFAULT_MAJOR_ROOT 0
  37#define DEFAULT_MINOR_ROOT 0
  38
  39/* Minimal number of setup sectors (see also bootsect.S) */
  40#define SETUP_SECTS 4
  41
  42uint8_t buf[1024];
  43int fd;
  44int is_big_kernel;
  45
  46__attribute__((noreturn))
  47void die(const char *str, ...)
  48{
  49        va_list args;
  50        va_start(args, str);
  51        vfprintf(stderr, str, args);
  52        fputc('\n', stderr);
  53        exit(1);
  54}
  55
  56void file_open(const char *name)
  57{
  58        fd = open(name, O_RDONLY, 0);
  59        if (fd < 0)
  60                die("Unable to open `%s': %m", name);
  61}
  62
  63__attribute__((noreturn))
  64void usage(void)
  65{
  66        die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
  67}
  68
  69int main(int argc, char **argv)
  70{
  71        unsigned int i, c, sz, setup_sectors;
  72        uint32_t sys_size;
  73        uint8_t major_root, minor_root;
  74        struct stat sb;
  75
  76        if (argc > 2 && !strcmp(argv[1], "-b")) {
  77                is_big_kernel = 1;
  78                argc--, argv++;
  79        }
  80        if ((argc < 4) || (argc > 5))
  81                usage();
  82        if (argc > 4) {
  83                if (!strcmp(argv[4], "CURRENT")) {
  84                        if (stat("/", &sb)) {
  85                                perror("/");
  86                                die("Couldn't stat /");
  87                        }
  88                        major_root = major(sb.st_dev);
  89                        minor_root = minor(sb.st_dev);
  90                } else if (strcmp(argv[4], "FLOPPY")) {
  91                        if (stat(argv[4], &sb)) {
  92                                perror(argv[4]);
  93                                die("Couldn't stat root device.");
  94                        }
  95                        major_root = major(sb.st_rdev);
  96                        minor_root = minor(sb.st_rdev);
  97                } else {
  98                        major_root = 0;
  99                        minor_root = 0;
 100                }
 101        } else {
 102                major_root = DEFAULT_MAJOR_ROOT;
 103                minor_root = DEFAULT_MINOR_ROOT;
 104        }
 105        fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
 106
 107        file_open(argv[1]);
 108        i = read(fd, buf, sizeof(buf));
 109        fprintf(stderr, "Boot sector %d bytes.\n", i);
 110        if (i != 512)
 111                die("Boot block must be exactly 512 bytes");
 112        if (buf[510] != 0x55 || buf[511] != 0xaa)
 113                die("Boot block hasn't got boot flag (0xAA55)");
 114        buf[508] = minor_root;
 115        buf[509] = major_root;
 116        if (write(1, buf, 512) != 512)
 117                die("Write call failed");
 118        close(fd);
 119
 120        /* Copy the setup code */
 121        file_open(argv[2]);
 122        for (i = 0; (c = read(fd, buf, sizeof(buf))) > 0; i += c)
 123                if (write(1, buf, c) != c)
 124                        die("Write call failed");
 125        if (c != 0)
 126                die("read-error on `setup'");
 127        close(fd);
 128
 129        /* Pad unused space with zeros */
 130        setup_sectors = (i + 511) / 512;
 131        /* for compatibility with ancient versions of LILO. */
 132        if (setup_sectors < SETUP_SECTS)
 133                setup_sectors = SETUP_SECTS;
 134        fprintf(stderr, "Setup is %d bytes.\n", i);
 135        memset(buf, 0, sizeof(buf));
 136        while (i < setup_sectors * 512) {
 137                c = setup_sectors * 512 - i;
 138                if (c > sizeof(buf))
 139                        c = sizeof(buf);
 140                if (write(1, buf, c) != c)
 141                        die("Write call failed");
 142                i += c;
 143        }
 144
 145        file_open(argv[3]);
 146        if (fstat(fd, &sb))
 147                die("Unable to stat `%s': %m", argv[3]);
 148        sz = sb.st_size;
 149        fprintf(stderr, "System is %d kB\n", sz / 1024);
 150        sys_size = (sz + 15) / 16;
 151        /* 0x28000*16 = 2.5 MB, conservative estimate for the current maximum */
 152        if (sys_size > (is_big_kernel ? 0x28000 : DEF_SYSSIZE))
 153                die("System is too big. Try using %smodules.",
 154                        is_big_kernel ? "" : "bzImage or ");
 155        if (sys_size > 0xffff)
 156                fprintf(stderr,
 157                        "warning: kernel is too big for standalone boot "
 158                        "from floppy\n");
 159        while (sz > 0) {
 160                int l, n;
 161
 162                l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
 163                n = read(fd, buf, l);
 164                if (n != l) {
 165                        if (n < 0)
 166                                die("Error reading %s: %m", argv[3]);
 167                        else
 168                                die("%s: Unexpected EOF", argv[3]);
 169                }
 170                if (write(1, buf, l) != l)
 171                        die("Write failed");
 172                sz -= l;
 173        }
 174        close(fd);
 175
 176        /* Write sizes to the bootsector */
 177        if (lseek(1, 497, SEEK_SET) != 497)
 178                die("Output: seek failed");
 179        buf[0] = setup_sectors;
 180        if (write(1, buf, 1) != 1)
 181                die("Write of setup sector count failed");
 182        if (lseek(1, 500, SEEK_SET) != 500)
 183                die("Output: seek failed");
 184        buf[0] = (sys_size & 0xff);
 185        buf[1] = ((sys_size >> 8) & 0xff);
 186        if (write(1, buf, 2) != 2)
 187                die("Write of image length failed");
 188
 189        return 0;
 190}
 191