?? mx1-load.c
字號:
/******************************************************************* MX1-Loader - DragonBall M9328/MX1 loader mx1-load.c - Universal MX1 loader main module (C) Copyright 2004 by Pavel Pisa - project originator http://cmp.felk.cvut.cz/~pisa (C) Copyright 2004 PiKRON Ltd. http://www.pikron.com USB support based on work of Roman Bartosinski (bartosr@centrum.cz) The MX1-Loader project can be used and distributed in compliance with any of next licenses - GPL - GNU Public License See file COPYING for details. - LGPL - Lesser GNU Public License - MPL - Mozilla Public License - and other licenses added by project originator Code can be modified and re-distributed under any combination of the above listed licenses. If contributor does not agree with some of the licenses, he/she can delete appropriate line. WARNING: if you delete all lines, you are not allowed to distribute code or sources in any form. *******************************************************************/#define _GNU_SOURCE#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <termios.h>#include <sys/time.h>#include <sys/types.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <getopt.h>#include <bfd.h>#include <inttypes.h>#include "rs232_fn.h"#include "universal-load.h"char *mx1_hwlink="rs232-mx1";char *mx1_sdev="/dev/ttyS0";int mx1_baud=57600;int mx1_waitrep=1000000;int mx1_fd;int mx1_xhz=18432000;int go_flg=0;int reset_flg=0;int break_flg=0;int upload_flg=0;int regerase_flg=0;int dump_flg=0;int masserase_flg=0;unsigned long masserase_end=0;int fill_flg;void *fill_pat_val;int fill_pat_len;char *file_format=NULL;int command=0;int blockmode=0;int erase_block=-1;int mem_type=0;unsigned long mem_start=0;unsigned long mem_length=0;unsigned long mem_offs=0;unsigned long go_addr=0;unsigned long entry_addr=0;uniload_alg_extprop_t *extprop_list=NULL;int hashmark=1;int uniload_load_use_lma=0;static int load_section_error;voiduniload_propeller(u_long addr, FILE * fp){static char *str = "\\|/-";static int index;int tv_diff;static struct timeval tv_old;struct timeval tv_actual; gettimeofday(&tv_actual,NULL); tv_diff=tv_actual.tv_sec-tv_old.tv_sec; if(!tv_diff) return; tv_old=tv_actual; if (!hashmark) return; fprintf(fp, "%c 0x%08lx\b\b\b\b\b\b\b\b\b\b\b\b", str[index++], addr); fflush(fp); index %= 4;}#define MEM_DUMP_ATONCE 1024#define MEM_MAX_ATONCE (1024*1024)int uniload_mem_dump(uniload_alg_info_t *algi, int mem_type, unsigned long start, unsigned long len){ int res; unsigned long addr=start; unsigned char buff[MEM_DUMP_ATONCE]; unsigned char *p; int blen=MEM_DUMP_ATONCE; int cnt; int i; while(len){ cnt=(len>blen)?blen:len; res=uniload_mem_read(algi, mem_type, addr, cnt, buff); if(res<0){ fprintf(stderr,"uniload_mem_dump: uniload_mem_read returned %d\n", res); return -1; } len-=cnt; p=buff; while(cnt){ printf("%08lX:",addr); i=cnt>16?16:cnt; addr+=i; cnt-=i; while(i--){ printf("%02X%c",*(p++),i?' ':'\n'); } } } return 0; }int uniload_upload_file(uniload_alg_info_t *algi, char *file_name, char *format, int mem_type, unsigned long start, unsigned long len){ FILE *file; char *mode="wb"; int res; unsigned long addr=start; unsigned char buff[MEM_DUMP_ATONCE]; int blen=MEM_DUMP_ATONCE; int cnt; if(!strcmp(file_name,"-")) file_name=NULL; if(file_name){ if((file=fopen(file_name,mode))==NULL) {perror("uniload_upload_file : file open"); return -1; } } else file=stdout; while(len){ cnt=(len>blen)?blen:len; res=uniload_mem_read(algi, mem_type, addr, cnt, buff); if(res<0){ fprintf(stderr,"uniload_upload_file: uniload_mem_read returned %d\n", res); if(file_name) fclose(file); return -1; } if(fwrite(buff,cnt,1,file)!=1){ perror("upload_file : file write"); return -1; } len-=cnt; addr+=cnt; } if(file_name) fclose(file); return 0;}int uniload_mem_fill(uniload_alg_info_t *algi, int mem_type, unsigned long start, unsigned long len, unsigned char *pat_val, int pat_len){ int res; unsigned long addr=start; unsigned char buff[MEM_DUMP_ATONCE]; int blen=MEM_DUMP_ATONCE; unsigned char *p; int cnt; int i; if(pat_len<=0) return -1; if((pat_len<=blen/2)&&(len>pat_len)){ i=blen<len+pat_len?blen:len+pat_len-1; if((pat_len==1)){ blen=i; memset(buff,*pat_val,blen); }else{ i=i/pat_len; blen=i*pat_len; for(p=buff;i;i--,p+=pat_len){ memcpy(p,pat_val,pat_len); } } pat_val=buff; } else { blen=pat_len; } while(len){ cnt=(len>blen)?blen:len; res=uniload_mem_write(algi, mem_type, addr, cnt, pat_val); if(res<0){ fprintf(stderr,"uniload_mem_fill: uniload_mem_write returned %d\n", res); return -1; } len-=cnt; addr+=cnt; } return 0; }int uniload_do_load_plain_binary(uniload_alg_info_t *algi, char *file_name){ FILE *file; char *mode="rb"; int res; unsigned long addr=algi->mem_offs; unsigned char *buff; int blen=MEM_DUMP_ATONCE; int cnt; if(!strcmp(file_name,"-")) file_name=NULL; if(file_name){ if((file=fopen(file_name,mode))==NULL) {perror("uniload_do_load_plain_binary : file open"); return -1; } } else file=stdin; if(algi->max_blksize){ blen=algi->max_blksize<MEM_MAX_ATONCE?algi->max_blksize:MEM_MAX_ATONCE; } buff=malloc(blen); if(!buff){ blen=MEM_DUMP_ATONCE; buff=malloc(blen); if(!buff) return -1; } while(1){ cnt=fread(buff,1,blen,file); if(cnt==0) break; if(cnt<0){ perror("uniload_do_load_plain_binary : file read"); if(file_name) fclose(file); free(buff); return -1; } uniload_propeller(addr, stdout); res=uniload_mem_write(algi, algi->def_mem_type, addr, cnt, buff); if(res<0){ fprintf(stderr,"uniload_do_load_plain_binary: uniload_mem_write addr 0x%lx returned %d\n", addr, res); if(file_name) fclose(file); free(buff); return -1; } addr+=cnt; } if(file_name) fclose(file); free(buff); return 0;}/*----------------------------------------------------------------*/static voiduniload_load_section(bfd * abfd, sec_ptr sec, PTR priv){ u_long addr; u_long load_bytes; file_ptr offset; int cnt; char *cbuf; uniload_alg_info_t *algi=(uniload_alg_info_t *)priv; int ret; long cbuf_size=algi->max_blksize; if(!cbuf_size) cbuf_size=512; dbprintf("uniload_load_section:\n\tsection %s index %d\n", sec->name, sec->index); dbprintf("\tflags %#x raw_size 0x%08lx cooked_size 0x%08lx\n", sec->flags, (long)sec->_raw_size, (long)sec->_cooked_size); dbprintf("\tvma %#lx lma %#lx output_offset %#lx\n", (long)sec->vma, (long)sec->lma, (long)sec->output_offset); if ((load_section_error < 0) || ((bfd_get_section_flags(abfd, sec) & SEC_LOAD) == 0)) { return; } if(!uniload_load_use_lma) addr = bfd_section_vma(abfd, sec); else addr = bfd_section_lma(abfd, sec); if ((load_bytes = bfd_section_size(abfd,sec)) == 0) return; if(cbuf_size>load_bytes) cbuf_size = load_bytes; cbuf = malloc(cbuf_size); if(!cbuf){ dbprintf("cannot allocate cbuf %ld bytes\n", cbuf_size); load_section_error = -1; return; } offset = 0; while (load_bytes) { if (load_bytes > cbuf_size) { cnt = cbuf_size; } else { cnt = load_bytes; } /* printf("cbuf_size %ld cnt %d\n",cbuf_size, cnt); */ if (!bfd_get_section_contents(abfd, sec, cbuf, offset, cnt)) { dbprintf("read error section %s\n", sec->name); load_section_error = -1; free(cbuf); return; } /* mx1_wrb_filt(mx1_bfilt,(caddr_t) addr, cnt, cbuf)) */ if ((ret=uniload_mem_write(algi, algi->def_mem_type, addr+algi->mem_offs, cnt, cbuf))<0) { dbprintf("write error on block write, written %d returned %d errno %d\n", cnt, ret, errno); load_section_error = -2; free(cbuf); return; } load_bytes -= cnt; addr += cnt; offset += cnt; uniload_propeller(addr, stdout); } free(cbuf);}static int bfd_initialized;static bfd * prepare_binary(char *file_name){ bfd *abfd; if (!bfd_initialized) { bfd_init(); bfd_initialized = 1; } abfd = bfd_openr(file_name, 0); if (!abfd) { dbprintf("Unable to open file %s\n", file_name); return NULL; } if (bfd_check_format(abfd, bfd_object) == 0) { dbprintf("File %s is not an object file\n", file_name); bfd_close(abfd); return NULL; } return abfd;}/* * load a binary file, returns error codes */intuniload_do_load_binary(char *file_name, char *entry_name, u_long *entry_pt, uniload_alg_info_t *algi){ bfd *abfd; u_long entry_addr = 0; if ((abfd = prepare_binary(file_name)) == NULL) return -3; if (entry_name) while (isspace(*entry_name)) entry_name++; if (entry_name && isdigit(*entry_name)) { entry_addr = strtoul (entry_name, NULL, 0); } else if (entry_name) { long i, symcnt; asymbol **symtab; if ((i=bfd_get_symtab_upper_bound(abfd))<=0 || !(symtab=malloc(i))) return -3; if ((symcnt = bfd_canonicalize_symtab (abfd, symtab))<0) return -3; for (i=0; i<symcnt; i++) { if (!strcmp (entry_name, symtab[i]->name)) { entry_addr = symtab[i]->section->vma + symtab[i]->value; break; } } } else { entry_addr = bfd_get_start_address(abfd); } if(entry_pt) *entry_pt = entry_addr; load_section_error = 0; bfd_map_over_sections(abfd, uniload_load_section, algi); if (hashmark) { printf(" . \b\b\b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } bfd_close(abfd); return load_section_error;}intuniload_do_load_binary_section(char *file_name, char *section_name, uniload_alg_info_t *algi){ bfd *abfd; asection *sec; if ((abfd = prepare_binary(file_name)) == NULL) return -3; if ((sec = bfd_get_section_by_name(abfd, section_name)) == NULL) return -4; load_section_error = 0; if (hashmark) { printf(" "); fflush(stdout); } uniload_load_section(abfd, sec, algi); if (hashmark) { printf("\r \r"); fflush(stdout); } bfd_close(abfd); return load_section_error;}int uniload_download_file(uniload_alg_info_t *algi, char *file_name, char *file_format, char *entry_name, u_long *entry_pt){ int ret; if(file_format){ if(!strcmp(file_format,"binary")){ ret=uniload_do_load_plain_binary(algi, file_name); return ret; } } ret=uniload_do_load_binary(file_name, entry_name, entry_pt, algi); return ret;}/*----------------------------------------------------------------*/int si_long(char **ps,long *val,int base){ char *p; *val=strtol(*ps,&p,base); if(*ps==p) return -1; *ps=p; return 1;}int add_to_arr(void **pdata,int *plen,int base,char *str){ char *s=str; long val; void *p; do{ while(*s && strchr(", \t:;",*s)) s++; if(!*s) break; if(si_long(&s,&val,base)<0){ return -1; } if(*pdata==NULL){ *plen=0; *pdata=p=malloc(1); }else{ p=realloc(*pdata,*plen+1); if(p==NULL) return -1; *pdata=p; } ((unsigned char*)p)[*plen]=val; (*plen)++; } while(1); return 1;}/*----------------------------------------------------------------*/int uniload_extprop_add(uniload_alg_info_t *algi, uniload_alg_extprop_t *extprop){ extprop->next=algi->extprop; algi->extprop=extprop; return 0;}uniload_alg_extprop_t *uniload_extprop_find(uniload_alg_info_t *algi, char *key){ uniload_alg_extprop_t *extprop=algi->extprop;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -