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

📄 tfsloader.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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, A.OUT and MSBIN are supported.  This requires that
 *	TFS_EBIN_COFF, TFS_EBIN_ELF, TFS_EBIN_AOUT or TFS_EBIN_MSBIN 
 *	respectively, be set in the monitor's config.h file.  Also, defining
 *	TFS_EBIN_ELFMSBIN will allow TFS to support both ELF and MSBIN.
 *
 *	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.
 *
 *	Note1: the majority of this code was edited with 4-space tabs.
 *	Note2: as more and more contributions are accepted, the term "author"
 *		   is becoming a mis-representation of credit.
 *
 *	Original author:	Ed Sutter
 *	Email:				esutter@lucent.com
 *	Phone:				908-582-2351
 */
#include "config.h"
#include "stddefs.h"
#include "genlib.h"
#include "tfs.h"
#include "tfsprivate.h"
#include "coff.h"
#include "elf.h"
#include "aout.h"
#include "msbin.h"
#if INCLUDE_TFS


/* tfsld_memcpy():
 * Front end to all memcpy calls done by the loader.
 * This function just does a quick check to make sure that the
 * address ranged being copied to is not part of the monitor's
 * own .bss space...
 *
 * How we return here depends on the verbosity level.  If verbosity
 * is greater than 1, then assume that this pass through tfsld_memcpy()
 * is to dump out map information, not to actually do a memcpy().
 * This same logic is used within the s_memcpy() routine and must remain
 * consistent to work properly.
 */
int
tfsld_memcpy(char *to, char *from, int count, int verbose, int verify)
{
	if (verbose <= 1) {
		if (inUmonBssSpace(to,to+count))
			return(-1);
	}

	return(s_memcpy(to,from,count,verbose,verify));
}

void
showEntrypoint(unsigned long entrypoint)
{
	printf(" entrypoint: 0x%lx\n",entrypoint);
}

void
showSection(char *sname)
{
	printf(" %-10s: ",sname);
}

#if TFS_EBIN_AOUT

/* tfsloadaout():
 *	The file pointed to by fp is assumed to be an AOUT
 *	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
tfsloadaout(TFILE *fp,int verbose,long *entrypoint,char *sname,int verifyonly)
{
	uchar	*tfrom, *dfrom;
	struct	exec *ehdr;

	if (tfsTrace)
		printf("tfsloadaout(%s)\n",TFS_NAME(fp));

	/* 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)
		showSection("text");

	if (tfsld_memcpy((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)
		showSection("data");

	if (tfsld_memcpy((char *)(ehdr->a_entry+ehdr->a_text),(char *)dfrom,
		ehdr->a_data,verbose,verifyonly) != 0)
		return(TFSERR_MEMFAIL);

	/* Clear out bss space: */
	if (verbose)
		showSection("bss");

	if (s_memset((char *)(ehdr->a_entry+ehdr->a_text+ehdr->a_data),
	    0,ehdr->a_bss,verbose,verifyonly) != 0)
		return(TFSERR_MEMFAIL);


	if (verbose & !verifyonly)
		showEntrypoint(ehdr->a_entry);

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

	return(TFS_OKAY);
}
#endif

#if TFS_EBIN_COFF

/* tfsloadcoff():
 *	The file pointed to by fp is assumed 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
tfsloadcoff(TFILE *fp,int verbose,long *entrypoint,char *sname,int verifyonly)
{
	int		i, err;
	FILHDR	*fhdr;
	AOUTHDR	*ahdr;
	SCNHDR	*shdr;

	if (tfsTrace)
		printf("tfsloadcoff(%s)\n",TFS_NAME(fp));

	/* 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 incoming section name is specified, then we only load the
		 * section with that name...
		 */
		if ((sname != 0) && (strcmp(sname,shdr->s_name) != 0))
			continue;

		if (verbose)
			showSection(shdr->s_name);

		if (ISLOADABLE(shdr->s_flags)) {
#if INCLUDE_UNZIP
			if (TFS_ISCPRS(fp)) {
				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
#endif
			{
				if (tfsld_memcpy((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 (s_memset((char *)(shdr->s_paddr),0,shdr->s_size,
				verbose,verifyonly) != 0)
				err++;
		}
		else if (verbose)
			printf("???\n");
		shdr++;
	}

	if (verbose && !verifyonly && !sname)
		showEntrypoint(ahdr->entry);

	if (err)
		return(TFSERR_MEMFAIL);

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

	return(TFS_OKAY);
}
#endif

#if TFS_EBIN_ELF | TFS_EBIN_ELFMSBIN

/* tfsloadelf():
 *	The file pointed to by fp is assumed 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
tfsloadelf(TFILE *fp,int verbose,long *entrypoint,char *sname,int verifyonly)
{
	Elf32_Word	size, notproctot;
	int			i, j, err;
	char		*shname_strings, *name;
	Elf32_Addr	sh_addr;
	ELFFHDR		*ehdr;
	ELFSHDR		*shdr;
	ELFPHDR		*phdr;

	if (tfsTrace)
		printf("tfsloadelf(%s)\n",TFS_NAME(fp));

	/* 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;
	
		name = shname_strings + shdr->sh_name;
	

⌨️ 快捷键说明

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