On Fri, Nov 01, 2002 at 08:58:50AM -0800, Brian Macy wrote:
> I just noticed the flash module. I don't see any instructions on how to 
> use it (just dd an image?) or on how to extract the image from the sun 
> supplied upgrade executable.

I can't recall where the program is to write flash (I used to have it
around), but you should be able to find it with a google search real
easy. As for extracting an OBP flash from a Sun update, use the attached
program I write awhile back to do exactly that.

This program could probably be done more easily using objdump, but I
like writing code, so here it is.

-- 
Debian     - http://www.debian.org/
Linux 1394 - http://www.linux1394.org/
Subversion - http://subversion.tigris.org/
Deqo       - http://www.deqo.com/
/* Extract an OBP flash file from a Sun stand-alone update */

/* (C) 2001 Ben Collins <[EMAIL PROTECTED]> */

/* Licensed under the GPLv2 */

/* Sun supplies OBP flash updates via their SunSolve website. These files
 * are stand-alone programs that you boot in order to install the flash.
 * I've tried booting one of these via SILO, but it doesn't work (maybe
 * SILO can be made to do that?).
 *
 * Anyway, the OBP flash consists of two segments, OBP and POST, each 512k
 * bytes long (although it does not actually use all of that). Each of
 * these segments is stored in the .text section of the Sun flash update
 * program. This program basically searches for the first occurence of the
 * flash magic (OBMD), copies 512k from that point, and starts searching
 * for the second segment after that. Pretty simple.
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>

struct obp {
        char            magic[4];       /* OBMD */
        unsigned int    size;
        unsigned int    checksum;
        unsigned int    __unknown2;
        char            name[4];        /* OBP or POST */
        unsigned int    year;
        unsigned char   mon;
        unsigned char   mday;
        unsigned char   hour;
        unsigned char   min;
        unsigned char   major;
        unsigned char   minor;
        unsigned char   patchlevel;
        unsigned char   __unknown3;
};

#define FLASH_SIZE (1024*1024)

static void print_obp_info(struct obp *obp)
{
        printf("%-4s\tVersion: %d.%d.%-3d\t%04d/%02d/%02d %02d:%02d\n",
                        obp->name, obp->major, obp->minor, obp->patchlevel,
                        obp->year, obp->mon, obp->mday, obp->hour, obp->min);
        printf("\tSize: %u\n\tChecksum: %04X\n", obp->size, obp->checksum);
        return;
}

int main(int argc, char *argv[])
{
        unsigned char *data;
        unsigned int size;
        int fdin, fdout, i;
        char *outfile = "flash-stripped";
        struct obp *obp;

        if (argc != 2 && argc != 3) {
                fprintf(stderr, "Usage: extract-flash <flash-update> [output 
file]\n");
                exit(1);
        }

        if (argc == 3) {
                outfile = argv[2];
                if (unlink(outfile)) {
                        perror(outfile);
                        exit(1);
                }
        }

        fdin = open(argv[1], O_RDONLY);
        if (fdin < 0) {
                perror(argv[1]);
                exit(1);
        }

        fdout = open(outfile, O_WRONLY|O_CREAT|O_EXCL, 0644);
        if (fdout < 0) {
                perror(outfile);
                exit(1);
        }

        size = lseek(fdin, 0, SEEK_END);
        if (size < 0) {
                perror(argv[1]);
                exit(1);
        }

        data = mmap(0, size, PROT_READ, MAP_SHARED, fdin, 0);
        if (data == (void *)-1) {
                perror(argv[1]);
                exit(1);
        }

        while (memcmp(data, "OBMD", 4) && size) {
                data++;
                size--;
        }

        if (!size) {
                fprintf(stderr, "Could not find OBP magic\n");
                exit(1);
        }

        obp = (struct obp *)data;
        print_obp_info(obp);

        write(fdout, data, FLASH_SIZE/2);

        data += FLASH_SIZE/2;

        while (memcmp(data, "OBMD", 4) && size) {
                data++;
                size--;
        }

        if (!size) {
                fprintf(stderr, "Could not find OBP magic\n");
                exit(1);
        }

        obp = (struct obp *)data;
        print_obp_info(obp);

        write(fdout, data, FLASH_SIZE/2);

        close(fdin);
        close(fdout);

        return 0;
}

Reply via email to