00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <fcntl.h>
00031 #include <sys/time.h>
00032 #include <sys/types.h>
00033 #include <signal.h>
00034 #include <errno.h>
00035
00036 #include <srecload.h>
00037 #include <lx.h>
00038
00039 #if (defined(__unix__) || defined(unix)) && !defined(USG)
00040 #include <sys/param.h>
00041 #endif
00042
00043 #define DEFAULT_STACK_SIZE 1024
00044 #define RELOC_MAX 16384
00045
00046
00047 #if (defined(__sun__) && defined(__svr4__)) || defined(BSD) // Solaris||BSD
00048 #undef HAVE_GETOPT_LONG
00049 #else
00050 #define HAVE_GETOPT_LONG 1
00051 #endif
00052
00053 #ifdef HAVE_GETOPT_LONG
00054 #include <getopt.h>
00055
00057 static const struct option long_options[]={
00058 {"stack" ,required_argument,0,'s'},
00059 {"verbose",no_argument ,0,'v'},
00060 {"display",no_argument ,0,'d'},
00061 {0 ,0 ,0,0 }
00062 };
00063
00064 #else // HAVE_GETOPT_LONG
00065
00066 #define getopt_long(ac, av, opt, lopt, lidx) (getopt((ac), (av), (opt)))
00067
00068 #endif // HAVE_GETOPT_LONG
00069
00070 int verbose_flag=0;
00071
00072
00074
00076 void lx_from_images(lx_t *lx,image_t *img,unsigned short stack_size) {
00077 const unsigned char diff_hi=(img[1].base - img[0].base) >> 8;
00078 const unsigned char diff_lo=(img[1].base - img[0].base) & 0xff;
00079 const unsigned short size=img[0].text_size + img[0].data_size;
00080
00081 int i;
00082
00083 if(verbose_flag)
00084 printf("diff_hi=0x%02x diff_lo=0x%02x\n",diff_hi,diff_lo);
00085
00086
00087
00088 if(img[0].text_size != img[1].text_size ||
00089 img[0].data_size != img[1].data_size ||
00090 img[0].bss_size != img[1].bss_size ) {
00091
00092 fprintf(stderr,"image size mismatch\n");
00093 exit(-1);
00094 }
00095 if(img[0].offset != img[1].offset) {
00096 fprintf(stderr,"starting offset mismatch\n");
00097 exit(-1);
00098 }
00099 if(!diff_hi || !diff_lo) {
00100 fprintf(stderr,"need images whose base offsets differ in high and low byte\n");
00101 exit(-1);
00102 }
00103
00104
00105
00106 lx->version =0;
00107 lx->base =img[0].base;
00108 lx->text_size =img[0].text_size;
00109 lx->data_size =img[0].data_size;
00110 lx->bss_size =img[0].bss_size;
00111 lx->stack_size=stack_size;
00112 lx->offset =img[0].offset;
00113 lx->num_relocs=0;
00114
00115 if(verbose_flag)
00116 printf("base =0x%04x offset =0x%04x\n"
00117 "text_size=0x%04x data_size=0x%04x bss_size=0x%04x stack_size=0x%04x\n",
00118 lx->base,lx->offset,lx->text_size,lx->data_size,lx->bss_size,lx->stack_size);
00119
00120 if((lx->reloc=malloc(RELOC_MAX*sizeof(unsigned short)))==NULL) {
00121 fprintf(stderr,"out of memory\n");
00122 exit(-1);
00123 }
00124 if((lx->text=malloc(size))==NULL) {
00125 fprintf(stderr,"out of memory\n");
00126 exit(-1);
00127 }
00128 memcpy(lx->text,img[0].text,size);
00129
00130
00131
00132 for(i=0; i<size; i++) {
00133 unsigned char c0=img[0].text[i];
00134 unsigned char c1=img[1].text[i];
00135
00136 if(verbose_flag)
00137 printf("0x%04x: %02x - %02x = %02x\n",i,c0,c1,0xff & (c1-c0));
00138
00139 if(c0!=c1) {
00140 unsigned char l0=img[0].text[i+1];
00141 unsigned char l1=img[1].text[i+1];
00142
00143 if(l0 == l1) {
00144 fprintf(stderr,"single byte difference at +0x%04x\n",i);
00145 exit(-1);
00146 } else {
00147 unsigned short addr0=((c0<<8) | l0) - img[0].base;
00148 unsigned short addr1=((c1<<8) | l1) - img[1].base;
00149
00150 if(addr0!=addr1) {
00151 fprintf(stderr,"relocation offset mismatch at +0x%04x\n",i);
00152 exit(-1);
00153 }
00154
00155 if(verbose_flag)
00156 printf("reloc[%d]=0x%04x\n",lx->num_relocs,i);
00157
00158 lx->reloc[lx->num_relocs++]=(unsigned short)i++;
00159 }
00160 }
00161 }
00162 }
00163
00165 int main(int argc, char **argv) {
00166 image_t img[2];
00167 lx_t lx;
00168 int opt;
00169 int display_flag = 0;
00170 unsigned short stack_size=DEFAULT_STACK_SIZE;
00171 #ifdef HAVE_GETOPT_LONG
00172 int option_index;
00173 #endif
00174
00175
00176
00177 while((opt=getopt_long(argc, argv, "s:vd",
00178 (struct option *)long_options, &option_index) )!=-1) {
00179 unsigned tmp;
00180
00181 switch(opt) {
00182 case 's':
00183 sscanf(optarg,"%x",&tmp);
00184 stack_size=(unsigned short)tmp;
00185 break;
00186 case 'v':
00187 verbose_flag=1;
00188 break;
00189 case 'd':
00190 display_flag=1;
00191 break;
00192 }
00193 }
00194
00195 if(argc-optind<3) {
00196 fprintf(stderr,"usage: %s file.ds1 file.ds2 file.lx\n"
00197 " [-s<stacksize>] [-v] [-d]\n"
00198 " size in hex, please.\n",
00199 argv[0]);
00200 exit(1);
00201 }
00202
00203 image_load(img , argv[optind++]);
00204 image_load(img+1, argv[optind++]);
00205 lx_from_images(&lx,img,stack_size);
00206
00207 if(lx_write(&lx, argv[optind])) {
00208 fprintf(stderr,"error writing %s\n",argv[optind]);
00209 return -1;
00210 }
00211
00212 if (display_flag) {
00213 printf("version=%d\n", lx.version);
00214 printf("base=0x%x\n", lx.base);
00215 printf("text_size=%d\n", lx.text_size);
00216 printf("data_size=%d\n", lx.data_size);
00217 printf("bss_size=%d\n", lx.bss_size);
00218 printf("stack_size=%d\n", lx.stack_size);
00219 printf("start_offset=%d\n", lx.offset);
00220 printf("num_relocs=%d\n", lx.num_relocs);
00221 printf("contiguous free memory required to download=%d\n",
00222 lx.text_size + lx.data_size*2 + lx.bss_size);
00223 }
00224
00225 return 0;
00226 }