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

📄 tfsloader.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 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 + -