Logo Search packages:      
Sourcecode: palo version File versions

mkbootable.c

/* 
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include "load.h"
#include "palo.h"

#define B32(x)    __be32_to_cpu((x))

static const char Id[] = "$Id: mkbootable.c,v 1.3.4.1 2001/06/13 03:13:17 bame Exp $";

/* compute the sum of words in an 4-byte aligned region */
int
checksum(void *p, size_t len)
{
    int xsum = 0;
    int *x = (int *)p;
    int i;

    if (0) printf("checksum(%p, %u) = ", p, len);
    len /= 4;

    for (i = 0; i < len; i++)
    {
      xsum += B32(x[i]);
    }

    if (0) printf("0x%08x\n", xsum);

    return (xsum);
}

/* maximum allowed HP boot loader (IPL) size */
#define MAXBLSIZE (256 * 1024)

void
fix_bootloader(int out, int bootloader)
{
    size_t rblsize;           /* sector-rounded boot loader size */
    struct loadable loadable;
    int xsum1;
    void *blimage;
    int r;
    int wide;

    memset(&loadable, 0, sizeof loadable);

    r = prepare_loadable(bootloader, &loadable, &wide);
    if (!r)
    {
      fprintf(stderr, "Can't grok your bootloader executable format\n");
      exit(2);
    }

    rblsize = loadable.size;
    printf("entry %p size %d\n", loadable.entry, rblsize);
    rblsize += (FW_BLOCKSIZE - 1);
    rblsize &= ~(FW_BLOCKSIZE - 1);

    if (loadable.entry != loadable.first)
    {
      fprintf(stderr, "Entry point addres %p must be the same as the lowest"
            "address %p\n", loadable.entry, loadable.first);
      exit(2);
    }

    /* IPL max size is 256k */
    if (rblsize > MAXBLSIZE)
      error(5, loadable.size);

    /* load the boot loader into RAM */
    blimage = (void *)calloc(1, MAXBLSIZE);
    assert(blimage != NULL);
    if (!load_loadable(blimage, bootloader, &loadable))
      error(13);

    /* checksum it */
    xsum1 = checksum(blimage, loadable.size);

    /* write checksum into RAM -- see ipl/crt0.S!!! */
    ((int *)blimage)[1] = B32(-xsum1);

    /* write it out */
    seekwrite(out, blimage, rblsize, 0);
    close(bootloader);

    free(blimage);
}

int
main(int argc, char *argv[])
{
    int bootloader = -1;
    int out = -1;

    switch(argc)
    {
    case 1:
      bootloader = fileno(stdin);
      out = fileno(stdout);
      break;
    case 2:
      if ((bootloader = open(argv[1], O_RDONLY)) == -1)
      {
          perror(argv[1]);
          return 2;
      }
      out = fileno(stdout);
      break;
    case 3:
      if ((bootloader = open(argv[1], O_RDONLY)) == -1)
      {
          perror(argv[1]);
          return 2;
      }
      if ((out = open(argv[2], O_RDWR|O_CREAT, 0666)) == -1)
      {
          perror(argv[2]);
          return 2;
      }
      break;
    default:
      fprintf(stderr, "Usage: %s [ipl [bootable_ipl]]\n", argv[0]);
      return 3;
    }

    fix_bootloader(out, bootloader);

    fsync(out);

    return 0;
}

Generated by  Doxygen 1.6.0   Back to index