tools/build-R2_19_3/fsboot/sbl/common.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *!
00003 *! FILE NAME  : common.c
00004 *!
00005 *! DESCRIPTION: Common functions for boot loader.
00006 *!
00007 *!
00008 *! ---------------------------------------------------------------------------
00009 *! HISTORY
00010 *!
00011 *! DATE         NAME               CHANGES
00012 *! ----         ----               -------
00013 *! ???  ? ????  Ronny Ranerup      Initial version
00014 *! ---------------------------------------------------------------------------
00015 *! (C) Copyright 1999, 2000, Axis Communications AB, LUND, SWEDEN
00016 *!***************************************************************************/
00017 /* 
00018  * $Id: common.c,v 1.1.1.1 2008/11/27 20:04:03 elphel Exp $ 
00019  */
00020 
00021 /**************************  Version  **************************************/
00022 
00023 char version[] = "Time-stamp: $Id: common.c,v 1.1.1.1 2008/11/27 20:04:03 elphel Exp $";
00024 
00025 /**************************  Include files  ********************************/
00026 
00027 #include <conf.h>
00028 #include <e100boot.h>
00029 #include <pcap.h>
00030 #include "boot_images.h"
00031 #include <reg_des.h>
00032 #include <common.h>
00033 
00034 #include <serial.h>
00035 #include <network.h>
00036 
00037 /**************************  Constants and macros  *************************/
00038 
00039 
00040 
00041 #define BOOT_CMDS_FILE "BOOT_CMDS"
00042 
00043 /**************************  Type definitions  *****************************/
00044 struct label_t {
00045   struct label_t *prev;
00046   udword addr;
00047   char *name;
00048 };
00049 
00050 /**************************  Global variables  *****************************/
00051 
00052 char needle[MAX_STRING_LEN] = {0,};     /* search needle for --find */
00053 int needle_len = 0;             
00054 
00055 int exitonfind = FALSE;
00056 
00057 int doing_flash = FALSE;        /* Just a flag to see if we should
00058                                    warn that it might take some
00059                                    time. */
00060 
00061 int toFiles             = FALSE;        /* Dump all packets to files. */
00062 int cmdsOnly            = FALSE;        /* Just dump boot cmds to file. */
00063 int netBoot             = TRUE;         /* Do network boot? */
00064 int serBoot             = FALSE;        /* Do serial boot? */
00065 
00066 int listenOnly          = FALSE; /* if set, don't transmit over eth, just listen */
00067 
00068 struct label_t *loop_label = NULL;
00069 struct label_t *label      = NULL;
00070 
00071 struct packet_buf *first_packet = NULL;
00072 struct packet_buf *last_packet  = NULL;
00073 
00074 struct packet_buf *boot_cmds_packet;
00075 
00076 int create_boot_loader = TRUE;
00077 
00078 /* We use the INTERNAL boot image as default */
00079 char boot_loader_file[MAX_STRING_LEN] = INTERNAL_NW;
00080 
00081 int noleds = FALSE; /* Use boot images that doesn't toggle leds? */
00082 
00083 struct boot_files_T *first_boot_file = NULL;
00084 struct boot_files_T *last_boot_file = NULL;
00085 
00086 #define NR_BOOT_CMDS (SIZE_OF_BOOT_CMDS/sizeof(unsigned int))
00087 unsigned int boot_cmds[NR_BOOT_CMDS];
00088 
00089 int boot_cmds_cnt = 0;
00090 
00091 int svboot = FALSE;
00092 
00093 int quiet = 0;
00094 
00095 struct packet_header_T send_packet;
00096 struct packet_header_T *receive_packet;
00097 
00098 int seq_nr           = 0;
00099 unsigned nrof_net_packets = 0;  /* total number of packets to transmit */
00100 
00101 /* debug flags */
00102 int db1 = FALSE;
00103 int db2 = FALSE;
00104 int db3 = FALSE;
00105 int db4 = FALSE;
00106 int db5 = FALSE;
00107 
00108 char device[MAX_STRING_LEN] = "eth0";
00109 
00110 /**************************  Function prototypes  **************************/
00111 FILE                   *Fopen                   (char *name, char *mode);
00112 int                     main                    (int argc, char *argv[]);
00113 int                     GetNumberOption         (int *argNr, int argCount, char *argVect[], unsigned int *ret, char *option, int base);
00114 int                     GetStringOption         (int *argNr, int argCount, char *argVect[], char *ret, char *option);
00115 int                     GetRegisterOption       (int *argNr, int argCount, char *argVect[], unsigned int *ret, char *option, int base);
00116 struct boot_files_T*    allocate_boot_file      (struct boot_files_T *bf);
00117 struct packet_buf*      CreateNewBootPacket     (void);
00118 struct packet_buf*      allocate_packet         (struct packet_buf *p);
00119 void                    SigHandler              (int sig);
00120 void                    CreateBootLoader        (char *filename, unsigned size, unsigned addr);
00121 void                    FinishBootCmds          (void);
00122 void                    ParseArgs               (int argc, char *argv[]);
00123 void                    PrintHelp               (void);
00124 void                    CreateBootCmds          (void);
00125 void                    handle_labels           (void);
00126 void                    new_label               (struct label_t **label, udword addr, char *name);
00127 void                    printData               (unsigned char* buf, unsigned addr, unsigned size);
00128 
00129 /****************************************************************************
00130 *#
00131 *#  FUNCTION NAME: main
00132 *#
00133 *#  PARAMETERS: Command line arguments.
00134 *#
00135 *#---------------------------------------------------------------------------
00136 *#  HISTORY
00137 *#
00138 *#  DATE     NAME     CHANGES
00139 *#  ----     ----     -------
00140 *#  961022   ronny    Initial version
00141 *#
00142 *#***************************************************************************/
00143 
00144 int
00145 main(int argc, char *argv[])
00146 {
00147   ParseArgs(argc, argv);
00148 
00149   if (cmdsOnly) {               
00150     /* We make this a special case to avoid messing up other code. */
00151     CreateBootCmds();
00152     FinishBootCmds();
00153     SendToDevice(&boot_cmds_packet->data[SIZE_OF_HEADER],SIZE_OF_BOOT_CMDS);
00154     exit(EXIT_SUCCESS);
00155   }
00156 
00157   if (netBoot && !toFiles) {            
00158     /* Do not bother with this if we just want to write the packets to
00159        files. Means you do not have to be root to run --tofiles. */
00160     net_init();
00161   }
00162   else if (serBoot) {
00163     SetupSerial();    
00164   }
00165 
00166   {
00167     unsigned size = 0;
00168     unsigned    i = 0;
00169 
00170     do {
00171       if ((strcmp(INTERNAL2, boot_image_info[i].name) == 0)) {
00172         size = boot_image_info[i].len;
00173         break;
00174       }
00175       i++;
00176     } while(boot_image_info[i].name);
00177     
00178     if (!size) {
00179       printf("no boot size\n");
00180       exit(EXIT_FAILURE);
00181     }
00182     
00183     CreateBootLoader(boot_loader_file, size, 0x3800001e);
00184   }
00185 
00186   CreateBootLoader(INTERNAL2, 0, 0x38000800);
00187   
00188 
00189   CreateBootCmds();
00190   FinishBootCmds();
00191 
00192   printf("Starting boot...\n");
00193   if (doing_flash) {
00194     printf("We're doing a flash write, this may take up to a few minutes...\n");
00195   }
00196 
00197   if (toFiles) {
00198     udword seq = 0;
00199     struct packet_buf *p;
00200 
00201     while((p = create_packet(seq++))) {
00202       SendToDevice(p->data, p->size);
00203     }
00204 
00205     exit(EXIT_SUCCESS);
00206   }
00207 
00208   if (netBoot) {
00209     NetBoot();
00210   }
00211   else if (serBoot) {
00212     SerBoot();
00213   }
00214 
00215   printf("Done.\n");
00216   return EXIT_SUCCESS;
00217 } /* main  */
00218 
00219 /****************************************************************************
00220 *#
00221 *#  FUNCTION NAME: free_packet
00222 *#
00223 *#  PARAMETERS: struct to free
00224 *#
00225 *#  DESCRIPTION: Frees struct and data in struct.
00226 *#
00227 *#  RETURNS: Pointer to next struct.
00228 *#
00229 *#---------------------------------------------------------------------------
00230 *#  HISTORY
00231 *#
00232 *#  DATE         NAME     CHANGES
00233 *#  ----         ----     -------
00234 *#  2000 02 07   ronny    Initial version
00235 *#
00236 *#***************************************************************************/
00237 
00238 struct packet_buf* 
00239 free_packet(struct packet_buf *p) {
00240   struct packet_buf *next_p;
00241 
00242   next_p = p->next;
00243   free(p->data);
00244   free(p);
00245   return(next_p);
00246 
00247 }
00248 
00249 /****************************************************************************
00250 *#
00251 *#  FUNCTION NAME: create_packet
00252 *#
00253 *#  PARAMETERS: Sequence number.
00254 *#
00255 *#  DESCRIPTION: Return pointer to packet with specified sequence number. 
00256 *#
00257 *#---------------------------------------------------------------------------
00258 *#  HISTORY
00259 *#
00260 *#  DATE         NAME     CHANGES
00261 *#  ----         ----     -------
00262 *#  2000 06 28   ronny    Initial version
00263 *#
00264 *#***************************************************************************/
00265 
00266 struct packet_buf*
00267 create_packet(udword seq)
00268 {
00269   struct packet_buf *p = first_packet;
00270   /* Should check last first? */
00271   
00272   if (db4) printf("> create_packet seq %d\n", seq);
00273 
00274   while (p) {
00275     if (p->seq == seq) {
00276       return(p);
00277     }
00278     p = p->next;
00279   }
00280   
00281   return(CreateNewBootPacket());
00282 }
00283 
00284 /****************************************************************************
00285 *#
00286 *#  FUNCTION NAME: find_string
00287 *#
00288 *#  PARAMETERS: New string to search.
00289 *#
00290 *#  DESCRIPTION: Searches a number of strings for needle[], including strings 
00291 *#  overlapping between different calls.
00292 *#
00293 *#---------------------------------------------------------------------------
00294 *#  HISTORY
00295 *#
00296 *#  DATE     NAME     CHANGES
00297 *#  ----     ----     -------
00298 *#  020502   ronny    Initial version
00299 *#
00300 *#***************************************************************************/
00301 
00302 void
00303 find_string(char *str)
00304 {
00305   static int matched = 0;
00306   int hs[MAX_STRING_LEN];
00307   static int cur_hs = 0;
00308   static int hs_len = 0;
00309   static int last_hs = 0;
00310 
00311   static int cur_needle = 0;
00312 
00313   if (!needle[0]) {
00314     return;
00315   }
00316   //    printf("# adding >%s<\n", str);
00317   
00318   {
00319     int c = 0;
00320     int s = 0;
00321     
00322     while((c = str[s])) {
00323       
00324       //    printf("\n# cur_hs %d, hs_len %d\n", cur_hs, hs_len);
00325       {
00326         int i;
00327         
00328         for(i=0; i!= hs_len; i++) {
00329           //      printf("hs[%d] = %d(%c)\n", i, (int)hs[i], hs[i] < 32 ? 'X' : hs[i]);
00330         }
00331       }
00332       
00333       if (cur_hs == hs_len) {
00334         //      printf("adding char %d(%c) at hs[%d]\n", (int)c, c < 32 ? 'X' : c, hs_len);
00335         hs[hs_len] = c;
00336         hs_len++;
00337         s++;
00338       }
00339       
00340       //      printf("testing %d at cur_hs %d against %d at cur_needle  %d\n", 
00341       //             (int)hs[cur_hs], cur_hs, (int)needle[cur_needle], cur_needle);
00342       
00343       if (hs[cur_hs] == needle[cur_needle]) {
00344         if (cur_needle+1 == needle_len) { 
00345           int exitcode = EXIT_SUCCESS;
00346 
00347           //      printf("\nFound needle from --find option.\n");
00348           if (exitonfind) {
00349             int ret;
00350             //      printf("scanf (s=%d)'%s'\n", s, &str[s+1]);
00351             ret = sscanf(&str[s+1], "%i", &exitcode);
00352             //      printf("ret %d, '%s'\n", ret, &str[s+1]);
00353           }
00354           printf("Exiting with code %d\n", exitcode);
00355           exit(exitcode);
00356         }
00357         cur_needle++;
00358         cur_hs++;
00359       }
00360       else {
00361         //      printf("no match, shifting hs.\n");
00362         {
00363           int i;
00364           for(i=0; i!= hs_len-1; i++) {
00365             hs[i] = hs[i+1];
00366           }
00367         }
00368         hs_len--;
00369         cur_needle = 0;
00370         cur_hs = 0;
00371       }
00372     }
00373   }
00374 }
00375 
00376 /****************************************************************************
00377 *#
00378 *#  FUNCTION NAME: Fopen
00379 *#
00380 *#  PARAMETERS: Name and mode, both strings.
00381 *#
00382 *#  DESCRIPTION: Opens a file and returns its fd, or NULL.
00383 *#
00384 *#---------------------------------------------------------------------------
00385 *#  HISTORY
00386 *#
00387 *#  DATE     NAME     CHANGES
00388 *#  ----     ----     -------
00389 *#  961022   ronny    Initial version
00390 *#
00391 *#***************************************************************************/
00392 
00393 FILE *
00394 Fopen(char *name, char *mode)
00395 {
00396   FILE *fd;
00397 
00398   if (db2) printf(">>> Fopen '%s', mode '%s'\n", name, mode);
00399 
00400 #if defined(_WIN32)
00401   fd = _fsopen(name, mode, _SH_DENYNO);
00402 #else
00403   fd = fopen(name, mode);
00404 #endif
00405 
00406   if (fd == NULL) {
00407     printf("<<< Fopen failed on '%s', mode '%s'\n", name, mode);
00408     return ((FILE*) NULL);
00409   }
00410 
00411   if (strncmp(mode, "a", 1) == 0) {
00412     if (db3) printf("* Append mode, seeking to end.\n");
00413     fseek(fd, 0L, SEEK_SET);
00414   }
00415 
00416   if (db2) printf("<<< Fopen: '%s'\n", name);
00417 
00418   return(fd);
00419 }
00420 
00421 /****************************************************************************
00422 *#
00423 *#  FUNCTION NAME: ParseArgs
00424 *#
00425 *#  PARAMETERS: Standard command line args. 
00426 *#
00427 *#  DESCRIPTION: Parses command line arguments.
00428 *#
00429 *#---------------------------------------------------------------------------
00430 *#  HISTORY
00431 *#
00432 *#  DATE     NAME     CHANGES
00433 *#  ----     ----     -------
00434 *#  960909   ronny    Initial version
00435 *#***************************************************************************/
00436 
00437 void
00438 ParseArgs (int argc, char *argv[])
00439 {
00440   int  argi;
00441   int  i;
00442   int  printHelp = FALSE;
00443   char dbStr[MAX_STRING_LEN];              /* Debug option string. */
00444   int  number;
00445   int  argCount;
00446   char **argVect;
00447   struct stat st;
00448 
00449   argCount = argc;
00450   argVect = argv;
00451 
00452   for (argi = 1; argi < argCount; argi++) {
00453 
00454     if (strncmp(argVect[argi], "--quiet", 7) == 0) {
00455       quiet = TRUE;
00456     }
00457 
00458     else if (strncmp(argVect[argi], "--from", 6) == 0) {
00459       if (GetStringOption(&argi, argCount, argVect, host1, "--from") == 0) {
00460         printHelp = TRUE;
00461       }
00462       else {
00463         printf("Host: %s %s\n", host1, host2);
00464         if (sscanf(host1, "%x-%x-%x-%x-%x-%x", &i, &i, &i, &i, &i, &i) == 6) {
00465           printf("Ethernet address\n");
00466         }
00467       }
00468     }
00469 
00470     else if (strncmp(argVect[argi], "--device", 8) == 0) {
00471       if (GetStringOption(&argi, argCount, argVect, device, "--device") == 0) {
00472         printHelp = TRUE;
00473       }
00474     }
00475 
00476     else if (strncmp(argVect[argi], "--etraxfs", 9) == 0) {
00477       boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
00478       boot_cmds[boot_cmds_cnt++] = 0xb0014004; /* bif_core.rw_grp2_cfg */
00479       boot_cmds[boot_cmds_cnt++] = 0x000004c5; /* bwe,32,z=2,e=3,l=5 */
00480       boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
00481       boot_cmds[boot_cmds_cnt++] = 0xb0038000; /* pinmux.rw_pa */
00482       boot_cmds[boot_cmds_cnt++] = 0x000000f0; /* pa4,pa5,pa6,pa7 */
00483       boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
00484       boot_cmds[boot_cmds_cnt++] = 0xb001a008; /* gio.rw_pa_oe */
00485       boot_cmds[boot_cmds_cnt++] = 0x00000070; /* pa4,pa5,pa6 */
00486       boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
00487       boot_cmds[boot_cmds_cnt++] = 0xb0014008; /* bif_core.rw_grp3_cfg */
00488       boot_cmds[boot_cmds_cnt++] = 0x060006cf; /* gated_csp0=rd,
00489                                                   gated_csp1=wr, default waitstates */
00490     }
00491 
00492     else if (strncmp(argVect[argi], "--network", 9) == 0) {
00493       netBoot = TRUE;
00494       serBoot = FALSE;
00495     }
00496 
00497     else if (strncmp(argVect[argi], "--listenonly", 12) == 0) {
00498       listenOnly = TRUE;
00499     }
00500 
00501     else if (strncmp(argVect[argi], "--serial", 8) == 0) {
00502       serBoot = TRUE;
00503       netBoot = FALSE;
00504       strcpy(device, "/dev/ttyS0");
00505       strcpy(boot_loader_file, INTERNAL_SER);
00506 
00507     }
00508     
00509     else if (strncmp(argVect[argi], "--noleds", 8) == 0) {
00510       noleds = TRUE;
00511     }
00512     
00513     else if (strncmp(argVect[argi], "--images", 8) == 0) {
00514       int i = 0;
00515       
00516       printf("Internal images:\n");
00517       
00518       while(boot_image_info[i].name) {
00519         printf("'%s', %s, size %lu bytes.\n", 
00520                boot_image_info[i].name,
00521                boot_image_info[i].info,
00522                boot_image_info[i].len
00523                );
00524         i++;
00525       }
00526       exit(EXIT_SUCCESS);
00527       
00528     }
00529     
00530     else if (strncmp(argv[argi], "--baudrate", 10) == 0) {
00531       if (GetNumberOption (&argi, argCount, argVect, &set_baudrate, "--baudrate", 10) == 0) {
00532         printHelp = TRUE;
00533       }
00534     }
00535     
00536     else if (strncmp(argVect[argi], "--tofiles", 9) == 0) {
00537       toFiles = TRUE;
00538     }
00539     
00540     else if (strncmp(argVect[argi], "--cmdsonly", 10) == 0) {
00541       cmdsOnly = TRUE;
00542     }
00543     
00544     else if (strncmp(argVect[argi], "--to", 4) == 0) {
00545       if ((GetStringOption(&argi, argCount, argVect, host2, "--to") == 0)) {
00546         printHelp = TRUE;
00547       }
00548       else {
00549         printf("Host: %s %s\n", host1, host2);
00550         both_addresses = TRUE;
00551         if (sscanf(host2, "%x-%x-%x-%x-%x-%x", &i, &i, &i, &i, &i, &i) == 6) {
00552           printf("Ethernet address\n");
00553         }
00554       }
00555     }
00556 
00557     else if (strncmp(argVect[argi], "--printp", 8) == 0) {
00558       pPacket = 1;
00559     }
00560 
00561     else if (strncmp(argVect[argi], "--printascii", 11) == 0) {
00562       pPacket = 1;
00563       printPacketType = ASCII;
00564     }
00565 
00566     else if (strncmp(argVect[argi], "--printudec", 11) == 0) {
00567       pPacket = 1;
00568       printPacketType = UDEC;
00569     }
00570 
00571     else if (strncmp(argVect[argi], "--printhex", 10) == 0) {
00572       pPacket = 1;
00573       printPacketType = HEX;
00574     }
00575 
00576     else if (strncmp(argVect[argi], "--bpl", 5) == 0) {
00577       if (GetNumberOption(&argi, argCount, argVect, &p_packet_bpl, "--bpl", 10) == 0) {
00578         printHelp = TRUE;
00579       }
00580     }
00581 
00582     else if (strncmp(argVect[argi], "--promisc", 11) == 0) {
00583       promisc = 1;
00584     }
00585 
00586     else if (strncmp(argVect[argi], "--testcard", 10) == 0) {
00587     }
00588 
00589     else if (strncmp(argVect[argi], "--verify", 8) == 0) {
00590       boot_cmds[boot_cmds_cnt++] = MEM_VERIFY;
00591       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--verify", 16);
00592       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--verify", 16);
00593     }
00594 
00595     else if (strncmp(argVect[argi], "--setreg", 8) == 0) {
00596       boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
00597       if ((argVect[argi+1][0] >= 'A') && (argVect[argi+1][0] <= 'Z')) {
00598         GetRegisterOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--setreg", 16);
00599       }
00600       else {
00601         GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--setreg", 16);
00602       }
00603       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--setreg", 16);
00604     }
00605     
00606     else if (strncmp(argVect[argi], "--getreg", 8) == 0) {
00607       boot_cmds[boot_cmds_cnt++] = GET_REGISTER;
00608       if ((argVect[argi+1][0] >= 'A') && (argVect[argi+1][0] <= 'Z')) {
00609         GetRegisterOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--getreg", 16);
00610       }
00611       else {
00612         GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--getreg", 16);
00613       }
00614     }
00615 
00616     else if (strncmp(argVect[argi], "--pause", 7) == 0) {
00617       boot_cmds[boot_cmds_cnt++] = PAUSE_LOOP;
00618       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--pause", 16);
00619     }
00620 
00621     else if (strncmp(argVect[argi], "--memtest", 9) == 0) {
00622       boot_cmds[boot_cmds_cnt++] = MEM_TEST;
00623       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memtest", 16);
00624       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memtest", 16);
00625     }
00626 
00627     else if (strncmp(argVect[argi], "--loop", 6) == 0) {
00628       char str[MAX_STRING_LEN];
00629       boot_cmds[boot_cmds_cnt++] = LOOP;
00630       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--loop", 16);
00631       GetStringOption(&argi, argCount, argVect, str, argVect[argi]);
00632       new_label(&loop_label, boot_cmds_cnt+1, str);
00633       boot_cmds_cnt++;
00634     }
00635     
00636     else if (strncmp(argVect[argi], "--label", 7) == 0) {
00637       char str[MAX_STRING_LEN];
00638       GetStringOption(&argi, argCount, argVect, str, "--label");
00639       new_label(&label, boot_cmds_cnt, str);
00640     }
00641 
00642     else if (strncmp(argVect[argi], "--memdump", 9) == 0) {
00643       boot_cmds[boot_cmds_cnt++] = MEM_DUMP;
00644       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memdump", 16);
00645       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memdump", 16);
00646     }
00647 
00648     else if (strncmp(argVect[argi], "--restartfs", 11) == 0) {
00649       boot_cmds[boot_cmds_cnt++] = RESTART_FS;
00650     }
00651 
00652     else if (strncmp(argVect[argi], "--nanderase", 11) == 0) {
00653       boot_cmds[boot_cmds_cnt++] = NAND_FLASH_ERASE;
00654       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanderase", 16);
00655       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanderase", 16);
00656     }
00657 
00658     else if (strncmp(argVect[argi], "--nandmarkbad", 13) == 0) {
00659       boot_cmds[boot_cmds_cnt++] = NAND_FLASH_MARK_BAD;
00660       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nandmarkbad", 16);
00661       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nandmarkbad", 16);
00662     }
00663 
00664     else if (strncmp(argVect[argi], "--nandignorebad", 15) == 0) {
00665       boot_cmds[boot_cmds_cnt++] = NAND_FLASH_IGNORE_BAD;
00666     }
00667 
00668     else if (strncmp(argVect[argi], "--nanddumpoobbad", 16) == 0) {
00669       boot_cmds[boot_cmds_cnt++] = NAND_FLASH_OOB_DUMP_BAD;
00670       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanddumpoobbad", 16);
00671       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanddumpoobbad", 16);
00672     }
00673 
00674     else if (strncmp(argVect[argi], "--nanddumpoob", 13) == 0) {
00675       boot_cmds[boot_cmds_cnt++] = NAND_FLASH_OOB_DUMP;
00676       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanddumpoob", 16);
00677       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanddumpoob", 16);
00678     }
00679 
00680     else if (strncmp(argVect[argi], "--nanddump", 10) == 0) {
00681       boot_cmds[boot_cmds_cnt++] = NAND_FLASH_DUMP;
00682       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanddump", 16);
00683       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nanddump", 16);
00684     }
00685 
00686     else if (strncmp(argVect[argi], "--memclear", 10) == 0) {
00687       boot_cmds[boot_cmds_cnt++] = MEM_CLEAR;
00688       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memclear", 16);
00689       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memclear", 16);
00690     }
00691 
00692     else if (strncmp(argVect[argi], "--flash", 7) == 0) {
00693             boot_cmds[boot_cmds_cnt++] = FLASH;
00694             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--flash", 16);
00695             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--flash", 16);
00696             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--flash", 16);
00697             doing_flash = TRUE;
00698     }
00699 
00700     else if (strncmp(argVect[argi], "--nandflash", 11) == 0) {
00701             boot_cmds[boot_cmds_cnt++] = NAND_FLASH;
00702             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nandflash", 16);
00703             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nandflash", 16);
00704             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nandflash", 16);
00705             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--nandflash", 16);
00706             doing_flash = TRUE;
00707     }
00708 
00709 #if 0
00710     else if (strncmp(argVect[argi], "--stupidflash", 13) == 0) {
00711             boot_cmds[boot_cmds_cnt++] = STUPID_NAND_FLASH;
00712             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--stupidflash", 16);
00713             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--stupidflash", 16);
00714             GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--stupidflash", 16);
00715             doing_flash = TRUE;
00716     }
00717 #endif
00718 
00719     else if (strncmp(argVect[argi], "--jump", 6) == 0) {
00720       boot_cmds[boot_cmds_cnt++] = JUMP;
00721       GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--jump", 16);
00722     }
00723 
00724     else if (strncmp(argVect[argi], "--file", 6) == 0) {
00725       char str[MAX_STRING_LEN];
00726       boot_cmds[boot_cmds_cnt++] = PACKET_INFO;
00727       GetStringOption(&argi, argCount, argVect, 
00728                       str, "--file");   /* file name */
00729       GetNumberOption(&argi, argCount, argVect, 
00730                       &boot_cmds[boot_cmds_cnt++], str, 16); /* address */
00731       last_boot_file = allocate_boot_file(last_boot_file);
00732       first_boot_file = first_boot_file ? first_boot_file : last_boot_file;
00733       last_boot_file->fileName = malloc(strlen(str) + 1);
00734       strcpy(last_boot_file->fileName, str);
00735       last_boot_file->size_p = &boot_cmds[boot_cmds_cnt];
00736       last_boot_file->size_sent = 0;
00737       if (strncmp(str, "-", 1) != 0) {
00738         if (stat(last_boot_file->fileName, &st) == -1) {
00739           printf("Cannot get size of file '%s'. %s.\n", 
00740                  last_boot_file->fileName, strerror(errno));
00741           exit(EXIT_FAILURE);
00742         }
00743         if (db2) printf("* size is %d 0x%8.8x\n", 
00744                         (int)st.st_size, (unsigned int)st.st_size);
00745         last_boot_file->size = st.st_size;
00746         boot_cmds[boot_cmds_cnt++] = st.st_size;
00747       }
00748       else {
00749         GetNumberOption(&argi, argCount, argVect, 
00750                         &last_boot_file->size , str, 16); /* size */
00751         
00752         boot_cmds[boot_cmds_cnt++] = last_boot_file->size;
00753         if(db2)printf("* size is %d 0x%8.8x\n", last_boot_file->size, 
00754                last_boot_file->size);
00755         
00756       }
00757     }
00758 
00759     else if (strncmp(argVect[argi], "--bootfile", 10) == 0) {
00760       GetStringOption(&argi, argCount, argVect, 
00761                       boot_loader_file, "--bootfile");
00762     }
00763 
00764     else if (strncmp(argVect[argi], "-d", 2) == 0) {
00765       if (GetNumberOption (&argi, argCount, argVect, &number, "-d", 10) == 0) {
00766         printHelp = TRUE;
00767       }
00768       else {
00769         sprintf(dbStr, "%d", number);
00770         for (i = 0; i != (int) strlen(dbStr); i++) {
00771           switch (dbStr[i] - '0') {
00772           case 1:
00773             db1 = TRUE;
00774             break;
00775           case 2:
00776             db2 = TRUE;
00777             break;
00778           case 3:
00779             db3 = TRUE;
00780             break;
00781           case 4:
00782             db4 = TRUE;
00783             break;
00784           case 5:
00785             db5 = TRUE;
00786             break;
00787           default:
00788             printf("ERROR! Debug level %d is not defined.\n", dbStr[i] - '0');
00789             printHelp = TRUE;
00790             break;
00791           }
00792         }
00793       }
00794     }
00795     
00796     else if (strncmp(argVect[argi], "--find", 6) == 0) {
00797       GetStringOption(&argi, argCount, argVect, 
00798                       needle, "--find");
00799       /* convert control characters like /n to the real ascii valure */
00800       {
00801         int i;
00802         int j = 0;
00803         char c;
00804         int esc = 0;
00805         
00806         for (i=0; (c = needle[i]);i++,j++) {
00807           //      printf("c = %d, i %d, j %d\n", (int)c, i, j);  
00808           if (c == '\\') {
00809             //      printf("esc\n");
00810             esc = 1;
00811             continue;
00812           }
00813           else if (esc) {
00814             esc = 0;
00815             switch(c) {
00816             case 'r': {
00817               c = '\r';
00818               break;
00819             }
00820             case 'n': {
00821               c = '\n';
00822               break;
00823             }
00824             case '\\': {
00825               c = '\\';
00826               break;
00827             }
00828               
00829             default: {
00830               printf("Uknown escape sequence '\\%c'\n", c);
00831               exit(EXIT_FAILURE);
00832             }
00833             }
00834             j--;
00835           }
00836           //      printf("setting j %d to %d\n", j, (int)c);
00837           needle[j] = c;
00838         }
00839         needle_len = j;
00840       }
00841 
00842       for (i=0; needle[i];i++) {
00843         //printf("i = %d, c %d\n", i,(int)needle[i]);  
00844       }
00845 
00846     }
00847     
00848     else if (strncmp(argVect[argi], "--exitonfind", 12) == 0) {
00849       exitonfind = TRUE;
00850     }
00851     
00852     else {
00853       printf("ERROR! Don't understand option '%s'\n", argVect[argi]);
00854       printHelp = TRUE;
00855     }
00856 
00857   }
00858   
00859   if (printHelp == TRUE) {
00860     PrintHelp();
00861     exit(EXIT_FAILURE);
00862   }
00863 
00864   if (noleds) {
00865     strcpy(&boot_loader_file[strlen(boot_loader_file)], "_NOLEDS");
00866   }
00867 
00868   handle_labels();
00869 }
00870 
00871 /****************************************************************************
00872 *#
00873 *#  FUNCTION NAME: handle_labels
00874 *#
00875 *#  PARAMETERS: global loop_label, label
00876 *#
00877 *#  DESCRIPTION: Checks and matches labels from --loop and --label commands
00878 *#  and inserts the resolved addresses into boot commands.
00879 *#
00880 *#---------------------------------------------------------------------------
00881 *#  HISTORY
00882 *#
00883 *#  DATE     NAME     CHANGES
00884 *#  ----     ----     -------
00885 *#  20020204 ronny    Initial version
00886 *#
00887 *#***************************************************************************/
00888 
00889 void 
00890 handle_labels(void)
00891 {
00892   struct label_t *ll = loop_label;
00893   struct label_t *l  = label;
00894   struct label_t *last_l  = l;
00895 
00896 
00897   while(ll) {
00898     int match = 0;
00899 
00900     l = last_l;
00901     while(l) {
00902       match = 0;
00903 
00904       if (l->name && ll->name && (strcmp(l->name, ll->name) == 0)) {
00905         match = 1;
00906         boot_cmds[ll->addr] = IO_BUF_START+(l->addr*4);
00907         break;
00908       }
00909       l = l->prev;
00910     }
00911     if (!match) {
00912       printf("Error. No label '%s' defined as needed by --loop command.\n", ll->name);
00913       exit(EXIT_FAILURE);
00914     }
00915     ll = ll->prev;
00916   }
00917 }
00918 
00919 /****************************************************************************
00920 *#
00921 *#  FUNCTION NAME: new_label
00922 *#
00923 *#  PARAMETERS: 
00924 *#
00925 *#  DESCRIPTION: create a label for the --label option
00926 *#
00927 *#---------------------------------------------------------------------------
00928 *#  HISTORY
00929 *#
00930 *#  DATE     NAME     CHANGES
00931 *#  ----     ----     -------
00932 *#  20020201 ronny    Initial version
00933 *#
00934 *#***************************************************************************/
00935 
00936 void
00937 new_label(struct label_t **label, udword addr, char *name) 
00938 {
00939   struct label_t *new_p;
00940   
00941   new_p = malloc(sizeof(struct label_t));
00942   
00943   if (*label == NULL) {         /* first one? */
00944     *label = new_p;
00945     new_p->prev = NULL;
00946   }
00947   else {
00948     new_p->prev = *label;
00949   }
00950 
00951   *label = new_p;
00952   new_p->addr = boot_cmds_cnt;
00953   new_p->name = malloc(strlen(name));
00954   strcpy(new_p->name, name);
00955   
00956 }
00957 
00958 /****************************************************************************
00959 *#
00960 *#  FUNCTION NAME: GetStringOption
00961 *#
00962 *#  PARAMETERS: int *argNr      : Returns next argc here. 
00963 *#              int argCount    : Index of last argument.
00964 *#              char *argVect[] : argv.
00965 *#              char *ret       : Copy string here.
00966 *#              char *option    : Name of the option.
00967 *#
00968 *#  DESCRIPTION: Extracts a string option from argv, and updates argnr.
00969 *#  Returns TRUE/FALSE and string in *ret.
00970 *#
00971 *#---------------------------------------------------------------------------
00972 *#  HISTORY
00973 *#
00974 *#  DATE     NAME     CHANGES
00975 *#  ----     ----     -------
00976 *#  960930   ronny    Initial version
00977 *#  961203   ronny    Handles filenames with spaces within 'file name'.
00978 *#
00979 *#***************************************************************************/
00980 
00981 int
00982 GetStringOption(int *argNr, int argCount, char *argVect[], char *ret,
00983                 char *option)
00984 {
00985   int startChar = strlen(option);
00986 
00987   *ret = '\0';
00988 
00989   /* Are there any more chars after option? If not skip to next argv. */
00990   if (strlen(argVect[*argNr]) <= (unsigned int)startChar) {
00991     (*argNr)++;
00992     startChar = 0;
00993   }
00994 
00995   /* Any args left? */
00996   if (*argNr >= argCount) {
00997     printf("ERROR! The option '%s' needs a string argument.\n", option);
00998     PrintHelp();
00999     exit(EXIT_FAILURE);
01000   }
01001 
01002   /* avoid stack overflow hacks */
01003   if (strlen(&argVect[*argNr][startChar]) > MAX_STRING_LEN) {
01004     printf("Argument '%s' longer than maximum allowable %d characters.\n", 
01005            &argVect[*argNr][startChar], MAX_STRING_LEN);
01006     exit(EXIT_FAILURE);
01007   }
01008 
01009   strcpy(ret, &argVect[*argNr][startChar]);
01010   if (db4) printf("<<< GetStringOption '%s'\n", ret);
01011 
01012   return TRUE;
01013 }
01014 
01015 /****************************************************************************
01016 *#
01017 *#  FUNCTION NAME: GetNumberOption
01018 *#
01019 *#  PARAMETERS: 
01020 *#
01021 *#  DESCRIPTION:
01022 *#
01023 *#---------------------------------------------------------------------------
01024 *#  HISTORY
01025 *#
01026 *#  DATE     NAME     CHANGES
01027 *#  ----     ----     -------
01028 *#  960930   ronny    Initial version
01029 *#
01030 *#***************************************************************************/
01031 
01032 int
01033 GetNumberOption(int *argNr, int argCount, char *argVect[], unsigned int *ret,
01034                 char *option, int base)
01035 {
01036   int startChar;
01037   int add_io_base = 0;
01038 
01039   (*argNr)++;
01040   startChar = 0;
01041 
01042   if ((*argNr >= argCount)) {
01043     printf("ERROR! The option '%s' needs a number argument.\n", option);
01044     PrintHelp();
01045     exit(EXIT_FAILURE);
01046   }
01047 
01048   if (argVect[*argNr][startChar] == '+') {
01049     add_io_base = 1;
01050     startChar++;
01051   }
01052 
01053   if (base == 16) {
01054     sscanf(&argVect[*argNr][startChar], "%x", ret);
01055   } else {
01056     *ret = atoi(&argVect[*argNr][startChar]);
01057   }
01058 
01059   if (add_io_base) {
01060     *ret += IO_BUF_START;
01061     if (*ret < IO_BUF_START || *ret >= IO_BUF_END) {
01062       printf("ERROR! '%s' is outside the IO buffer (option '%s').\n",
01063              argVect[*argNr], option);
01064       exit(EXIT_FAILURE);
01065     }
01066   }
01067 
01068   if (db4) printf("<<< GetNumberOption %x\r\n", *ret);
01069 
01070   return TRUE;
01071 }
01072 
01073 /****************************************************************************
01074 *#
01075 *#  FUNCTION NAME: GetRegisterOption
01076 *#
01077 *#  PARAMETERS: 
01078 *#
01079 *#  DESCRIPTION:
01080 *#
01081 *#---------------------------------------------------------------------------
01082 *#  HISTORY
01083 *#
01084 *#  DATE     NAME     CHANGES
01085 *#  ----     ----     -------
01086 *#  960930   ronny    Initial version
01087 *#
01088 *#***************************************************************************/
01089 
01090 int
01091 GetRegisterOption(int *argNr, int argCount, char *argVect[], unsigned int *ret,
01092                 char *option, int base)
01093 {
01094   int startChar;
01095   
01096   (*argNr)++;
01097   startChar = 0;
01098 
01099   if ((*argNr >= argCount)) {
01100     printf("Error! The option '%s' needs a register name.\n", option);
01101     PrintHelp();
01102     exit(EXIT_FAILURE);
01103   }
01104   
01105   {
01106     int r = 0;
01107     
01108     while (reg_des[r].name) {
01109       if (strcmp(reg_des[r].name, argVect[*argNr]) == 0) {
01110         *ret = reg_des[r].addr;
01111         return TRUE;
01112         break;
01113       }
01114       r++;
01115     }
01116   }
01117 
01118   printf("Error! Didn't find a register name matching '%s'.\n", 
01119          argVect[*argNr]);
01120   
01121   exit(EXIT_FAILURE);
01122 
01123   return FALSE;
01124 }
01125 
01126 /****************************************************************************
01127 *#
01128 *#  FUNCTION NAME: PrintHelp
01129 *#
01130 *#  PARAMETERS: None.
01131 *#
01132 *#  DESCRIPTION: Prints help info.
01133 *#
01134 *#---------------------------------------------------------------------------
01135 *#  DATE     NAME     CHANGES
01136 *#  ----     ----     -------
01137 *#  960909   ronny    Initial version
01138 *#
01139 *#***************************************************************************/
01140 
01141 void
01142 PrintHelp(void)
01143 {
01144   
01145   printf("fsboot version %s.\n", version);
01146 
01147   printf(
01148          "\nfsboot [--device devicename] [--file [filename|-] addr [size]] \n"
01149          "       [--flash src dst size]\n"
01150          "       [--nandflash src dst max_dst size]\n"
01151          "       [--nanderase from to] [--nanddump from to] [--nanddumpoob from to]\n"
01152          "       [--nanddumpoobbad from to] [--nandmarkbad from to] [--nandignorebad]\n"
01153          "       [--memtest addr addr]\n"
01154          "       [--memclear addr addr] [--memdump addr addr]\n"
01155          "       [--setreg addr|regname val] [--getreg addr|regname] \n"
01156          "       [--verify addr val] [--loop addr label] [--label label]\n"
01157          "       [--5400] [--5600] [--testcard] [--devboard] \n"
01158          "       [--testcardlx] [--serial] [--baudrate baudrate]\n"
01159          "       [--bootfile file] [--jump addr]\n"
01160          "       [--tofiles] [--cmdsonly] [--images] [--noleds]\n"
01161          "       [-d debugflags] [--listenonly]\n");
01162   printf(
01163          "\n       The commands sent to the cbl, and which are parsed by the cbl,\n"
01164          "       are stored at 0x%8.8x-0x%8.8x.\n\n", IO_BUF_START, IO_BUF_END);
01165   printf("       See the man page for more details about fsboot.\n\n");
01166   
01167 }
01168 
01169 /****************************************************************************
01170 *#
01171 *#  FUNCTION NAME: CreateBootLoader
01172 *#
01173 *#  PARAMETERS: 
01174 *#
01175 *#  DESCRIPTION: Creates boot packets from boot file or internal loader.
01176 *#
01177 *#---------------------------------------------------------------------------
01178 *#  DATE     NAME     CHANGES
01179 *#  ----     ----     -------
01180 *#  960909   ronny    Initial version
01181 *#***************************************************************************/
01182 
01183 void
01184 CreateBootLoader(char *filename, unsigned add_size, unsigned addr)
01185 {
01186   struct stat st;
01187   char *buf = NULL;
01188   //  int size_pos = 0x18;
01189   //  int addr_pos = 0x28;
01190   struct packet_header_T *ph;
01191   int packet_size;
01192   int header_size = 0;
01193   int buf_cnt = 0;
01194   int i;
01195   udword sum = 0;
01196   unsigned extra_pad = 0;
01197 
01198   if (create_boot_loader) {
01199     int image_nbr = 0;
01200     int found = 0;
01201     const struct boot_image_info_type *info;
01202 
01203     if (db4) printf("> CreateBootLoader\n");
01204 
01205     info = &boot_image_info[image_nbr];
01206 
01207     /* Use internal boot loader? */
01208     while (!found && info->name != NULL) {
01209       if (strcmp(filename, info->name) == 0) {
01210         st.st_size = info->len;
01211         buf = (char*) malloc(st.st_size);
01212         memcpy(buf, info->ptr, st.st_size); /* unnecessary? */
01213         found = TRUE;
01214         printf("Using internal boot loader: %s - %s.\n",
01215                info->name, info->info);
01216       }
01217       else {
01218         image_nbr++;
01219         info = &boot_image_info[image_nbr];
01220       }
01221     }
01222 
01223     /* No internal? Load it from file instead. */
01224     if (!found) {               
01225       FILE *fd;
01226       
01227       /* We didn't find an internal match, load the boot file from disk. */
01228       if ((fd = Fopen(filename, "r")) == NULL) {
01229         printf("Cannot open bootloader '%s'. %s.\n",
01230                filename, strerror(errno));
01231         exit(EXIT_FAILURE);
01232       }
01233 
01234       if (fstat(fileno(fd), &st) == -1) {
01235         printf("Cannot get filestatus of bootloader '%s'. %s.\n",
01236                filename, strerror(errno));
01237         exit(EXIT_FAILURE);
01238       }
01239 
01240       buf = (char*) malloc(st.st_size);
01241       //      printf("CreateBootLoader: buf = (char*) malloc(st.st_size); 2\n");
01242       if (read(fileno(fd), buf, st.st_size) != st.st_size) {
01243         printf("Read fewer bytes than there should be in %s.\n",
01244                filename);
01245         exit(EXIT_FAILURE);
01246       }
01247 
01248       fclose(fd);
01249     }
01250     
01251     /* Alright, got loader in buf[] and size in st. */
01252     if (netBoot) {
01253       packet_size = DATA_SIZE;
01254     }
01255     else {
01256       packet_size = st.st_size;
01257     }
01258 
01259     for (i = 0; i != st.st_size; i++) {
01260       sum += ((byte*)buf)[i];
01261     }
01262     if (db1) printf("Checksum 0x%x, bytes %d(0x%x)\n", sum, i, i);
01263 
01264     printData(buf, addr, st.st_size);
01265 
01266     /* Now create list of packets. */
01267     while (buf_cnt <= st.st_size) {
01268 
01269       header_size = seq_nr == 0 ? 
01270         SIZE_OF_FIRST_HEADER : sizeof(struct packet_header_T);
01271 
01272       if (netBoot) {
01273         unsigned bytes_left = st.st_size - buf_cnt;
01274         /* size of this packet */
01275         packet_size = (bytes_left < DATA_SIZE ? bytes_left : DATA_SIZE) + header_size;
01276         if (packet_size < 60) { /* pad to 60 (excluding crc) */
01277           extra_pad   = 60-packet_size;
01278           packet_size += extra_pad; 
01279           if (db2) {
01280             printf("extra pad: %d\n", extra_pad);
01281           }
01282         }
01283       }
01284       else {
01285         packet_size = st.st_size;
01286         header_size = 0;
01287       }
01288       
01289       if (db4) printf("seq_nr %d, header_size %d, packet_size %d\n", 
01290                       seq_nr, header_size, packet_size);
01291       
01292       last_packet = allocate_packet(last_packet);
01293 
01294       first_packet = first_packet ? first_packet : last_packet;
01295 
01296       last_packet->size      = packet_size;
01297       last_packet->data      = (char*)malloc(packet_size);
01298       last_packet->seq       = seq_nr;
01299       last_packet->baud_rate = 115200;
01300 
01301       last_packet->boot_file = allocate_boot_file(NULL);
01302       last_packet->boot_file->fileName = filename;
01303 
01304       //      printf("last_packet->size %8.8x\n", last_packet->size);
01305       //      printf("last_packet->data %8.8x\n",last_packet->data);
01306 
01307       if (netBoot) {
01308         ph = (struct packet_header_T*) last_packet->data;
01309         memcpy(ph->dest, axis_000200, 6);
01310         memcpy(ph->src,  eth_addr_local,     6);
01311         ph->length = htons(packet_size);
01312         ph->snap1  = htonl(SNAP1);
01313         ph->snap2  = htonl(SNAP2);
01314         ph->tag    = htonl(SERVER_TAG);
01315         ph->seq    = htonl(seq_nr);
01316         if (seq_nr != 0) {
01317           ph->type   = htonl(BOOT_PACKET);
01318           ph->id     = htonl(0);
01319         }
01320       }
01321       
01322       memcpy(&last_packet->data[header_size], &buf[buf_cnt], 
01323              packet_size - header_size);
01324       if (db3 || db5) DecodeSvintoBoot(last_packet->data);
01325 
01326       if (netBoot) {
01327         buf_cnt += DATA_SIZE;
01328       } 
01329       else {
01330         buf_cnt += packet_size +1;
01331       }
01332 
01333       seq_nr++;
01334     }
01335   }
01336   
01337   nrof_net_packets = seq_nr+1;
01338 
01339   /* Hack binary, insert size of level2 loader. */
01340   if (add_size) { 
01341 #define SIZE_PATTERN 0x12345678
01342 #define SIZE_POS (SIZE_OF_FIRST_HEADER + (netBoot ? 0x04 : 0x04))
01343 
01344     printData(first_packet->data, 0, SIZE_POS+16);
01345     
01346     if (*(udword*)&first_packet->data[SIZE_POS] != SIZE_PATTERN) {
01347       printf("Bootloader corrupt. Should contain tag 0x%8.8x at 0x%x, but contains %x\n", 
01348              SIZE_PATTERN, SIZE_POS, *(udword*)&buf[SIZE_POS]);
01349       exit(EXIT_FAILURE);
01350     }
01351     
01352     /* How much data to load except data in first packet. */
01353 
01354     add_size += extra_pad;      /* add pad from last packet */
01355 
01356     *(udword*)(&first_packet->data[SIZE_POS]) = add_size; 
01357     
01358     if (db3) printf("Inserting boot size 0x%x(%d) at 0x%x.\n", 
01359                     (unsigned int) *(udword*)(&first_packet->data[SIZE_POS]), 
01360                     (unsigned int) *(udword*)(&first_packet->data[SIZE_POS]), 
01361                     (unsigned int)&first_packet->data[SIZE_POS]);
01362   }
01363   
01364   if (db4) printf("< CreateBootLoader\n");
01365 }
01366 
01367 /****************************************************************************
01368 *#
01369 *#  FUNCTION NAME: allocate_packet
01370 *#
01371 *#  PARAMETERS: None.
01372 *#
01373 *#  DESCRIPTION: 
01374 *#
01375 *#---------------------------------------------------------------------------
01376 *#  DATE     NAME     CHANGES
01377 *#  ----     ----     -------
01378 *#  960909   ronny    Initial version
01379 *#***************************************************************************/
01380 
01381 struct packet_buf*
01382 allocate_packet(struct packet_buf *p)
01383 {
01384   
01385   if (db4) printf("> allocate_packet\n");
01386 
01387   if (p) {
01388     p->next = (struct packet_buf*) malloc(sizeof(struct packet_buf));
01389     p       = p->next;
01390   }
01391   else {
01392     p = (struct packet_buf*) malloc(sizeof(struct packet_buf));
01393   }
01394   p->next = NULL;
01395   
01396   return(p);
01397 }
01398 
01399 /****************************************************************************
01400 *#
01401 *#  FUNCTION NAME: allocate_boot_file
01402 *#
01403 *#  PARAMETERS: None.
01404 *#
01405 *#  DESCRIPTION: 
01406 *#
01407 *#---------------------------------------------------------------------------
01408 *#  DATE     NAME     CHANGES
01409 *#  ----     ----     -------
01410 *#  960909   ronny    Initial version
01411 *#***************************************************************************/
01412 
01413 struct boot_files_T*
01414 allocate_boot_file(struct boot_files_T *bf)
01415 {
01416 
01417   if (bf) {
01418     bf->next = (struct boot_files_T*) malloc(sizeof(struct boot_files_T));
01419     bf       = bf->next;
01420   }
01421   else {
01422     bf = (struct boot_files_T*) malloc(sizeof(struct boot_files_T));
01423   }
01424   bf->next = NULL;
01425   
01426   return(bf);
01427 }
01428 
01429 /****************************************************************************
01430 *#
01431 *#  FUNCTION NAME: CreateBootCmds
01432 *#
01433 *#  PARAMETERS: None.
01434 *#
01435 *#  DESCRIPTION: Creates a boot packet from the boot commands. The data is 
01436 *#  filled in later by FinishBootCmds().
01437 *#
01438 *#---------------------------------------------------------------------------
01439 *#  DATE     NAME     CHANGES
01440 *#  ----     ----     -------
01441 *#  980818   ronny    Initial version
01442 *#***************************************************************************/
01443 
01444 void
01445 CreateBootCmds(void)
01446 {
01447   struct packet_header_T *ph;
01448 
01449   if (db4) printf("***> CreateBootCmds\n");
01450 
01451   last_packet = allocate_packet(last_packet);
01452 
01453   boot_cmds_packet = last_packet;
01454   
01455   last_packet->boot_file = allocate_boot_file(NULL);
01456   last_packet->boot_file->fileName =  BOOT_CMDS_FILE;
01457   last_packet->baud_rate =  115200;
01458   
01459   last_packet->size = netBoot ? SIZE_OF_BOOT_CMDS + sizeof(struct packet_header_T) 
01460     : SIZE_OF_BOOT_CMDS;
01461   if(db4) printf("Size of data part excluding CRC and header: %d\nTotal size of packet excluding CRC: %d\n", 
01462            SIZE_OF_BOOT_CMDS, last_packet->size);
01463   last_packet->data = (char *) malloc(last_packet->size);
01464   last_packet->seq = seq_nr;
01465   
01466   if (netBoot) {
01467     /* Create packet header. */
01468     ph = (struct packet_header_T *) last_packet->data;
01469     memcpy(ph->dest, axis_000200, 6);
01470     memcpy(ph->src, eth_addr_local, 6);
01471     ph->length = htons(last_packet->size);
01472     ph->snap1 = htonl(SNAP1);
01473     ph->snap2 = htonl(SNAP2);
01474     ph->tag = htonl(SERVER_TAG);
01475     ph->seq = htonl(seq_nr);
01476     if (db1) {
01477       printf("Boot commands in packet seq_nr: %d (0x%x).\n", seq_nr, seq_nr);
01478     }
01479     seq_nr++;
01480     ph->type = htonl(BOOT_CMDS);
01481     ph->id = htonl(0);
01482   }
01483   
01484   if (db3) DecodeSvintoBoot(last_packet->data);
01485   if (db4) printf("<*** CreateBootCmds\n");
01486 
01487 }
01488 
01489 /****************************************************************************
01490 *#
01491 *#  FUNCTION NAME: FinishBootCmds
01492 *#
01493 *#  PARAMETERS: None.
01494 *#
01495 *#  DESCRIPTION: Copies the boot commands into the correct packet and changes
01496 *#  the dwords to network order.
01497 *#
01498 *#---------------------------------------------------------------------------
01499 *#  DATE     NAME     CHANGES
01500 *#  ----     ----     -------
01501 *#  960909   ronny    Initial version
01502 *#***************************************************************************/
01503 
01504 void
01505 FinishBootCmds(void)
01506 {
01507   int i;
01508   unsigned int offset = 0;
01509 
01510   /* fill in number of boot commands(dwords) last in packet */
01511   boot_cmds[NR_BOOT_CMDS-1] = htonl(boot_cmds_cnt);
01512 
01513   for (i = 0; i != boot_cmds_cnt; i++) {
01514     boot_cmds[i] = htonl(boot_cmds[i]);
01515     if (db3) printf("%8.8x\n", boot_cmds[i]);
01516   }
01517 
01518   /* Copy boot commands into packet. */
01519   if (netBoot) {
01520     offset = sizeof(struct packet_header_T);
01521   }
01522   
01523   memcpy(&boot_cmds_packet->data[offset], boot_cmds, SIZE_OF_BOOT_CMDS);
01524 
01525 }
01526 
01527 /****************************************************************************
01528 *#
01529 *#  FUNCTION NAME: CreateNewBootPacket
01530 *#
01531 *#  PARAMETERS: None.
01532 *#
01533 *#  DESCRIPTION: Creates next packet for the files specified by '--file'.
01534 *#
01535 *#  RETURNS: Next packet, or NULL.
01536 *#
01537 *#---------------------------------------------------------------------------
01538 *#  DATE     NAME     CHANGES
01539 *#  ----     ----     -------
01540 *#  960909   ronny    Initial version
01541 *#***************************************************************************/
01542 
01543 struct packet_buf*
01544 CreateNewBootPacket(void)
01545 {
01546   static char buf[DATA_SIZE];
01547   struct packet_header_T *ph;
01548   int packet_size;
01549   int header_size;
01550   int i;
01551   udword sum;
01552   int size = 0;
01553   int padding = 0;
01554   
01555   static struct boot_files_T *bf = NULL;
01556 
01557   if (db3) printf("> CreateNewBootPacket\n");
01558   
01559   bf = bf ? bf : first_boot_file;
01560   
01561   while (bf) {
01562     if (!bf->fd) {
01563       if (strcmp(bf->fileName, "-") == 0) {
01564         bf->fd = stdin;
01565       }
01566       else {
01567         bf->fd = fopen(bf->fileName, "r");
01568       }
01569       
01570       if (bf->fd == NULL) {
01571         printf("Cannot open boot file %s. Exiting\n", bf->fileName);
01572         exit(EXIT_FAILURE);
01573       }
01574       if (db3) printf("Opening boot file %s\n", bf->fileName);
01575     }
01576   
01577     if (!padding) {
01578       unsigned bytes_to_read = bf->size - bf->size_sent;
01579       bytes_to_read = bytes_to_read < DATA_SIZE ? bytes_to_read : DATA_SIZE;
01580       if (db3) printf("Reading %d(0x%x)\n", bytes_to_read, bytes_to_read);
01581 
01582       size = fread(buf, 1, bytes_to_read, bf->fd);
01583       if (db3) printf("Read %d(0x%x)\n", size, size);
01584       if (size == 0) {
01585         if (db3) printf("Nothing more to read. Read: %d/%d\n", 
01586                         bf->size_sent, bf->size);
01587         padding = 1;
01588       }
01589     }
01590 
01591     if (padding) {
01592       if (bf->size_sent < bf->size) {
01593         if (db3) printf("padding...\n");
01594         size = (bf->size - bf->size_sent > DATA_SIZE) ? 
01595           DATA_SIZE : bf->size - bf->size_sent;
01596         memset(buf, 0, size);
01597       }
01598       else {
01599         if (db3) printf("All written\n");
01600         padding = 0;
01601         size = 0;
01602       }
01603     }
01604     
01605     if (size != 0) {
01606       if (db3) printf("size: %d %d/%d\n", size, bf->size_sent, bf->size);
01607       bf->size_sent += size;
01608       last_packet = allocate_packet(last_packet);
01609       
01610       /* Calculate checksum. */
01611       sum = 0;
01612       for (i = 0; i != size; i++) {
01613         sum += ((byte*)buf)[i];
01614       }
01615       if (db2) printf("Checksum 0x%x, bytes %d(0x%x)\n", sum, i, i);
01616      
01617       /* Figure out size of packet. */
01618       if (netBoot) {
01619         header_size = seq_nr == 0 ? 
01620           SIZE_OF_FIRST_HEADER : sizeof(struct packet_header_T);
01621         
01622         packet_size = ((size) < DATA_SIZE ? size : DATA_SIZE) + header_size;
01623       }
01624       else {
01625         header_size = 0;
01626         packet_size = size;
01627       }
01628 
01629       if (netBoot) {
01630         /* Is packet smaller than 64 bytes? 4 bytes are from the CRC
01631            added by lower layers, so don't count them here. */
01632         if (packet_size < 60) { 
01633           printf(
01634                  "Last packet from file '%s', is smaller than 64 bytes. \n"
01635                  "This is not allowed in the Ethernet standard. Will pad with %d "
01636                  "bytes.\n", bf->fileName, 60-packet_size);
01637           
01638           *(bf->size_p) += 60-packet_size;
01639           packet_size = 60;
01640         }
01641       }
01642     
01643       last_packet->size = packet_size;
01644       last_packet->data = (char*)malloc(packet_size);
01645       last_packet->boot_file = bf;
01646       last_packet->baud_rate = set_baudrate;
01647 
01648       /*      printf("size %8.8x\n", last_packet->size);*/
01649       /*      printf("data %8.8x\n",last_packet->data);*/
01650 
01651       if (netBoot) {
01652         /* Initialize ethernet header. */
01653         ph = (struct packet_header_T*) last_packet->data;
01654         memcpy(ph->dest, axis_000200, 6);
01655         memcpy(ph->src,  eth_addr_local,     6);
01656         /*      printf("packet_size %d\n", packet_size);*/
01657         ph->length = htons(packet_size);
01658         ph->snap1  = htonl(SNAP1);
01659         ph->snap2  = htonl(SNAP2);
01660         ph->tag    = htonl(SERVER_TAG);
01661         ph->seq    = htonl(seq_nr);
01662         last_packet->seq = seq_nr;
01663         if (seq_nr != 0) {
01664           ph->type   = htonl(FILE_PACKET);
01665           ph->id     = htonl(0); /* id doesn't matter, we send to a unicast address */
01666         }
01667       }
01668 
01669       /* Copy data in place. */
01670       memcpy(&last_packet->data[header_size], buf, packet_size - header_size);
01671       if (db2) DecodeSvintoBoot(last_packet->data);
01672       /*      PrintPacket(last_packet->data, last_packet->size, HEX);*/
01673       seq_nr++;
01674     
01675       if (db3) printf("< CreateNewBootPacket\n");
01676       return(last_packet);
01677     }  
01678     else 
01679     {                   /* Nothing read from fd. */
01680       if (bf->fd != stdin) {
01681         fclose(bf->fd);
01682       }
01683       bf = bf->next;
01684     }
01685   }
01686   
01687   if (db3) printf("< CreateNewBootPacket\n");
01688   return(NULL);
01689 }
01690 
01691 void 
01692 printData(unsigned char* buf, unsigned addr, unsigned size)
01693 {
01694 
01695   /* print data */
01696   if (db4) {                    
01697     int i;
01698     
01699     for(i=0; i<size; i+=8) {
01700       int j;
01701       
01702       printf("0x%8.8x[%4.4x]: ", addr+i, i);
01703         for(j=0; i+j<size && j<8; j++) {
01704           printf("%2.2x ", (unsigned char) buf[i+j]);
01705         }
01706         printf("\n");
01707     }
01708   }
01709 }
01710   
01711 /****************** END OF FILE common.c **********************************/

Generated on Fri Nov 28 00:06:25 2008 for elphel by  doxygen 1.5.1