📄 tfsloader.c
字号:
/* If incoming section name is specified, then we only load the
* section with that name...
*/
if ((sname != 0) && (strcmp(sname,name) != 0))
continue;
if ((verbose) && (ehdr->e_shstrndx != SHN_UNDEF))
showSection(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;
}
sh_addr = shdr->sh_addr;
/* Look to the program header to see if the destination address
* of this section needs to be adjusted. If this section is
* within a program header and that program header's members
* p_vaddr & p_paddr are not equal, then adjust the section
* address based on the delta between p_vaddr and p_paddr...
*/
phdr = (ELFPHDR *)((int)ehdr + ehdr->e_phoff);
for (j=0;j<ehdr->e_phnum;j++,phdr++) {
if ((phdr->p_type == PT_LOAD) &&
(sh_addr >= phdr->p_vaddr) &&
(sh_addr < phdr->p_vaddr+phdr->p_filesz) &&
(phdr->p_vaddr != phdr->p_paddr)) {
sh_addr += (phdr->p_paddr - phdr->p_vaddr);
break;
}
}
if (shdr->sh_type == SHT_NOBITS) {
if (s_memset((char *)(sh_addr),0,size,
verbose,verifyonly) != 0)
err++;
}
else {
#if INCLUDE_UNZIP
if (TFS_ISCPRS(fp)) {
int outsize;
outsize = decompress((char *)(ehdr)+shdr->sh_offset,size,
(char *)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,sh_addr);
}
}
else
#endif
{
if (tfsld_memcpy((char *)(sh_addr),
(char *)((int)ehdr+shdr->sh_offset),
size,verbose,verifyonly) != 0)
err++;
}
/* Flush caches for each loadable section... */
flushDcache((char *)sh_addr,size);
invalidateIcache((char *)sh_addr,size);
}
}
if (err)
return(TFSERR_MEMFAIL);
if (verbose && !verifyonly && !sname)
showEntrypoint(ehdr->e_entry);
/* Store entry point: */
if (entrypoint)
*entrypoint = (long)(ehdr->e_entry);
return(TFS_OKAY);
}
#endif
#if TFS_EBIN_ELFMSBIN | TFS_EBIN_MSBIN
/* tfsloadmsbin():
* This loader is a bit different than the others.
* The model for AOUT, COFF & ELF is simply to load each section from
* the stored location in flash to the location specifed by the section
* header. The sections may be compressed.
* The MSBIN loader supports a few additional options because of the
* fact that WinCE files can be formatted as .bin or .nbo. When
* the file is the ".bin" type, then this loader is used similar to
* the AOUT, COFF & ELF loaders. When the file is the ".nbo" type,
* then it is simply loaded into the starting address of the target's
* DRAM and the entrypoint is that base address.
* To support this scheme, TFS uses both the 'c' flag (compressed)
* and the extension on the filename as follows...
*
* 1 filename.bin with 'c' flag inactive:
* Load the file as specified by the sections within the file
* header.
* 2 filename.bin with 'c' flag active:
* Load the file as specified by the sections within the file
* header and assume each section is compressed.
* 3 filename.nbo with 'c' flag inactive:
* Copy the entire content of the file from TFS flash space to
* APPRAMBASE and return the address APPRAMBASE as the entrypoint.
* 4 filename.nbo with 'c' flag active:
* Decompress the entire content of the file from TFS flash space
* to APPRAMBASE and return the address APPRAMBASE as the entrypoint.
*
* In three of the 4 cases above (1,2&3) some level of sanity checking
* can be done on the file prior to beginning the load. For the 4th
* case there is no sanity check, this function assumes the file is
* compressed and is destined for the base of DRAM.
*/
int
tfsloadmsbin(TFILE *fp,int verbose,long *entrypoint,char *sname,int verifyonly)
{
ulong offset;
MSBINFHDR filhdr;
MSBINSHDR scnhdr;
char *dot;
int err, snum;
if (tfsTrace)
printf("tfsloadmsbin(%s)\n",TFS_NAME(fp));
dot = strrchr(TFS_NAME(fp),'.');
if (!dot)
return(TFSERR_BADEXTENSION);
/* Check the filename extension for ".bin" or ".nbo" and process
* accordingly...
*/
if (strcmp(dot,".bin") == 0) {
#if INCLUDE_UNZIP
if (TFS_ISCPRS(fp)) {
return(TFSERR_NOTAVAILABLE);
}
#endif
/* Verify basic file sanity... */
if (memcmp((char *)TFS_BASE(fp),MSBIN_SYNC_DATA,MSBIN_SYNC_SIZE) != 0)
return(TFSERR_BADHDR);
/* The file header is at offset MSBIN_SYNC_SIZE in the
* file, so copy it from the file to a local structure...
*/
memcpy((char *)&filhdr,(TFS_BASE(fp) + MSBIN_SYNC_SIZE),
sizeof(MSBINFHDR));
/* Start by clearing the entire image space to zero...
*/
if (verbose)
printf("MsbinImage: ");
s_memset((char *)filhdr.imageaddr,0,(int)filhdr.imagelen,verbose,
verifyonly);
err = snum = 0;
offset = (ulong)(TFS_BASE(fp) + MSBIN_SYNC_SIZE + sizeof(MSBINFHDR));
/* Walk through all sections within the file. For each section,
* copy the structure out of TFS to local space, then process it.
*/
for(snum = 1;err==0;snum++) {
memcpy((char *)&scnhdr,(char *)offset,sizeof(MSBINSHDR));
offset += sizeof(MSBINSHDR);
/* The image terminates with an image record header with the
* physical address and checksum set to zero...
*/
if ((scnhdr.addr == 0) && (scnhdr.csum == 0))
break;
if (verbose)
printf("section %02d: ", snum);
if (tfsld_memcpy((char *)(scnhdr.addr),
(char *)offset,scnhdr.len,verbose,verifyonly) != 0)
err++;
/* Flush caches for each loadable section... */
flushDcache((char *)scnhdr.addr,scnhdr.len);
invalidateIcache((char *)scnhdr.addr,scnhdr.len);
offset += scnhdr.len;
}
if (err)
return(TFSERR_MEMFAIL);
if (verbose && !verifyonly && !sname)
showEntrypoint(filhdr.imageaddr);
/* Store entry point: */
if (entrypoint)
*entrypoint = (long)(filhdr.imageaddr);
}
else if (strcmp(dot,".nb0") == 0) {
char *drambase;
drambase = (char *)getAppRamStart();
#if INCLUDE_UNZIP
if (TFS_ISCPRS(fp)) {
decompress((char *)TFS_BASE(fp), (int)TFS_SIZE(fp),drambase);
}
else
#endif
{
memcpy(drambase,(char *)TFS_BASE(fp),(int)TFS_SIZE(fp));
}
/* Flush caches for each loadable section... */
flushDcache(drambase,(int)TFS_SIZE(fp));
invalidateIcache(drambase,(int)TFS_SIZE(fp));
/* Store entry point: */
if (entrypoint)
*entrypoint = (long)(drambase);
}
else {
return(TFSERR_BADEXTENSION);
}
return(TFS_OKAY);
}
#endif
int
tfsloadebin(TFILE *fp,int verbose,long *entrypoint,char *sname,int verifyonly)
{
#if TFS_EBIN_ELFMSBIN
int err;
#endif
#if !INCLUDE_UNZIP
/* If the file is compressed, but decompression is not built into
* the monitor, then return an error that indicates that the
* needed facility in TFS is not enabled...
*/
if (TFS_ISCPRS(fp))
return(TFSERR_NOTAVAILABLE);
#endif
/* If verbosity is greater than one and verifyonly is not set, then
* we are simply dumping a map, so start with an appropriate
* header...
*/
if ((verbose > 1) && (verifyonly == 0))
printf("Load map:\n");
#if TFS_EBIN_AOUT
return(tfsloadaout(fp,verbose,entrypoint,sname,verifyonly));
#elif TFS_EBIN_COFF
return(tfsloadcoff(fp,verbose,entrypoint,sname,verifyonly));
#elif TFS_EBIN_ELF
return(tfsloadelf(fp,verbose,entrypoint,sname,verifyonly));
#elif TFS_EBIN_MSBIN
return(tfsloadmsbin(fp,verbose,entrypoint,sname,verifyonly));
#elif TFS_EBIN_ELFMSBIN
err = tfsloadelf(fp,verbose,entrypoint,sname,verifyonly);
if (err == TFSERR_BADHDR)
return(tfsloadmsbin(fp,verbose,entrypoint,sname,verifyonly));
else
return(err);
#else
#error Invalid TFS_EBIN type.
#endif
}
#endif /* INCLUDE_TFS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -