コード例 #1
0
ファイル: exec_elf.c プロジェクト: xmyth/pmon-osolution
static int
   elfreadsyms (int fd, Elf32_Ehdr *eh, Elf32_Shdr *shtab, int flags)
{
	Elf32_Shdr *sh, *strh, *shstrh, *ksh;
	Elf32_Sym *symtab;
	Elf32_Ehdr *keh;
	char *shstrtab, *strtab, *symend;
	int nsym, offs, size, i;
	int *symptr;

	/* Fix up twirl */
	if (bootseg++ > 0) {
		fprintf (stderr, "\b + ");
	}

	/*
	 *  If we are loading symbols to support kernel DDB symbol handling
	 *  make room for an ELF header at _end and after that a section
	 *  header. DDB then finds the symbols using the data put here.
	 */
	if(flags & KFLAG) {
		tablebase = roundup(tablebase, sizeof(long));
		symptr = (int *)tablebase;
		tablebase += sizeof(int *) * 2;
		keh = (Elf32_Ehdr *)tablebase;
		tablebase += sizeof(Elf32_Ehdr); 
		tablebase = roundup(tablebase, sizeof(long));
		ksh = (Elf32_Shdr *)tablebase;
		tablebase += roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long)); 
		memcpy(ksh, shtab, roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long)));
		sh = ksh;
	}
	else {
		sh = shtab;
	}
	shstrh = &sh[eh->e_shstrndx];

	for (i = 0; i < eh->e_shnum; sh++, i++) {
		if (sh->sh_type == SHT_SYMTAB) {
			break;
		}
	}
	if (i >= eh->e_shnum) {
		return (0);
	}

	if(flags & KFLAG) {
		strh = &ksh[sh->sh_link];
		nsym = sh->sh_size / sh->sh_entsize;
		offs = sh->sh_offset;
		size = sh->sh_size;
		fprintf (stderr, "%d syms ", nsym);
	} else {
		strh = &shtab[sh->sh_link];
		nsym = (sh->sh_size / sh->sh_entsize) - sh->sh_info;
		offs = sh->sh_offset + (sh->sh_info * sh->sh_entsize);
		size = nsym * sh->sh_entsize;
		fprintf (stderr, "%d syms ", nsym);
	}



	/*
	 *  Allocate tables in correct order so the kernel grooks it.
	 *  Then we read them in the order they are in the ELF file.
	 */
	shstrtab = gettable(shstrh->sh_size, "shstrtab", flags);
	strtab = gettable(strh->sh_size, "strtab", flags);
	symtab = gettable(size, "symtab", flags);
	symend = (char *)symtab + size;


	do {
		if(shstrh->sh_offset < offs && shstrh->sh_offset < strh->sh_offset) {
#if 0
			/*
			 *  We would like to read the shstrtab from the file but since this
			 *  table is located in front of the shtab it is already gone. We can't
			 *  position backwards outside the current segment when using tftp.
			 *  Instead we create the names we need in the string table because
			 *  it can be reconstructed from the info we now have access to.
			 */
			if (!readtable (shstrh->sh_offset, (void *)shstrtab,
					shstrh->sh_size, "shstring", flags)) {
				return(0);
			}
#else
			memset(shstrtab, 0, shstrh->sh_size);
			strcpy(shstrtab + shstrh->sh_name, ".shstrtab");
			strcpy(shstrtab + strh->sh_name, ".strtab");
			strcpy(shstrtab + sh->sh_name, ".symtab");
#endif
			shstrh->sh_offset = 0x7fffffff;
		}

		if (offs < strh->sh_offset && offs < shstrh->sh_offset) {
			if (!(readtable(fd, offs, (void *)symtab, size, "sym", flags))) {
				return (0);
			}
			offs = 0x7fffffff;
		}

		if (strh->sh_offset < offs && strh->sh_offset < shstrh->sh_offset) {
			if (!(readtable (fd, strh->sh_offset, (void *)strtab,
					 strh->sh_size, "string", flags))) {
				return (0);
			}
			strh->sh_offset = 0x7fffffff;
		}
		if (offs == 0x7fffffff && strh->sh_offset == 0x7fffffff &&
		    shstrh->sh_offset == 0x7fffffff) {
			break;
		}
	} while(1);


	if(flags & KFLAG) {
		/*
		 *  Update the kernel headers with the current info.
		 */
		shstrh->sh_offset = (Elf32_Off)shstrtab - (Elf32_Off)keh;
		strh->sh_offset = (Elf32_Off)strtab - (Elf32_Off)keh;
		sh->sh_offset = (Elf32_Off)symtab - (Elf32_Off)keh;
		memcpy(keh, eh, sizeof(Elf32_Ehdr));
		keh->e_phoff = 0;
		keh->e_shoff = sizeof(Elf32_Ehdr);
		keh->e_phentsize = 0;
		keh->e_phnum = 0;

		printf("\nKernel debugger symbols ELF hdr @ %p", keh);

		symptr[0] = (int)keh;
		symptr[1] = roundup((int)symend, sizeof(int));

	} else {

		/*
		 *  Add all global sybols to PMONs internal symbol table.
		 */
		for (i = 0; i < nsym; i++, symtab++) {
			int type;

			dotik (4000, 0);
			if (symtab->st_shndx == SHN_UNDEF ||
			    symtab->st_shndx == SHN_COMMON) {
				continue;
			}

			type = ELF_ST_TYPE (symtab->st_info);
			if (type == STT_SECTION || type == STT_FILE) {
				continue;
			}

			/* only use globals and functions */
			if (ELF_ST_BIND(symtab->st_info) == STB_GLOBAL ||
			    type == STT_FUNC){
				if (symtab->st_name >= strh->sh_size) {
					fprintf (stderr, "\ncorrupt string pointer");
					return (0);
				}
			}
			if (!newsym (strtab + symtab->st_name, symtab->st_value)) {
				fprintf (stderr, "\nonly room for %d symbols", i);
				return (0);
			}
		}
	}
	return (1);
}
コード例 #2
0
ファイル: flash.c プロジェクト: BarclayII/pmon-3amatx
/*
 *  Verify flash contents to ram contents.
 */
int
fl_verify_device(void *fl_base, void *data_base, int data_size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	void *fl_last;
	int ok;
	int i;


	dev = fl_devident(fl_base, &map);
	if(dev == NULL) {
		return(-3);	/* No flash device found at address */
	}

	if(data_size == -1 || (int)data_base == -1) {
		return(-4);		/* Bad parameters */
	}
	if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) {
		return(-4);	/* Size larger than device array */
	}

	if(verbose) {
		printf("Verifying FLASH. ");
	}

	for(i = 0; i < data_size; i += map->fl_map_width) {
		fl_last = fl_base;
		switch(map->fl_map_bus) {
		case FL_BUS_8:
			ok = (*((u_char *)fl_base) == *((u_char *)data_base));
			fl_base++;
			data_base++;
			break;

		case FL_BUS_16:
			ok = (*((u_short *)fl_base) == *((u_short *)data_base));
			fl_base += 2;
			data_base += 2;
			break;

		case FL_BUS_32:
			ok = (*((u_int *)fl_base) == *((u_int *)data_base));
			fl_base += 4;
			data_base += 4;
			break;

		case FL_BUS_64:
			movequad(&widedata, fl_base);
			ok = (bcmp(data_base, (void *)&widedata, 8) == 0);
			data_base += 8;
			fl_base += 8;
			break; 

		case FL_BUS_8_ON_64:
			ok = (*((u_char *)map->fl_map_base +
				   (((int)fl_base - map->fl_map_base) << 3)) ==
				*(u_char *)data_base++);
			fl_base++;
			break;
		}

		if(verbose & !ok) {
			printf(" error offset %p\n", fl_last);
			{
			char str[100];
			int timeout;
			printf("erase all chip(y/N)?");
			gets(str);
			if(str[0]=='y'||str[0]=='Y')
			{
				tgt_flashwrite_enable();
				fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */
				printf("Erasing all FLASH blocks. ");
				(*dev->functions->erase_chip)(map, dev);
				delay(1000);
				for(timeout = 0 ;
					((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff,0, TRUE)) == 1)
						&& (timeout < PFLASH_MAX_TIMEOUT); timeout++) {
						delay(1000);
					if(verbose) {
						dotik(256, 0);
					}
				}
				delay(1000);

				if(!(timeout < PFLASH_MAX_TIMEOUT)) {
					(*dev->functions->erase_suspend)(map, dev);
				}
				(*dev->functions->reset)(map, dev);
				tgt_flashwrite_disable();
				fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */
			}
		   }
			break;
		}
		else if(verbose) {
			dotik(32, 0);
		}
	}

	if(verbose && ok) {
		printf("\b No Errors found.\n");
	}
	
	return(ok);
}
コード例 #3
0
ファイル: flash.c プロジェクト: BarclayII/pmon-3amatx
/*
 *  Program a flash device. Assumed that the area is erased already.
 */
int
fl_program_device(void *fl_base, void *data_base, int data_size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	int ok;
	int i, off;
	
	if(tgt_flashwrite_enable() == 0) {
		return(-2);	/* Flash can't be write enabled */
	}
	dev = fl_devident(fl_base, &map);
	if(dev == NULL) {
		tgt_flashwrite_disable();
		return(-3);	/* No flash device found at address */
	}

	if(data_size == -1 || (int)data_base == -1) {
		return(-4);		/* Bad parameters */
	}
	if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) {
		return(-4);	/* Size larger than device array */
	}

	off = (int)(fl_base - map->fl_map_base) + map->fl_map_offset;
	if(verbose) {
		printf("Programming FLASH. ");
	}

	tgt_flashwrite_enable();
    fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */

	for(i = 0; i < data_size; i += map->fl_map_width) {

		ok = (*dev->functions->program)(map, dev, (int)off, data_base);

		switch(map->fl_map_bus) {
		case FL_BUS_8:
		case FL_BUS_8_ON_64:
			off++;
			data_base++;
			break;

		case FL_BUS_16:
			data_base += 2;
			off += 2;
			break;

		case FL_BUS_32:
			data_base += 4;
			off += 4;
			break;

		case FL_BUS_64:
			data_base += 8;
			off += 8;
			break; 
		}

		if(verbose) {
			dotik(256, 0);
		}
	}

	(*dev->functions->reset)(map, dev);

	if(verbose) {
		printf("\b Done.\n");
	}
	
	tgt_flashwrite_disable();
    fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */
	return(ok);
}
コード例 #4
0
ファイル: flash.c プロジェクト: BarclayII/pmon-3amatx
/*
 *  Erase the flash device(s) addressed.
 */
int
fl_erase_device(void *base, int size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	int mask, ok, block;
	int timeout;

	if(tgt_flashwrite_enable() == 0) {
		printf("Flash can't be write enabled\n");
		return(-2);	/* Flash can't be write enabled */
	}

	dev = fl_devident(base, &map);
	if(dev == NULL) {
		printf("No flash found at %x\n",(u_int32_t)base);
		return(-3);	/* No flash device found at address */
	}

	/*
	 * Sanity checks!
	 */
	if(size == -1 && (int)base == map->fl_map_base) {
		size = map->fl_map_size;	/* Entire flash */
	}

        if(dev->fl_varsecsize != NULL) {
                int offset = (int)(base - map->fl_map_base) + map->fl_map_offset;
                int totalsize;
		printf("offset=%x,base=%x\n",offset,map->fl_map_base);

                for(block=0, totalsize=0; totalsize < offset; block++) {
                        totalsize += dev->fl_varsecsize[block] * map->fl_map_chips;
                }

                mask = ((dev->fl_varsecsize[block] * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }
                base -= map->fl_map_base;

        } else {
                mask = ((dev->fl_secsize * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }

                base -= map->fl_map_base;
                block = (int)base / map->fl_map_chips / dev->fl_secsize;
                size = (size + mask) & ~mask; /* Round up to catch entire flash */
        }
        
        tgt_flashwrite_enable();
        fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */
        
	while(size > 0) {
		int boffs = (int)base;
#if 0
		if(size == map->fl_map_size &&
			dev->fl_cap & (FL_CAP_DE|FL_CAP_A7)) {
			/*
			 * Erase entire devices using the BULK erase feature
			 */
			if(verbose) {
				printf("Erasing all FLASH blocks. ");
			}

			(*dev->functions->erase_chip)(map, dev);

			size = 0;
		}
		else {
#endif
			/*
			 * Not entire flash or no BULK erase feature. We
			 * use sector/block erase.
			 */
			if(verbose) {
				printf("\rErasing FLASH block %3d      \b\b\b\b\b", block);
			}

			if((*dev->functions->erase_sector)(map, dev, boffs) != 0) {

				printf("\nError: Failed to enter erase mode\n");
				(*dev->functions->erase_suspend)(map, dev);
				(*dev->functions->reset)(map, dev);
				return(-4);
			}

                        if(dev->fl_varsecsize != NULL) {
                                base += dev->fl_varsecsize[block] * map->fl_map_chips;
                                size -= dev->fl_varsecsize[block] * map->fl_map_chips;
                                block++;
                        } else {
                                base += dev->fl_secsize * map->fl_map_chips;
                                size -= dev->fl_secsize * map->fl_map_chips;
                                block++;
                        }
//		}

		delay(1000);
		for(timeout = 0 ;
		    ((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff, boffs, TRUE)) == 1)
				&& (timeout < PFLASH_MAX_TIMEOUT); timeout++) {
				delay(1000);
			if(verbose) {
				dotik(256, 0);
			}
		}
		delay(1000);

		if(!(timeout < PFLASH_MAX_TIMEOUT)) {
			(*dev->functions->erase_suspend)(map, dev);
		}
		(*dev->functions->reset)(map, dev);

		if(verbose) {
			if(!(timeout < PFLASH_MAX_TIMEOUT)) {
/* XXX if timed out what should really happen here? This doesn't look right. */
				printf("\b\b, command timed out!\n");
			} else {
				printf("\b Done.\n");
			}
		}
	}

	tgt_flashwrite_disable();
    fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */
	return(ok);
}



int fl_program(void *fl_base, void *data_base, int data_size, int verbose)
{
        char *nvrambuf;
        char *nvramsecbuf;
	    char *nvram;
		int offs,count,left;
		struct fl_device *dev=fl_devident(fl_base,0);
		int nvram_size=dev->fl_secsize;

	nvramsecbuf = (char *)malloc(nvram_size);
	if(nvramsecbuf == 0) {
		printf("Warning! Unable to malloc nvrambuffer!\n");
		return(-1);
	}
      nvram = fl_base;
	  left = data_size;
	  while(left)
	  {

		offs = (int)nvram &(nvram_size - 1);
        nvram  = (int)nvram & ~(nvram_size - 1);
		count = min(nvram_size-offs,left);
		 

        memcpy(nvramsecbuf, nvram, nvram_size);		
		nvrambuf = nvramsecbuf + offs;
		memcpy(nvrambuf,data_base,count);
#ifdef NVRAM_IN_FLASH
#ifndef LS3B_SPI_BOOT        
		if(fl_erase_device(nvram, nvram_size, verbose)) {
		printf("Error! Nvram erase failed!\n");
		free(nvramsecbuf);
                return(0);
        }
        
		if(fl_program_device(nvram, nvramsecbuf, nvram_size, verbose)) {
		printf("Error! Nvram program failed!\n");
		free(nvramsecbuf);
                return(0);
        }
#else
        spi_erase( (unsigned long)(nvram)- tgt_flashmap()->fl_map_base, nvram_size);
		if( spi_program(nvramsecbuf, (unsigned long)(nvram)- tgt_flashmap()->fl_map_base, nvram_size, 0) ) { 
		     printf("Error! Nvram program failed!\n");
		     free(nvramsecbuf);
		     return(0);
		}
#endif
#endif

		data_base += count;
		nvram += nvram_size;
		left -= count;
		}
	free(nvramsecbuf);
        return 0;
}
コード例 #5
0
ファイル: flash.c プロジェクト: BernardXiong/loongson1-pmon
/*
 *  Verify flash contents to ram contents.
 */
int
fl_verify_device(void *fl_base, void *data_base, int data_size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	void *fl_last;
	int ok;
	int i;


	dev = fl_devident(fl_base, &map);
	if(dev == NULL) {
		return(-3);	/* No flash device found at address */
	}

	if(data_size == -1 || (int)data_base == -1) {
		return(-4);		/* Bad parameters */
	}
	if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) {
		return(-4);	/* Size larger than device array */
	}

	if(verbose) {
		printf("Verifying FLASH. ");
	}

	for(i = 0; i < data_size; i += map->fl_map_width) {
		fl_last = fl_base;
		switch(map->fl_map_bus) {
		case FL_BUS_8:
			ok = (*((u_char *)fl_base) == *((u_char *)data_base)); fl_base += 1; data_base += 1;
			break;

		case FL_BUS_16:
			ok = (*(u_short *)fl_base == *((u_short *)data_base)); fl_base += 2; data_base += 2;
			break;

		case FL_BUS_32:
			ok = (*(u_int *)fl_base == *(u_int *)data_base); fl_base += 4; data_base += 4;
			break;

		case FL_BUS_64:
			movequad(&widedata, fl_base);
			ok = (bcmp(data_base, (void *)&widedata, 8) == 0);
			data_base += 8;
			fl_base += 8;
			break; 

		case FL_BUS_8_ON_64:
			ok = (*((u_char *)map->fl_map_base +
				   (((int)fl_base - map->fl_map_base) << 3)) ==
				*(u_char *)data_base++);
			fl_base++;
			break;
		}

		if(verbose & !ok) {
			printf(" error offset %p\n", fl_last);
			{
			char str[100];
			int timeout;
			printf("erase all chip(y/N)?");
			gets(str);
			if(str[0]=='y'||str[0]=='Y')
			{
				tgt_flashwrite_enable();
				printf("Erasing all FLASH blocks. ");
				fl_erase_device(map->fl_map_base,map->fl_map_size,FALSE);
				tgt_flashwrite_disable();
			}
			}
			break;
		}
		else if(verbose) {
			dotik(32, 0);
		}
	}

	if(verbose && ok) {
		printf("\b No Errors found.\n");
	}
	
	return(ok);
}
コード例 #6
0
ファイル: flash.c プロジェクト: BernardXiong/loongson1-pmon
  __attribute__((weak))fl_erase_device(void *base, int size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	int mask, ok, block;
	int timeout;

	if(tgt_flashwrite_enable() == 0) {
		printf("Flash can't be write enabled\n");
		return(-2);	/* Flash can't be write enabled */
	}

	dev = fl_devident(base, &map);
	if(dev == NULL) {
		printf("No flash found at %x\n",(u_int32_t)base);
		return(-3);	/* No flash device found at address */
	}

	/*
	 * Sanity checks!
	 */
	if(size == -1 && (int)base == map->fl_map_base) {
		size = map->fl_map_size;	/* Entire flash */
	}

        if(dev->fl_varsecsize != NULL) {
                int offset = (int)(base - map->fl_map_base) + map->fl_map_offset;
                int totalsize;
		printf("offset=%x,base=%x\n",offset,map->fl_map_base);

                for(block=0, totalsize=0; totalsize < offset; block++) {
                        totalsize += dev->fl_varsecsize[block] * map->fl_map_chips;
                }

                mask = ((dev->fl_varsecsize[block] * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }
                base -= map->fl_map_base;

        } else {
                mask = ((dev->fl_secsize * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }

                base -= map->fl_map_base;
                block = (int)base / map->fl_map_chips / dev->fl_secsize;
                size = (size + mask) & ~mask; /* Round up to catch entire flash */
        }
        
        tgt_flashwrite_enable();
        
	while(size > 0) {
		int boffs = (int)base;
		if(size == map->fl_map_size &&
			dev->fl_cap & (FL_CAP_DE|FL_CAP_A7)) {
			/*
			 * Erase entire devices using the BULK erase feature
			 */
			if(verbose) {
				printf("Erasing all FLASH blocks. ");
			}

			(*dev->functions->erase_chip)(map, dev);

			size = 0;
		}
		else {
			/*
			 * Not entire flash or no BULK erase feature. We
			 * use sector/block erase.
			 */
			if(verbose) {
				printf("\rErasing FLASH block %3d      \b\b\b\b\b", block);
			}

			if((*dev->functions->erase_sector)(map, dev, boffs) != 0) {
				printf("\nError: Failed to enter erase mode\n");
				(*dev->functions->erase_suspend)(map, dev);
				(*dev->functions->reset)(map, dev);
				return(-4);
			}

                        if(dev->fl_varsecsize != NULL) {
                                base += dev->fl_varsecsize[block] * map->fl_map_chips;
                                size -= dev->fl_varsecsize[block] * map->fl_map_chips;
                                block++;
                        } else {
                                base += dev->fl_secsize * map->fl_map_chips;
                                size -= dev->fl_secsize * map->fl_map_chips;
                                block++;
                        }
		}

		delay(1000);
		for(timeout = 0 ;
		    ((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff, boffs, TRUE)) == 1)
				&& (timeout < PFLASH_MAX_TIMEOUT); timeout++) {
				delay(1000);
			if(verbose) {
				dotik(256, 0);
			}
		}
		delay(1000);

		if(!(timeout < PFLASH_MAX_TIMEOUT)) {
			(*dev->functions->erase_suspend)(map, dev);
		}
		(*dev->functions->reset)(map, dev);

		if(verbose) {
			if(!(timeout < PFLASH_MAX_TIMEOUT)) {
/* XXX if timed out what should really happen here? This doesn't look right. */
				printf("\b\b, command timed out!\n");
			} else {
				printf("\b Done.\n");
			}
		}
	}

	tgt_flashwrite_disable();
	return(ok);
}