Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

convert.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 2, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 1999
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s):
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   // trivial checks
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   // create BrickOS executable header
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   // compare images & build relocation table.
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   // read command-line options
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 }

Generated on Fri Feb 25 08:02:39 2005 for brickos by  doxygen 1.3.9.1