📄 tfsloader.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. * * 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"#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. */inttfsloadebin(TFILE *fp,int verbose,long *entrypoint,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) 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. */inttfsloadebin(TFILE *fp,int verbose,long *entrypoint,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 (verbose) printf("%-10s: ",shdr->s_name); if (ISLOADABLE(shdr->s_flags)) { 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 { 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. */inttfsloadebin(TFILE *fp,int verbose,long *entrypoint,int verifyonly){ Elf32_Word size, notproctot; int i, err; char *shname_strings; ELFFHDR *ehdr; ELFSHDR *shdr; 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; 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)) { 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 + -