⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfsloader.c

📁 可移到ucos上的文件系统
💻 C
字号:
/* tfsloader.c:
 *	This file contains the code that is specific to each of the file types
 *	supported by TFS as the binary executable type.
 *	Currently, COFF, ELF and A.OUT are supported.  This requires that
 *	TFS_EBIN_COFF, TFS_EBIN_ELF or TFS_EBIN_AOUT, respectively, be set in
 *	the monitor's config.h file.
 *
 *	General notice:
 *	This code is part of a boot-monitor package developed as a generic base
 *	platform for embedded system designs.  As such, it is likely to be
 *	distributed to various projects beyond the control of the original
 *	author.  Please notify the author of any enhancements made or bugs found
 *	so that all may benefit from the changes.  In addition, notification back
 *	to the author will allow the new user to pick up changes that may have
 *	been made by other users after this version of the code was distributed.
 *
 *	Author:	Ed Sutter
 *	email:	esutter@lucent.com		(home: lesutter@worldnet.att.net)
 *	phone:	908-582-2351			(home: 908-889-5161)
 */
#include "config.h"
#include "stddefs.h"
#include "genlib.h"
#include "tfs.h"
#include "coff.h"
#include "elf.h"
#include "aout.h"
#if INCLUDE_TFS

#if TFS_EBIN_AOUT

/* tfsloadaout():
 *	The file pointed to by fp has been determined to be an A.OUT
 *	formatted file.  This function loads the sections of that file into
 *	the designated locations and returns the address of the entry point.
 *	Caches are flushed after loading text section.
 */
int
tfsloadebin(TFILE *fp,int verbose,long *entrypoint,int verifyonly)
{
	uchar	*tfrom, *dfrom;
	struct	exec *ehdr;

	/* Establish file header pointer... */
	ehdr = (struct exec *)(TFS_BASE(fp));

	/* Return error if relocatable... */
	if ((ehdr->a_trsize) || (ehdr->a_drsize))
		return(TFSERR_BADHDR);

	/* Establish locations from which text and data are to be */
	/* copied from ... */
	tfrom = (uchar *)(ehdr+1);
	dfrom = tfrom+ehdr->a_text;

	/* Copy/verify text and data sections to RAM: */
	if (verbose)
		printf("%-10s: ","text");
	if (tfsmemcpy((char *)(ehdr->a_entry),(char *)tfrom,
		ehdr->a_text,verbose,verifyonly) != 0)
		return(TFSERR_MEMFAIL);

	/* Flush caches after writing to space that will be executed from... */
	flushDcache((char *)ehdr->a_entry,ehdr->a_text);
	invalidateIcache((char *)ehdr->a_entry,ehdr->a_text);

	if (verbose)
		printf("%-10s: ","data");
	if (tfsmemcpy((char *)(ehdr->a_entry+ehdr->a_text),(char *)dfrom,
		ehdr->a_data,verbose,verifyonly) != 0)
		return(TFSERR_MEMFAIL);

	/* Clear out bss space: */
	if (verbose)
		printf("%-10s: ","bss");
	if (tfsmemset((char *)(ehdr->a_entry+ehdr->a_text+ehdr->a_data),
	    0,ehdr->a_bss,verbose,verifyonly) != 0)
		return(TFSERR_MEMFAIL);


	if (verbose & !verifyonly)
		printf("entrypoint: 0x%lx\n",ehdr->a_entry);

	/* Store entry point: */
	if (entrypoint)
		*entrypoint = (long)(ehdr->a_entry);

	return(TFS_OKAY);
}

#elif TFS_EBIN_COFF

/* tfsloadcoff():
 *	The file pointed to by fp has been determined to be a COFF file.
 *	This function loads the sections of that file into the designated 
 *	locations.
 *	Caches are flushed after loading each loadable section.
 */
int
tfsloadebin(TFILE *fp,int verbose,long *entrypoint,int verifyonly)
{
	int		i, err;
	FILHDR	*fhdr;
	AOUTHDR	*ahdr;
	SCNHDR	*shdr;

	/* Establish file header pointers... */
	fhdr = (FILHDR *)(TFS_BASE(fp));
	if ((fhdr->f_opthdr == 0) || ((fhdr->f_flags & F_EXEC) == 0))
		return(TFSERR_BADHDR);
	
	err = 0;
	ahdr = (AOUTHDR *)(fhdr+1);
	shdr = (SCNHDR *)((uchar *)ahdr + fhdr->f_opthdr);

	/* For each section header, relocate or clear if necessary... */
	for (i=0;!err && i<fhdr->f_nscns;i++) {
		if (shdr->s_size == 0) {
			shdr++;
			continue;
		}
		if (verbose)
			printf("%-10s: ",shdr->s_name);
		if (ISLOADABLE(shdr->s_flags)) {
			if (TFS_ISCPRS(fp)) {
				extern	int decompress(char *,int, char *);
				int		outsize;

				outsize = decompress((char *)shdr->s_scnptr+(int)fhdr,
					shdr->s_size,(char *)shdr->s_paddr);
				if (outsize == -1) {
					err++;
					shdr++;
					continue;
				}
				if (verbose)
					printf("dcmp %7d bytes from 0x%08lx to 0x%08lx\n",outsize,
						shdr->s_scnptr+(ulong)fhdr,shdr->s_paddr);
			}
			else {
				if (tfsmemcpy((char *)(shdr->s_paddr),
					(char *)(shdr->s_scnptr+(int)fhdr),
				    shdr->s_size,verbose,verifyonly) != 0)
					err++;
			}
			/* Flush caches for each loadable section... */
			flushDcache((char *)shdr->s_paddr,shdr->s_size);
			invalidateIcache((char *)shdr->s_paddr,shdr->s_size);
		}
		else if (ISBSS(shdr->s_flags)) {
			if (tfsmemset((char *)(shdr->s_paddr),0,shdr->s_size,
				verbose,verifyonly) != 0)
				err++;
		}
		else if (verbose)
			printf("???\n");
		shdr++;
	}

	if (verbose & !verifyonly)
		printf("entrypoint: 0x%lx\n",ahdr->entry);

	if (err)
		return(TFSERR_MEMFAIL);

	/* Store entry point: */
	if (entrypoint)
		*entrypoint = (long)(ahdr->entry);

	return(TFS_OKAY);
}

#elif TFS_EBIN_ELF

/* tfsloadelf():
 *	The file pointed to by fp has been determined to be an ELF file.
 *	This function loads the sections of that file into the designated 
 *	locations.
 *	Caches are flushed after loading each loadable section.
 */
int
tfsloadebin(TFILE *fp,int verbose,long *entrypoint,int verifyonly)
{
	Elf32_Word	size, notproctot;
	int			i, err;
	char		*shname_strings;
	ELFFHDR		*ehdr;
	ELFSHDR		*shdr;

	/* Establish file header pointers... */
	ehdr = (ELFFHDR *)(TFS_BASE(fp));
	shdr = (ELFSHDR *)((int)ehdr + ehdr->e_shoff);
	err = 0;

	/* Verify basic file sanity... */
	if ((ehdr->e_ident[0] != 0x7f) || (ehdr->e_ident[1] != 'E') ||
		(ehdr->e_ident[2] != 'L') || (ehdr->e_ident[3] != 'F'))
		return(TFSERR_BADHDR);

	/* Store the section name string table base: */
	shname_strings = (char *)ehdr + shdr[ehdr->e_shstrndx].sh_offset;

	notproctot = 0;

	/* For each section header, relocate or clear if necessary... */
	for (i=0;!err && i<ehdr->e_shnum;i++,shdr++) {
		if ((size = shdr->sh_size) == 0)
			continue;

		if ((verbose) && (ehdr->e_shstrndx != SHN_UNDEF))
			printf("%-10s: ", shname_strings + shdr->sh_name);

		if (!(shdr->sh_flags & SHF_ALLOC)) {
			notproctot += size;
			if (verbose)
				printf("     %7ld bytes not processed (tot=%ld)\n",
					size,notproctot);
			continue;
		}

		if (shdr->sh_type == SHT_NOBITS) {
			if (tfsmemset((char *)(shdr->sh_addr),0,size,
				verbose,verifyonly) != 0)
				err++;
		}
		else {
			if (TFS_ISCPRS(fp)) {
				extern	int decompress(char *,int, char *);
				int		outsize;

				outsize = decompress((char *)(ehdr)+shdr->sh_offset,size,
					(char *)shdr->sh_addr);
				if (outsize == -1) {
					err++;
					continue;
				}
				if (verbose)
					printf("dcmp %7d bytes from 0x%08lx to 0x%08lx\n",outsize,
						(ulong)(ehdr)+shdr->sh_offset,shdr->sh_addr);
			}
			else {
				if (tfsmemcpy((char *)(shdr->sh_addr),
					(char *)((int)ehdr+shdr->sh_offset),
					size,verbose,verifyonly) != 0)
					err++;
			}
			/* Flush caches for each loadable section... */
			flushDcache((char *)shdr->sh_addr,size);
			invalidateIcache((char *)shdr->sh_addr,size);
		}
	}

	if (err)
		return(TFSERR_MEMFAIL);

	if (verbose & !verifyonly)
		printf("entrypoint: 0x%lx\n",ehdr->e_entry);

	/* Store entry point: */
	if (entrypoint)
		*entrypoint = (long)(ehdr->e_entry);

	return(TFS_OKAY);
}

#endif	/* TFS_EBIN_XXXX */
#endif	/* INCLUDE_TFS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -