diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/SLOF/romfs | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/SLOF/romfs')
| -rw-r--r-- | roms/SLOF/romfs/header.img | 1 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/.gitignore | 1 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/Makefile | 55 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/build_ffs.c | 476 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/cfg_parse.c | 371 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/cfgparse.h | 59 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/create_crc.c | 467 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/create_flash.c | 163 | ||||
| -rw-r--r-- | roms/SLOF/romfs/tools/createcrc.h | 19 | 
9 files changed, 1612 insertions, 0 deletions
diff --git a/roms/SLOF/romfs/header.img b/roms/SLOF/romfs/header.img new file mode 100644 index 00000000..794129c9 --- /dev/null +++ b/roms/SLOF/romfs/header.img @@ -0,0 +1 @@ +Key.Polynome....XXXXXXXX..Mask..XXXXXXXX.Polynome.Length....XXXX.Header.and.File.lengthXXXXXXXX... und weiter im Text! diff --git a/roms/SLOF/romfs/tools/.gitignore b/roms/SLOF/romfs/tools/.gitignore new file mode 100644 index 00000000..3e4afbce --- /dev/null +++ b/roms/SLOF/romfs/tools/.gitignore @@ -0,0 +1 @@ +build_romfs diff --git a/roms/SLOF/romfs/tools/Makefile b/roms/SLOF/romfs/tools/Makefile new file mode 100644 index 00000000..f86803db --- /dev/null +++ b/roms/SLOF/romfs/tools/Makefile @@ -0,0 +1,55 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2008 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# *     IBM Corporation - initial implementation +# ****************************************************************************/ + +# FIXME review -I ... +# export NEW_BUILD=1 + +TOPCMNDIR	?= ../.. +INCLCMNDIR	?= ../../include + +include $(TOPCMNDIR)/make.rules + + +CPPFLAGS = -I$(INCLCMNDIR) -I$(INCLBRDDIR) -I. +CFLAGS += $(FLAG) + +SRCS = build_ffs.c cfg_parse.c create_flash.c create_crc.c +OBJS = $(SRCS:%.c=%.o) + +all: build_romfs + +build_romfs: $(OBJS) +	$(HOSTCC) $(HOSTCFLAGS) $(FLAG) -o $@ $^ + +testing: build_romfs +	$(MAKE) -C test + +%.o: %.c +	$(HOSTCC) $(CPPFLAGS) $(HOSTCFLAGS) $(FLAG) -c $< -o $@ + +clean: +	rm -f build_romfs *.o  + +distclean: clean +	rm -f Makefile.dep + + +# Rules for creating the dependency file: +depend: +	rm -f Makefile.dep +	$(MAKE) Makefile.dep + +Makefile.dep: Makefile +	$(HOSTCC) -MM $(CPPFLAGS) $(HOSTCFLAGS) $(SRCS) > Makefile.dep + +# Include dependency file if available: +-include Makefile.dep diff --git a/roms/SLOF/romfs/tools/build_ffs.c b/roms/SLOF/romfs/tools/build_ffs.c new file mode 100644 index 00000000..218de75f --- /dev/null +++ b/roms/SLOF/romfs/tools/build_ffs.c @@ -0,0 +1,476 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <cfgparse.h> +#include <createcrc.h> + +#define FFS_TARGET_HEADER_SIZE (4 * 8) + +extern int verbose; + +#define pad8_num(x) (((x) + 7) & ~7) + +static int +file_exist(const char *name, int errdisp) +{ +	struct stat fileinfo; + +	memset((void *) &fileinfo, 0, sizeof(struct stat)); +	if (stat(name, &fileinfo) != 0) { +		if (0 != errdisp) { +			perror(name); +		} +		return 0; +	} +	if (S_ISREG(fileinfo.st_mode)) { +		return 1; +	} +	return 0; +} + +static int +file_getsize(const char *name) +{ +	int rc; +	struct stat fi; + +	rc = stat(name, &fi); +	if (rc != 0) +		return -1; +	return fi.st_size; +} + +static int +ffshdr_compare(const void *_a, const void *_b) +{ +	const struct ffs_header_t *a = *(struct ffs_header_t * const *) _a; +	const struct ffs_header_t *b = *(struct ffs_header_t * const *) _b; + +	if (a->romaddr == b->romaddr) +		return 0; +	if (a->romaddr > b->romaddr) +		return 1; +	return -1; +} + +static void +hdr_print(struct ffs_header_t *hdr) +{ +	printf("hdr: %p\n", hdr); +	printf("\taddr:      %08llx token:    %s\n" +	       "\tflags:     %08llx romaddr:  %08llx image_len: %08x\n" +	       "\tsave_len:  %08llx ffsize:   %08x hdrsize:   %08x\n" +	       "\ttokensize: %08x\n", +	       hdr->addr, hdr->token, hdr->flags, hdr->romaddr, +	       hdr->imagefile_length, hdr->save_data_len, +	       hdr->ffsize, hdr->hdrsize, hdr->tokensize); +} + +int +reorder_ffs_chain(struct ffs_chain_t *fs) +{ +	int i, j; +	int free_space; +	unsigned long long addr; +	struct ffs_header_t *hdr; +	int fix, flx, res, tab_size = fs->count; +	struct ffs_header_t *fix_tab[tab_size];	/* fixed offset */ +	struct ffs_header_t *flx_tab[tab_size];	/* flexible offset */ +	struct ffs_header_t *res_tab[tab_size];	/* result */ + +	/* determine size data to be able to do the reordering */ +	for (hdr = fs->first; hdr; hdr = hdr->next) { +		if (hdr->linked_to) +			hdr->imagefile_length = 0; +		else +			hdr->imagefile_length = file_getsize(hdr->imagefile); +		if (hdr->imagefile_length == -1) +			return -1; + +		hdr->tokensize = pad8_num(strlen(hdr->token) + 1); +		hdr->hdrsize = FFS_TARGET_HEADER_SIZE + hdr->tokensize; +		hdr->ffsize = +		    hdr->hdrsize + pad8_num(hdr->imagefile_length) + 8; +	} + +	memset(res_tab, 0, tab_size * sizeof(struct ffs_header_t *)); +	memset(fix_tab, 0, tab_size * sizeof(struct ffs_header_t *)); +	memset(flx_tab, 0, tab_size * sizeof(struct ffs_header_t *)); + +	/* now start with entries having fixed offs, reorder if needed */ +	for (fix = 0, flx = 0, hdr = fs->first; hdr; hdr = hdr->next) +		if (needs_fix_offset(hdr)) +			fix_tab[fix++] = hdr; +		else +			flx_tab[flx++] = hdr; +	qsort(fix_tab, fix, sizeof(struct ffs_header_t *), ffshdr_compare); + +	/* +	 * for fixed files we need to also remove the hdrsize from the +	 * free space because it placed in front of the romaddr +	 */ +	for (addr = 0, res = 0, i = 0, j = 0; i < fix; i++) { +		fix_tab[i]->addr = fix_tab[i]->romaddr - fix_tab[i]->hdrsize; +		free_space = fix_tab[i]->addr - addr; + +		/* insert as many flexible files as possible */ +		for (; free_space > 0 && j < flx; j++) { +			if (flx_tab[j]->ffsize <= free_space) {	/* fits */ +				flx_tab[j]->addr = addr; +				free_space -= flx_tab[j]->ffsize; +				addr += flx_tab[j]->ffsize; +				res_tab[res++] = flx_tab[j]; +			} else +				break; +		} +		res_tab[res++] = fix_tab[i]; +		addr = fix_tab[i]->romaddr + fix_tab[i]->ffsize - +		    fix_tab[i]->hdrsize; +	} +	/* at the end fill up the table with remaining flx entries */ +	for (; j < flx; j++) { +		flx_tab[j]->addr = addr; +		addr += flx_tab[j]->ffsize; +		res_tab[res++] = flx_tab[j]; +	} + +	if (verbose) { +		printf("--- resulting order ---\n"); +		for (i = 0; i < tab_size; i++) +			hdr_print(res_tab[i]); +	} + +	/* to check if the requested romfs images is greater than +	 * the specified romfs_size it is necessary to add 8 for +	 * the CRC to the totalsize */ +	addr += 8; + +	/* sanity checking if user specified maximum romfs size */ +	if ((fs->romfs_size != 0) && addr > fs->romfs_size) { +		fprintf(stderr, "[build_romfs] romfs_size specified as %d " +			"bytes, but %lld bytes need to be written.\n", +			fs->romfs_size, addr); +		return 1; +	} + +	/* resort result list */ +	for (i = 0; i < tab_size - 1; i++) +		res_tab[i]->next = res_tab[i + 1]; +	res_tab[i]->next = NULL; +	fs->first = res_tab[0]; +	return 0; +} + +/** + * allocate memory for a romfs file including header + */ +static unsigned char * +malloc_file(int hdrsz, int datasz, int *ffsz) +{ +	void *tmp; + +	/* complete file size is: +	 * header + 8byte aligned(data) + end of file marker (-1) */ +	*ffsz = hdrsz + pad8_num(datasz) + 8; +	/* get the mem */ +	tmp = malloc(*ffsz); + +	if (!tmp) +		return NULL; + +	memset(tmp, 0, *ffsz); + +	return (unsigned char *) tmp; +} + +static int +copy_file(struct ffs_header_t *hdr, unsigned char *ffile, int datasize, +	  int ffile_offset, int ffsize) +{ +	int cnt = 0; +	int imgfd; +	int i; + +	if (!file_exist(hdr->imagefile, 1)) { +		printf("access error to file: %s\n", hdr->imagefile); +		free(ffile); +		return -1; +	} + +	imgfd = open(hdr->imagefile, O_RDONLY); +	if (0 >= imgfd) { +		perror(hdr->imagefile); +		free(ffile); +		return -1; +	} + +	/* now copy file to file buffer */ +	/* FIXME using fread might be a good idea so +	   that we do not need to deal with shortened +	   reads/writes. Also error handling looks +	   broken to me. Are we sure that all data is +	   read when exiting this loop? */ +	while (1) { +		i = read(imgfd, ffile + ffile_offset, ffsize - ffile_offset); +		if (i <= 0) +			break; +		ffile_offset += i; +		cnt += i; +	} + +	/* sanity check */ +	if (cnt != datasize) { +		printf("BUG!!! copy error on image file [%s](e%d, g%d)\n", +		       hdr->imagefile, datasize, cnt); +		close(imgfd); +		free(ffile); +		return -1; +	} + +	close(imgfd); + +	return cnt; +} + +static uint64_t +next_file_offset(struct ffs_header_t *hdr, int rom_pos, int ffsize) +{ +	uint64_t tmp; + +	/* no next file; end of filesystem */ +	if (hdr->next == NULL) +		return 0; + +	if (hdr->next->romaddr > 0) { +		/* the next file does not follow directly after the +		 * current file because it requested to be +		 * placed at a special address; +		 * we need to calculate the offset of the +		 * next file; +		 * the next file starts at hdr->next->romaddr which +		 * is the address requested by the user */ +		tmp = hdr->next->romaddr; +		/* the next file starts, however, a bit earlier; +		 * we need to point at the header of the next file; +		 * therefore it is necessary to subtract the header size +		 * of the _next_ file */ +		tmp -= FFS_TARGET_HEADER_SIZE; +		/* also remove the length of the filename of the _next_ +		 * file */ +		tmp -= pad8_num(strlen(hdr->next->token) + 1); +		/* and it needs to be relative to the current file */ +		tmp -= rom_pos; +		return tmp; +	} + +	/* if no special treatment is required the next file just +	 * follows after the current file; +	 * therefore just return the complete filesize as offset */ +	return ffsize; +} + +static int +next_file_address(struct ffs_header_t *hdr, unsigned int rom_pos, int hdrsize, +		  unsigned int num_files) +{ +	/* check if file wants a specific address */ +	void *tmp; + +	if ((hdr->flags & FLAG_LLFW) == 0) +		/* flag to get a specific address has been set */ +		return rom_pos; + +	if (hdr->romaddr == 0) +		/* if the requested address is 0 then +		 * something is not right; ignore the flag */ +		return rom_pos; + +	/* check if romaddress is below current position */ +	if (hdr->romaddr < (rom_pos + hdrsize)) { +		printf("[%s] ERROR: requested impossible " "romaddr of %llx\n", +		       hdr->token, hdr->romaddr); +		return -1; +	} + +	/* spin offset to new position */ +	if (pad8_num(hdr->romaddr) != hdr->romaddr) { +		printf("BUG!!!! pad8_num(hdr->romaddr) != hdr->romaddr\n"); +		return -1; +	} + +	tmp = malloc(hdr->romaddr - rom_pos - hdrsize); + +	if (!tmp) +		return -1; + +	memset(tmp, 0, hdr->romaddr - rom_pos - hdrsize); +	if (buildDataStream(tmp, hdr->romaddr - rom_pos - hdrsize)) { +		free(tmp); +		printf("write failed\n"); +		return -1; +	} + +	free(tmp); + +	if (!num_files) +		printf("\nWARNING: The filesystem will have no entry header!\n" +		       "         It is still usable but you need to find\n" +		       "         the FS by yourself in the image.\n\n"); + +	return hdr->romaddr - hdrsize; +} + +int +build_ffs(struct ffs_chain_t *fs, const char *outfile, int notime) +{ +	int ofdCRC; +	int ffsize, datasize, i; +	int tokensize, hdrsize, ffile_offset, hdrbegin; +	struct ffs_header_t *hdr; +	unsigned char *ffile; +	unsigned int rom_pos = 0; +	unsigned int num_files = 0; +	uint64_t tmp; + +	if (NULL == fs->first) { +		return 1; +	} +	hdr = fs->first; + +	/* check output file and open it for creation */ +	if (file_exist(outfile, 0)) { +		printf("Output file (%s) will be overwritten\n", outfile); +	} + +	while (hdr) { + +		if (hdr->linked_to) { +			printf("\nBUG!!! links not supported anymore\n"); +			return 1; +		} + +		/* add +1 to strlen for zero termination */ +		tokensize = pad8_num(strlen(hdr->token) + 1); +		hdrsize = FFS_TARGET_HEADER_SIZE + tokensize; +		datasize = file_getsize(hdr->imagefile); + +		if (datasize == -1) { +			perror(hdr->imagefile); +			return 1; +		} + +		ffile_offset = 0; +		ffile = malloc_file(hdrsize, datasize, &ffsize); + +		if (NULL == ffile) { +			perror("alloc mem for ffile"); +			return 1; +		} + +		/* check if file wants a specific address */ +		rom_pos = next_file_address(hdr, rom_pos, hdrsize, num_files); +		hdrbegin = rom_pos; + +		if (hdrbegin == -1) { +			/* something went wrong */ +			free(ffile); +			return 1; +		} + +		/* write header ******************************************* */ +		/* next addr ********************************************** */ +		tmp = next_file_offset(hdr, rom_pos, ffsize); + +		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(tmp); +		rom_pos += 8; +		ffile_offset += 8; + +		/* length ************************************************* */ +		hdr->save_data_len = datasize; + +		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(datasize); +		rom_pos += 8; +		ffile_offset += 8; + +		/* flags ************************************************** */ +		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(hdr->flags); +		rom_pos += 8; +		ffile_offset += 8; + +		/* datapointer ******************************************** */ + +		//save-data pointer is relative to rombase +		hdr->save_data = hdrbegin + hdrsize; +		hdr->save_data_valid = 1; +		//changed pointers to be relative to file: +		tmp = hdr->save_data - hdrbegin; + +		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(tmp); +		rom_pos += 8; +		ffile_offset += 8; + +		/* name (token) ******************************************* */ +		memset(ffile + ffile_offset, 0, tokensize); +		strcpy((char *) ffile + ffile_offset, hdr->token); +		rom_pos += tokensize; +		ffile_offset += tokensize; + +		/* image file ********************************************* */ +		i = copy_file(hdr, ffile, datasize, ffile_offset, ffsize); + +		if (i == -1) +			return 1; + +		/* pad file */ +		rom_pos += i + pad8_num(datasize) - datasize; +		ffile_offset += i + pad8_num(datasize) - datasize; + +		/* limiter ************************************************ */ +		*(uint64_t *) (ffile + ffile_offset) = -1; +		rom_pos += 8; +		ffile_offset += 8; + +		if (buildDataStream(ffile, ffsize) != 0) { +			printf +			    ("Failed while processing file '%s' (size = %d bytes)\n", +			     hdr->imagefile, datasize); +			return 1; +		} +		free(ffile); +		hdr = hdr->next; +		num_files++; +	} + +	/* +	 * FIXME Current limination seems to be about 4MiB. +	 */ +	ofdCRC = open(outfile, O_CREAT | O_WRONLY | O_TRUNC, 0666); +	if (0 > ofdCRC) { +		perror(outfile); +		return 1; +	} +	i = writeDataStream(ofdCRC, notime); +	close(ofdCRC); + +	if (i) +		return 1; +	return 0; +} diff --git a/roms/SLOF/romfs/tools/cfg_parse.c b/roms/SLOF/romfs/tools/cfg_parse.c new file mode 100644 index 00000000..5137fbe4 --- /dev/null +++ b/roms/SLOF/romfs/tools/cfg_parse.c @@ -0,0 +1,371 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <cfgparse.h> + +static int inbetween_white(char *s, int max, char **start, char **end, +			   char **next); +static int add_header(struct ffs_chain_t *, struct ffs_header_t *); + +static int glob_come_from_cr = 0; + +static int +find_next_entry(int file, struct ffs_chain_t *chain) +{ +#define MAX_LINE_SIZE 1024 +	char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0; +	char *start, *end, *next; +	struct ffs_header_t *hdr;	//, *hdr2; +	int lc, rc; +	char c; + +	/* search for new config line */ +	if (0 == glob_come_from_cr) { +		while (1 == (rc = read(file, &c, 1))) { +			//printf("b0=%c b1=%c c=%c\n", +			//              b0, b1, c); +			b0 = b1; +			b1 = c; +			/* this looks for starting sign "<CR>[^#]" */ +			if (((0x0a == b0) || (0x0d == b0)) && +			    (('#' != b1) && (0x0a != b1) && (0x0d != b1))) { +				break; +			} +		} +	} else { +		/* normalize */ +		while (1 == (rc = read(file, &c, 1))) { +			//printf("read c=%c\n", c); +			if ((0x0a != c) && (0x0d != c)) { +				break; +			} +		} +		glob_come_from_cr = 0; +		//printf("debug: glob_come_from_cr = 0\n"); +	} +	if (1 != rc) { +		return 1; +	} + +	/* now buffer it until end of line */ +	memset((void *) lnbuf, 0, MAX_LINE_SIZE); +	lnbuf[0] = c; +	lc = 1; +	while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) { +		//printf("read lnbuf=%c\n", lnbuf[lc]); +		if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) { +			glob_come_from_cr = 1; +			//printf("debug: glob_come_from_cr = 1\n"); +			break; +		} +		lc++; +	} + +	/* allocate header */ +	hdr = malloc(sizeof(struct ffs_header_t)); +	if (NULL == hdr) { +		perror("alloc memory"); +		return 2; +	} +	memset((void *) hdr, 0, sizeof(struct ffs_header_t)); + +	/* attach header to chain */ +	if (0 != add_header(chain, hdr)) { +		return 2; +	} + +	/**********************************************************/ +	/* extract token name *********************************** */ +	start = NULL; +	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { +		printf("parsing error 1"); +		return 2; +	} +	/* get memory for it */ +	hdr->token = malloc(end - start + 1); +	if (NULL == hdr->token) { +		return 2; +	} +	/* set string */ +	strncpy(hdr->token, start, end - start + 1); +	hdr->token[end - start] = 0; + +	/**********************************************************/ +	/* extract file name *********************************** */ +	if (NULL == next) { +		return 2; +	} +	start = next; +	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { +		printf("parsing error 1"); +		return 2; +	} + +	/* get memory for it */ +	hdr->imagefile = malloc(end - start + 1); +	if (NULL == hdr->imagefile) { +		return 2; +	} + +	/* check if file is existing */ + +	/* set string */ +	strncpy(hdr->imagefile, start, end - start + 1); +	hdr->imagefile[end - start] = 0; + +	/* check if entry is linked to another header */ +	if (':' == *start) { +		printf +		    ("\nERROR: links are removed as feature in this version\n"); +		return 2; + +		/* +		   start++; +		   if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) { +		   printf("[%s]: link to [%s] not found\n",  +		   hdr->token, hdr->imagefile+1); +		   dump_fs_contents(chain); +		   return 2; +		   } +		   hdr->linked_to = hdr2; +		 */ +	} + +	/**********************************************************/ +	/* extract flags name *********************************** */ +	if (NULL == next) { +		return 2; +	} +	start = next; +	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { +		printf("parsing error 1"); +		return 2; +	} +	hdr->flags = strtoul(start, NULL, 16); + +	/**********************************************************/ +	/* extract rom start name *********************************** */ +	if (NULL == next) { +		return 2; +	} +	start = next; +	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { +		printf("parsing error 1"); +		return 2; +	} +	if ('-' == *start) { +		/* this means not specific address request for data */ +		hdr->romaddr = 0; +	} else { +		/* data has to begin at specific address */ +		hdr->romaddr = strtoul(start, NULL, 16); +	} + +	return 0; +} + +int +read_config(int conf_file, struct ffs_chain_t *ffs_chain) +{ +	int rc; + +	while (1) { +		rc = find_next_entry(conf_file, ffs_chain); +		if (rc != 0) +			break; +	} +	return rc; +} + +static int +inbetween_white(char *s, int max, char **start, char **end, char **next) +{ +	int pos = 0, posalt; + +	if (NULL != *start) { +		pos = *start - s; +		s = *start; +	} + +	/* wind to first non white */ +	while (pos < max) { +		if ((' ' == *s) || ('	' == *s)) { +			s++; +			pos++; +			continue; +		} +		break; +	} +	if (pos >= max) { +		/* no non-white found */ +		return 1; +	} + +	/* assign start */ +	*start = s; + +	/* wind to end of non white or end of buffer */ +	posalt = pos; +	while (pos < max) { +		if ((' ' == *s) || ('	' == *s) || +		    (0x0a == *s) || (0x0d == *s)) { +			break; +		} +		s++; +		pos++; +	} + +	if (pos == posalt) { +		return 1; +	} + +	*end = s; + +	if ((pos + 1) >= max) { +		*next = NULL; +	} else { +		*next = s; +	} + +	return 0; +} + +int +add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr) +{ +	struct ffs_header_t *next; + +	if (NULL == chain->first) { +		chain->count = 1; +		chain->first = hdr; +		return 0; +	} +	next = chain->first; + +	/* find last */ +	while (NULL != next->next) { +		next = next->next; +	} +	next->next = hdr; +	chain->count++; + +	return 0; +} + +void +dump_fs_contents(struct ffs_chain_t *chain) +{ +	struct ffs_header_t *next; + +	if (NULL == chain->first) { +		printf("no contents in fs\n"); +		return; +	} +	next = chain->first; + +	while (1) { +		if (NULL != next->token) { +			printf("Token [%s] ", next->token); +		} else { +			printf(" [not-set], "); +		} + +		if (NULL != next->imagefile) { +			printf(" <%s>, ", next->imagefile); +		} else { +			printf(" file<not-set>, "); +		} + +		printf("flags<%llx>, ", next->flags); +		printf("romaddr<%llx>, ", next->romaddr); + +		if (NULL != next->linked_to) { +			printf("linked to [%s]", next->linked_to->token); +		} + +		printf("\n"); +		if (NULL == next->next) { +			break; +		} + +		next = next->next; +	} + +} + +void +free_chain_memory(struct ffs_chain_t *chain) +{ +	struct ffs_header_t *hdr, *next_hdr; + +	if (NULL != chain->first) { +		hdr = chain->first; +		chain->first = NULL; +	} else { +		return; +	} + +	while (NULL != hdr) { +		//printf("%p  ", hdr); +		if (NULL != hdr->token) { +			//printf("free up %s\n", hdr->token); +			free(hdr->token); +		} +		if (NULL != hdr->imagefile) { +			free(hdr->imagefile); +		} +		next_hdr = hdr->next; +		free(hdr); +		hdr = next_hdr; +	} +} + + +/* + * Detect duplicate entries in the romfs list + */ +void +find_duplicates(struct ffs_chain_t *chain) +{ +	struct ffs_header_t *act, *sub; + +	if (NULL == chain->first) { +		printf("no contents in fs\n"); +		return; +	} +	act = chain->first; + +	do { +		sub = act->next; +		while (sub != NULL) { + +			if (act->token == NULL || sub->token == NULL) { +				printf("find_duplicates: token not set!\n"); +			} else if (strcmp(act->token, sub->token) == 0) { +				printf("*** NOTE: duplicate romfs file '%s'.\n", +				       act->token); +			} +			sub = sub->next; +		} + +		act = act->next; + +	} while (act != NULL); + +} diff --git a/roms/SLOF/romfs/tools/cfgparse.h b/roms/SLOF/romfs/tools/cfgparse.h new file mode 100644 index 00000000..ed5c8856 --- /dev/null +++ b/roms/SLOF/romfs/tools/cfgparse.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ +#ifndef CFGPARSE_H +#define CFGPARSE_H + +#include <byteswap.h> +#include <endian.h> + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be64(x)	(x) +#else +#define cpu_to_be64(x)	bswap_64(x) +#endif + +struct ffs_chain_t { +	int count; +	unsigned int romfs_size; +	struct ffs_header_t *first; +}; + +#define FLAG_LLFW 1		/* low level firmware at fix offs in romfs */ + +#define needs_fix_offset(hdr) ((hdr)->flags & FLAG_LLFW) + +struct ffs_header_t { +	unsigned long long flags; +	unsigned long long romaddr; +	char *token; +	char *imagefile; +	int imagefile_length; +	struct ffs_header_t *linked_to; +	struct ffs_header_t *next; +	unsigned long long save_data; +	unsigned long long save_data_len; +	int save_data_valid; + +	unsigned long long addr;	/* tmp */ +	int hdrsize;		/* tmp */ +	int tokensize;		/* tmp */ +	int ffsize;		/* tmp */ +}; + +void dump_fs_contents(struct ffs_chain_t *chain); +void find_duplicates(struct ffs_chain_t *chain); +void free_chain_memory(struct ffs_chain_t *chain); + +int read_config(int conf_file, struct ffs_chain_t *ffs_chain); +int reorder_ffs_chain(struct ffs_chain_t *fs); +int build_ffs(struct ffs_chain_t *fs, const char *outfile, int notime); +#endif diff --git a/roms/SLOF/romfs/tools/create_crc.c b/roms/SLOF/romfs/tools/create_crc.c new file mode 100644 index 00000000..51f137d8 --- /dev/null +++ b/roms/SLOF/romfs/tools/create_crc.c @@ -0,0 +1,467 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <cfgparse.h> +#include <time.h> +#include <calculatecrc.h> +#include <product.h> +#include "createcrc.h" + +int createHeaderImage(int); +unsigned int calCRCEthernet32(unsigned char *TextPtr, +			      unsigned long int TextLength, +			      unsigned int AccumCRC); +int createCRCParameter(uint64_t * ui64RegisterMask, +		       unsigned int *iRegisterLength); +uint64_t calCRCbyte(unsigned char *TextPtr, uint32_t Residual, +		    uint64_t AccumCRC); +uint64_t calCRCword(unsigned char *TextPtr, uint32_t Residual, +		    uint64_t AccumCRC); +uint64_t checkCRC(unsigned char *TextPtr, uint32_t Residual, uint64_t AccumCRC); + +/* file length in bytes */ +static uint64_t ui64globalFileSize = 0; +/* space for the file stream >= 4MB + 4bytes */ +static unsigned char pucFileStream[4400000]; +/* header length in bytes */ +static uint64_t ui64globalHeaderSize = 0; +/* flag to filter detect the header in buildDataStream() */ +static int iglobalHeaderFlag = 1; +static uint64_t ui64Generator1; + +/** + * Build the file image and store it as Data Stream of bytes + * calculate a first CRC for the first file and + * catch the position of this CRC + */ +int +buildDataStream(unsigned char *pucbuf, int size) +{ +	if (ui64globalFileSize + size > sizeof(pucFileStream)) { +		printf("Error: File size is too big!\n"); +		return -1; +	} + +	/* copy the data into the destination buffer */ +	memcpy(pucFileStream + ui64globalFileSize, pucbuf, size); +	ui64globalFileSize += size; + +	if (iglobalHeaderFlag == 1) {	// catch header + +		ui64globalHeaderSize = ui64globalFileSize; +		iglobalHeaderFlag = 0; +	} + +	return 0; +} + +/** + * write Header.img + */ +int +createHeaderImage(int notime) +{ +	int iCounter; +	uint64_t ui64RomAddr, ui64DataAddr; +	time_t caltime; +	struct tm *tm; +	char *pcVersion; +	char dastr[16] = { 0, }; +	unsigned long long da = 0; + +	union { +		unsigned char pcArray[FLASHFS_HEADER_DATA_SIZE]; +		struct stH stHeader; +	} uHeader; + +	/* initialize Header */ +	memset(uHeader.pcArray, 0x00, FLASHFS_HEADER_DATA_SIZE); + +	/* read driver info */ +	if (NULL != (pcVersion = getenv("DRIVER_NAME"))) { +		strncpy(uHeader.stHeader.version, pcVersion, 16); +	} else if (NULL != (pcVersion = getenv("USER"))) { +		strncpy(uHeader.stHeader.version, pcVersion, 16); +	} else if (pcVersion == NULL) { +		strncpy(uHeader.stHeader.version, "No known user!", 16); +	} + +	if (!notime) { +		/* read time and write it into data stream */ +		if ((caltime = time(NULL)) == -1) { +			printf("time error\n"); +		} +		if ((tm = localtime(&caltime)) == NULL) { +			printf("local time error\n"); +		} +		// length must be 13 instead 12 because of terminating +		// NUL. Therefore uH.stH.platform_revison must be +		// written later to overwrite the terminating NUL +		if (strftime(dastr, 15, "0x%Y%m%d%H%M", tm) == 0) { +			printf("strftime error\n"); +		} +		da = cpu_to_be64(strtoll(dastr, NULL, 16)); +	} +	memcpy(uHeader.stHeader.date, &da, 8); + +	/* write Magic value into data stream */ +	strncpy(uHeader.stHeader.magic, FLASHFS_MAGIC, 8); +	/* write platform name into data stream */ +	strcpy(uHeader.stHeader.platform_name, FLASHFS_PLATFORM_MAGIC); +	/* write platform revision into data stream */ +	strcpy(uHeader.stHeader.platform_revision, FLASHFS_PLATFORM_REVISION); + + +	/* fill end of file info (8 bytes of FF) into data stream */ +	uHeader.stHeader.ui64FileEnd = -1; + +	/* read address of next file and address of header date, both are 64 bit values */ +	ui64RomAddr = 0; +	ui64DataAddr = 0; +	for (iCounter = 0; iCounter < 8; iCounter++) { +		/* addr of next file */ +		ui64RomAddr = (ui64RomAddr << 8) + pucFileStream[FLASHFS_ROMADDR + iCounter]; +		/* addr of header data */ +		ui64DataAddr = (ui64DataAddr << 8) + pucFileStream[FLASHFS_DATADDR + iCounter]; +	} + +	/* calculate final flash-header-size and flash-file-size */ +	/* calculate end addr of header */ +	ui64globalHeaderSize = (uint32_t) ui64DataAddr + (uint32_t) FLASHFS_HEADER_DATA_SIZE; +	/* cut 64 bit to place CRC for File-End */ +	ui64globalHeaderSize -= 8; +	/* add 64 bit to place CRC behind File-End */ +	ui64globalFileSize += 8; + +	if (ui64globalHeaderSize >= ui64RomAddr) { +		printf("%s\n", "--- Header File to long"); +		return 1; +	} + +	/* fill free space in Header with zeros */ +	memset(&pucFileStream[ui64DataAddr], 0, (ui64RomAddr - ui64DataAddr)); +	/* place data to header */ +	memcpy(&pucFileStream[ui64DataAddr], uHeader.pcArray, +	       FLASHFS_HEADER_DATA_SIZE); + +	/* insert header length into data stream */ +	*(uint64_t *) (pucFileStream + FLASHFS_HEADER_SIZE_ADDR) = +	    cpu_to_be64(ui64globalHeaderSize); + +	/* insert flash length into data stream */ +	*(uint64_t *) (pucFileStream + ui64DataAddr + FLASHFS_FILE_SIZE_ADDR) = +	    cpu_to_be64(ui64globalFileSize); + +	/* insert zeros as placeholder for CRC */ +	*(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) = 0; +	*(uint64_t *) (pucFileStream + ui64globalFileSize - 8) = 0; + +	return 0; +} + +/** + * calculate standart ethernet 32 bit CRC + * generator polynome is 0x104C11DB7 + * this algorithm can be used for encoding and decoding + */ +unsigned int +calCRCEthernet32(unsigned char *TextPtr, unsigned long int TextLength, +		 unsigned int AccumCRC) +{ +	const unsigned int CrcTableHigh[16] = { +		0x00000000, 0x4C11DB70, 0x9823B6E0, 0xD4326D90, +		0x34867077, 0x7897AB07, 0xACA5C697, 0xE0B41DE7, +		0x690CE0EE, 0x251D3B9E, 0xF12F560E, 0xBD3E8D7E, +		0x5D8A9099, 0x119B4BE9, 0xC5A92679, 0x89B8FD09 +	}; +	const unsigned CrcTableLow[16] = { +		0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, +		0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, +		0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, +		0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD +	}; + +	unsigned char *Buffer = TextPtr; +	unsigned long int Residual = TextLength; + + +	while (Residual > 0) { +		unsigned int Temp = ((AccumCRC >> 24) ^ *Buffer) & 0x000000ff; +		AccumCRC <<= 8; +		AccumCRC ^= CrcTableHigh[Temp / 16]; +		AccumCRC ^= CrcTableLow[Temp % 16]; +		++Buffer; +		--Residual; +	} +	return AccumCRC; +} + +/** + * create CRC Parameter:  CRC Polynome, Shiftregister Mask and length + * + *   ui64Generator[0] = 0; + *   ui64Generator[1] = 0x42F0E1EB; + *   ui64Generator[1] = (ui64Generator[1] << 32) + 0xA9EA3693; + *   iRegisterLength = 63; + *   ui64RegisterMask =  0xffffffff; + *   ui64RegisterMask = ((ui64RegisterMask) << 32) + 0xffffffff; + * + *    ucl=0x00000000ffffffff = Mask for 32 bit LSFR to cut down number of bits + *    in the variable to get the same length as LFSR + * + *    il = length of LSFR = degree of generator polynom reduce il by one to calculate the degree + *    of the highest register in LSFR + * + *    Examples: + *    CRC-16 for Tap:		x16 + x15 + x2 + 1 + *     generator = 0x8005,	il = 16,	ucl = 0x000000000000FFFF + * + *    CRC-16 for Floppy:		x16 + x12 + x5 +1 + *     generator = 0x1021,	il = 16,	ucl = 0x000000000000FFFF + * + *    CRC-32 for Ethernet:	x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 + *     generator = 0x04C11DB7,	il = 32,	ucl = 0x00000000FFFFFFFF + * + *    CRC-64 SP-TrEMBL	x64 + x4 + x3 + x + 1 (maximal-length LFSR) + *     generator = 0x1B,	il = 64,	ucl = 0xFFFFFFFFFFFFFFFF + * + *    CRC-64 improved + *     x64 + x63 + x61 + x59 + x58 + x56 + x55 + x52 + x49 + x48 + x47 + x46+ x44 + + *     x41 + x37 + x36 + x34 + x32 + x31 + x28 + x26 + x23 + x22 + x19 + x16 + x13 + + *     x12 + x10 + x9 + x6 + x4 + x3 + 1 + *     (see http://www.cs.ud.ac.uk/staff/D.Jones/crcbote.pdf) + *     generator = 0xAD93D23594C9362D,  il = 64,    ucl = 0xFFFFFFFFFFFFFFFF + * + *    CRC-64 DLT1 spec + *     x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 + + *     x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 + + *     x10 + x9 + x7 + x4 + x + 1 + *     (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf  -> page63) + *     generator = 0x42F0E1EBA9EA3693 + * + *    CRC-64 from internet G(x)= 1006003C000F0D50B + */ +int +createCRCParameter(uint64_t * ui64RegisterMask, unsigned int *uiRegisterLength) +{ +	enum Generators { Tape_16, Floppy_16, Ethernet_32, SPTrEMBL_64, +		SPTrEMBL_improved_64, DLT1_64 +	}; +	enum Generators Generator; + +	Generator = CRC_METHODE; +	switch (Generator) { +	case Tape_16:{ +			*ui64RegisterMask = 0x0000ffff; +			ui64Generator1 = 0x00008005; +			*uiRegisterLength = 16; +			break; +		} +	case Floppy_16:{ +			*ui64RegisterMask = 0x0000ffff; +			ui64Generator1 = 0x00001021; +			*uiRegisterLength = 16; +			break; +		} +	case Ethernet_32:{ +			*ui64RegisterMask = 0xffffffff; +			ui64Generator1 = 0x04C11DB7; +			*uiRegisterLength = 32; +			break; +		} +	case SPTrEMBL_64:{ +			*ui64RegisterMask = 0xffffffff; +			*ui64RegisterMask = +			    ((*ui64RegisterMask) << 32) + 0xffffffff; +			ui64Generator1 = 0x0000001B; +			*uiRegisterLength = 64; +			break; +		} +	case SPTrEMBL_improved_64:{ +			*ui64RegisterMask = 0xffffffff; +			*ui64RegisterMask = +			    ((*ui64RegisterMask) << 32) + 0xffffffff; +			ui64Generator1 = 0xAD93D235; +			ui64Generator1 = (ui64Generator1 << 32) + 0x94C9362D; +			*uiRegisterLength = 64; +			break; +		} +	case DLT1_64:{ +			*ui64RegisterMask = 0xffffffff; +			*ui64RegisterMask = +			    ((*ui64RegisterMask) << 32) + 0xffffffff; +			ui64Generator1 = 0x42F0E1EB; +			ui64Generator1 = (ui64Generator1 << 32) + 0xA9EA3693; +			*uiRegisterLength = 64; +			break; +		} +	} +	(*uiRegisterLength)--; + +	return 0; +} + +/** + *  Check CRC by using Linear Feadback Shift Register (LFSR) + */ +uint64_t +calCRCbyte(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) +{ + +	uint64_t ui64Mask, ui64Generator0; +	uint8_t ui8Buffer; +	unsigned int uiRegisterLength; +	int iShift; + +	createCRCParameter(&ui64Mask, &uiRegisterLength); + +	ui8Buffer = (*cPtr); +	while (ui32NoWords > 0) { +		for (iShift = 7; iShift >= 0; iShift--) { + +			ui64Generator0 = (AccumCRC >> uiRegisterLength); +			AccumCRC <<= 1; +			ui64Generator0 &= 0x01; +			ui64Generator0 = (0 - ui64Generator0); +			AccumCRC ^= (ui64Generator1 & ui64Generator0); +		} +		AccumCRC ^= ui8Buffer; +		AccumCRC &= ui64Mask; +		ui32NoWords -= 1; +		cPtr += 1; +		ui8Buffer = (*cPtr); +	} +	return AccumCRC; +} + +/** + *  Check CRC by using Linear Feadback Shift Register (LFSR) + */ +uint64_t +calCRCword(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) +{ + +	uint64_t ui64Mask, ui64Generator0; +	uint16_t ui16Buffer; +	unsigned int uiRegisterLength; +	int iShift; + +	createCRCParameter(&ui64Mask, &uiRegisterLength); + +	if ((ui32NoWords % 2) != 0) { +		/* if Data string does not end at word boundery add one byte */ +		ui32NoWords++; +		cPtr[ui32NoWords] = 0; +	} +	ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1)); +	while (ui32NoWords > 0) { +		for (iShift = 15; iShift >= 0; iShift--) { +			ui64Generator0 = (AccumCRC >> uiRegisterLength); +			AccumCRC <<= 1; +			ui64Generator0 &= 0x01; +			ui64Generator0 = (0 - ui64Generator0); +			AccumCRC ^= (ui64Generator1 & ui64Generator0); +		} +		AccumCRC ^= ui16Buffer; +		AccumCRC &= ui64Mask; +		ui32NoWords -= 2; +		cPtr += 2; +		ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1)); +	} +	return AccumCRC; +} + +uint64_t +checkCRC(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) +{ + +	enum Generators { Ethernet_32 }; +	enum Generators Generator; +	uint64_t ui64Buffer = AccumCRC; + +	Generator = CRC_METHODE; + +	switch (Generator) { +	case Ethernet_32:{ +			/* (ui32NoWords - 4),no need of 4 bytes 0x as +			 * with shift-register method */ +			AccumCRC = +			    calCRCEthernet32(cPtr, (ui32NoWords - 4), AccumCRC); +			break; +		} +	default:{ +			AccumCRC = calCRCword(cPtr, ui32NoWords, AccumCRC); +			break; +		} +	} + +	if (calCRCbyte(cPtr, ui32NoWords, ui64Buffer) != AccumCRC) { +		printf("\n --- big Endian - small Endian problem --- \n"); +		AccumCRC--; +	} + +	return (AccumCRC); +} + +/** + *  insert header and file CRC into data stream + *  do CRC check on header and file + *  write data stream to disk + */ +int +writeDataStream(int iofd, int notime) +{ +	uint64_t ui64FileCRC = 0, ui64HeaderCRC = 0, ui64RegisterMask; +	unsigned int uiRegisterLength; + +	if (0 != createHeaderImage(notime)) { +		return 1; +	} + +	createCRCParameter(&ui64RegisterMask, &uiRegisterLength); + +	/* calculate CRC */ +	ui64HeaderCRC = checkCRC(pucFileStream, ui64globalHeaderSize, 0); +	*(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) = +	    cpu_to_be64(ui64HeaderCRC); + +	ui64FileCRC = checkCRC(pucFileStream, ui64globalFileSize, 0); +	*(uint64_t *) (pucFileStream + ui64globalFileSize - 8) = +	    cpu_to_be64(ui64FileCRC); + +	/* check CRC-implementation */ +	ui64HeaderCRC = calCRCword(pucFileStream, ui64globalHeaderSize, 0); +	ui64FileCRC = calCRCword(pucFileStream, ui64globalFileSize, 0); + +	if ((ui64HeaderCRC != 0) || (ui64FileCRC != 0)) { +		printf("\n\n %s \n %s \n\n", "CRCs not correct implemented.", +		       " ---> Data will not be written do disk."); +		return -1; +	} + +	/* write file image to disk */ +	if (0 < write(iofd, pucFileStream, ui64globalFileSize)) +		return 0; + +	printf("<< write failed >>\n"); +	return -1; +} diff --git a/roms/SLOF/romfs/tools/create_flash.c b/roms/SLOF/romfs/tools/create_flash.c new file mode 100644 index 00000000..f99fd622 --- /dev/null +++ b/roms/SLOF/romfs/tools/create_flash.c @@ -0,0 +1,163 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <getopt.h> + +#include <cfgparse.h> + +int verbose = 0; + +#define dprintf(fmt, args...) if (verbose) printf(fmt, ##args) + +static void +print_usage(void) +{ +	printf +	    ("Usage: build_romfs [-?] [--help] [-s|--romfs-size <romfs_size>]\n" +	     "\t[-p|--smart-pad] [-n|--notime] <config-file> <output-file>\n"); +} + +unsigned long +str_to_num(const char *str) +{ +	char *s = (char *) str; +	unsigned long num = strtoul(s, &s, 0); +	if (s) { +		if (s[0] == 'K') +			num <<= 10; +		if (s[0] == 'M') +			num <<= 20; +	} +	return num; +} + +/* + * NOTE: We should consider to install an exit handler which does the + * unlink() of the output file. In case of error we just do exit() and + * forget about all the clumsy error handling free/close code, which + * blows up the code significantly and makes it hard to read. + */ +int +main(int argc, char *argv[]) +{ +	int conf_file, rc; +	struct ffs_chain_t ffs_chain; +	int c; +	int smart_pad = 0;	/* default */ +	int notime = 0; +	const char *config_file = "boot_rom.ffs"; +	const char *output_file = "boot_rom.bin"; + +	memset((void *) &ffs_chain, 0, sizeof(struct ffs_chain_t)); + +	while (1) { +		int option_index = 0; +		static struct option long_options[] = { +			{"romfs-size", 1, 0, 's'}, +			{"smart-pad", 0, 0, 'p'}, +			{"notime", 0, 0, 'n'}, +			{"verbose", 0, 0, 'v'}, +			{"help", 1, 0, 'h'}, +			{0, 0, 0, 0} +		}; +		c = getopt_long(argc, argv, "s:ph?nv", long_options, +				&option_index); +		if (c == -1) +			break; + +		switch (c) { +		case 's': +			ffs_chain.romfs_size = str_to_num(optarg); +			break; +		case 'p': +			smart_pad = 1; +			break; +		case 'n': +			notime = 1; +			break; +		case 'v': +			verbose = 1; +			break; +		case '?': +		case 'h': +			print_usage(); +			return EXIT_SUCCESS; +		default: +			printf("?? getopt returned character code 0%o ??\n", c); +		} +	} + +	/* two files must always be specified: config-file and output-file */ +	if (optind + 2 != argc) { +		print_usage(); +		return EXIT_FAILURE; +	} + +	config_file = argv[optind++]; +	output_file = argv[optind++]; + +	dprintf("ROMFS FILESYSTEM CREATION V0.3 (bad parser)\n" +		"Build directory structure...\n" +		"  smart padding %s, maximum romfs size %d bytes\n", +		smart_pad ? "enabled" : "disabled", ffs_chain.romfs_size); + +	conf_file = open(config_file, O_RDONLY); +	if (0 >= conf_file) { +		perror("load config file:"); +		return EXIT_FAILURE; +	} + +	rc = read_config(conf_file, &ffs_chain); +	close(conf_file); +	if (rc < 1) { +		fprintf(stderr, "flash cannot be built due to config errors\n"); +		return EXIT_FAILURE; +	} + +	rc = EXIT_SUCCESS; + +	if (verbose) +		dump_fs_contents(&ffs_chain); +	if (smart_pad) +		/* FIXME: size is only verified during reorder */ +		rc = reorder_ffs_chain(&ffs_chain); + +	if (rc == EXIT_FAILURE) +		goto out; + +	dprintf("Build ffs and write to image file...\n"); +	if (build_ffs(&ffs_chain, output_file, notime) != 0) { +		fprintf(stderr, "build ffs failed\n"); +		rc = EXIT_FAILURE; +	} else { +		rc = EXIT_SUCCESS; +	} + +	/* Check if there are any duplicate entries in the image, +	   print warning if this is the case. */ +	find_duplicates(&ffs_chain); +	free_chain_memory(&ffs_chain); +	dprintf("\n"); + +      out: +	/* If the build failed, remove the target image file */ +	if (rc == EXIT_FAILURE) +		unlink(output_file); + +	return rc; +} diff --git a/roms/SLOF/romfs/tools/createcrc.h b/roms/SLOF/romfs/tools/createcrc.h new file mode 100644 index 00000000..1f235982 --- /dev/null +++ b/roms/SLOF/romfs/tools/createcrc.h @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ +#ifndef CREATECRC_H +#define CREATECRC_H + +int buildDataStream(unsigned char *pucbuf, int size); +int createHeaderImgage(char *pcFilename); +int writeDataStream(int ofd, int notime); + +#endif  | 
