OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Software/] [demos/] [util/] [bintoxum.c] - Rev 2

Compare with Previous | Blame | View Log

/*
 * File          : bintoxum.c
 * Project       : University of Utah, XUM Project
 * Creator(s)    : Grant Ayers (ayers@cs.utah.edu)
 *
 * Modification History:
 *   Rev   Date         Initials  Description of Change
 *   1.0   7-3-2012     GEA       Initial Design.
 *
 * Standards/Formatting:
 *   C, 8 hard tab, 80 column
 *
 * Description:
 *    Combines the text (instruction) and data sections of an
 *    executable into one file. You can think of this as a very
 *    simple version of ELF or a.out files.
 *
 *    The XUM processor has a simple flat physical address space
 *    which contains instructions and data. The output file from
 *    this utility is directly loadable into this memory, byte-for-byte,
 *    without using any kind of "intelligent" loader. It takes two
 *    binary input files, the instructions and data, and an offset
 *    address (decimal) for the data segment to begin, and outputs
 *    a file which can be sent directly to hardware via the XUM
 *    bootloader or other means.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
void usage(void);
void read_file(char *name, int *size, char **buf);
 
int main(int argc, char **argv)
{
	FILE *file;
	char *it_name, *id_name, *o_name;
	int it_size, id_size;
	char *it_buf, *id_buf;
	int data_start_addr;
	int pad;
	int ch;
 
	while ((ch = getopt(argc, argv, "d:")) != -1) {
		switch (ch) {
			case 'd':
				data_start_addr = (int)strtol(optarg,
					(char **)NULL, 10);
				break;
			default:
				usage();
		}
	}
 
	argc -= optind;
	argv += optind;
 
	if (argc != 3) {
		usage();
	}
 
	it_name = argv[0];
	id_name = argv[1];
	o_name  = argv[2];
 
	read_file(it_name, &it_size, &it_buf);
	read_file(id_name, &id_size, &id_buf);
 
	/* Open the output file */
	file = fopen(o_name, "wb+");
	if (file == NULL) {
		fprintf(stderr, "Error: Could not open \"%s\" for "
			"writing.\n", o_name);
		exit(1);
	}
 
	/* Copy text segment directly to output file */
	if (fwrite((void *)it_buf, 1, it_size, file) != it_size) {
		fprintf(stderr, "Error writing to output file.\n");
		exit(1);
	}
 
	/* Pad until the data segment */
	it_buf[0] = 0;
	while (it_size < data_start_addr) {
		if (fwrite((void *)it_buf, 1, 1, file) != 1) {
			fprintf(stderr, "Error writing to output file.\n");
			exit(1);
		}
		it_size++;
	}
 
	/* Copy data segment to output file */
	if (fwrite((void *)id_buf, 1, id_size, file) != id_size) {
		fprintf(stderr, "Error writing to output file.\n");
		exit(1);
	}
 
	/* Pad the data section to word length if needed */
	/* NOTE: Assumes only padding needed would be at the end. */
	pad = ((id_size % 4) != 0) ? 4 - (id_size % 4) : 0;
	if (pad != 0) {
		memset((void *)id_buf, 0, 4);
		if (fwrite((void *)id_buf, 1, pad, file) != pad) {
			fprintf(stderr, "Error writing to output file.\n");
			exit(1);
		}
	}
 
	fclose(file);
 
	return 0;
}
 
void usage(void)
{
	fprintf(stderr, "Usage: bintoxum [-d data start address] "
		"<text file> <data file> <output file>\n");
	exit(1);
}
 
void read_file(char *name, int *size, char **buf)
{
	FILE *file;
 
	file = fopen(name, "rb");
	if (file == NULL) {
		fprintf(stderr, "Error: Could not open \"%s\".\n", name);
		exit(1);
	}
	fseek(file, 0L, SEEK_END);
	*size = (int)ftell(file);
	if ((*size < 0) || (ftell(file) > (long)*size)) {
		fprintf(stderr, "Error: Input file is too large.\n");
		exit(1);
	}
	fseek(file, 0L, SEEK_SET);
	*buf = (char *)malloc(*size);
	if (*buf == NULL) {
		fprintf(stderr, "Error: Could not allocate %d bytes "
			"of memory.\n", *size);
		exit(1);
	}
	if (fread(*buf, 1, *size, file) != *size) {
		fprintf(stderr, "Error reading input file.\n");
		exit(1);
	}
	fclose(file);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.