#include <linux/mtd/mtd.h>

#include <stdio.h>

#include <fcntl.h>

#include <asm/ioctl.h>

#include <signal.h>

#include <sys/stat.h>


#define BLOCK_SIZE  4096

#define NUM_SECTORS 16

#define SECTOR_SIZE 64*1024


int
main(int argc, char *argv[])
{
    int fwh_fd, image_fd;
    int usect=0, lsect=0, ret;
    struct erase_info_user fwh_erase_info;
    char buffer[BLOCK_SIZE];
    struct stat statb;

    /* Ignore SIGINTR(^C) and SIGSTOP (^Z), lest
       you end up with a corrupted flash and an
       unbootable system */
    sigignore(SIGINT);
    sigignore(SIGTSTP);

    /* Open MTD char device */
    fwh_fd = open("/dev/mtd/0", O_RDWR);
    if (fwh_fd < 0) exit(1);

    /* Open BIOS image */
    image_fd = open("bios.img", O_RDONLY);
    if (image_fd < 0) exit(2);

    /* Sanity check */
    fstat(image_fd, &statb);
    if (statb.st_size != SECTOR_SIZE*NUM_SECTORS) {
        printf("BIOS image looks bad, exiting.\n");
        exit(3);
    }

    /* Unlock and erase all sectors */
    while (usect < NUM_SECTORS) {
        printf("Unlocking & Erasing Sector[%d]\r", usect+1);
        fwh_erase_info.start = usect*SECTOR_SIZE;
        fwh_erase_info.length = SECTOR_SIZE;
        ret = ioctl(fwh_fd, MEMUNLOCK, &fwh_erase_info);
        if (ret != 0) goto bios_done;
        ret = ioctl(fwh_fd, MEMERASE, &fwh_erase_info);
        if (ret != 0) goto bios_done;
        usect++;
    }

    /* Read blocks from the BIOS image and dump it to the
       Firmware Hub */
    while ((ret = read(image_fd, buffer, BLOCK_SIZE)) != 0) {
        if (ret < 0) goto bios_done;
        ret = write(fwh_fd, buffer, ret);
        if (ret <= 0) goto bios_done;
    }

    /* Verify by reading blocks from the BIOS flash and comparing
       with the image file */
    /* ... */
 bios_done:
    /* Lock back the unlocked sectors */
    while (lsect < usect) {
        printf("Relocking Sector[%d]\r", lsect+1);
        fwh_erase_info.start = lsect*SECTOR_SIZE;
        fwh_erase_info.length = SECTOR_SIZE;
        ret = ioctl(fwh_fd, MEMLOCK, &fwh_erase_info);
        if (ret != 0) printf("Relock failed on sector %d!\n", lsect);
        lsect++;
    }

    close(image_fd);
    close(fwh_fd);
} 


syntax highlighted by Code2HTML, v. 0.9.1