home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / GDB / GDB-4.13 / GDB-4 / gdb-4.13 / gdb / sparclite / aload.c next >
Encoding:
C/C++ Source or Header  |  1994-05-06  |  4.7 KB  |  207 lines

  1. /* Program to load an image into the SPARClite monitor board
  2.    Copyright 1993 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Call with:
  19.  
  20.    aload PROG TTY
  21.  
  22. ie: aload hello /dev/ttya
  23.  
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <fcntl.h>
  28. #include <termios.h>
  29. #include <unistd.h>
  30. #define min(A, B) (((A) < (B)) ? (A) : (B))
  31.  
  32. #include <sys/types.h>
  33. #include <bfd.h>
  34.  
  35. /* Where the code goes by default. */
  36.  
  37. #ifndef LOAD_ADDRESS
  38. #define LOAD_ADDRESS 0x40000000
  39. #endif
  40.  
  41. extern void *malloc();
  42.  
  43. static void
  44. sys_error(msg)
  45.      char *msg;
  46. {
  47.   perror(msg);
  48.   exit(1);
  49. }
  50.  
  51. static void
  52. error(msg)
  53.      char *msg;
  54. {
  55.   fputs(msg, stdout);
  56.   fputc('\n', stdout);
  57.   exit(1);
  58. }
  59.  
  60. static FILE *ttyf;
  61.  
  62. static void
  63. sendex(outtxt, outlen, intxt, inlen, id)
  64.      unsigned char *outtxt;
  65.      int outlen;
  66.      unsigned char *intxt;
  67.      int inlen;
  68.      char *id;
  69. {
  70.   char buf[100];
  71.   int cc;
  72.  
  73.   if (outlen > 0)
  74.     {
  75.       cc = write(fileno(ttyf), outtxt, outlen);
  76.       if (cc != outlen)
  77.     sys_error("Write %s failed", id);
  78.     }
  79.  
  80.   if (inlen > 0)
  81.     {
  82.       cc = read(fileno(ttyf), buf, inlen);    /* Get reply */
  83.       if (cc != inlen)
  84.     sys_error("Read %s reply failed", id);
  85.       if (bcmp(buf, intxt, inlen) != 0)
  86.     error("Bad reply to %s", id);
  87.     }
  88. }
  89.  
  90. main(argc, argv)
  91.      int argc;
  92.      char **argv;
  93. {
  94.   struct termios termios;
  95.   int cc, progsize, i;
  96.   unsigned char buf[10];
  97.   asection *section;
  98.   bfd *pbfd;
  99.   unsigned long entry;
  100.  
  101.   pbfd = bfd_openr(argv[1], 0);
  102.  
  103.   if (!pbfd)
  104.     sys_error("Open of PROG failed");
  105.  
  106. /* setup the tty.  Must be raw, no flow control, 9600 baud */
  107.  
  108.   ttyf = fopen(argv[2], "r+");
  109.   if (!ttyf)
  110.     sys_error("Open of TTY failed");
  111.   setbuf(ttyf, NULL);        /* Strictly unbuffered */
  112.  
  113.   if (tcgetattr(fileno(ttyf), &termios))
  114.     sys_error("tcgetattr failed");
  115.  
  116.   termios.c_iflag = 0;
  117.   termios.c_oflag = 0;
  118.   termios.c_cflag = CS8 | CREAD | CLOCAL;
  119.   termios.c_lflag = 0;
  120.   termios.c_cc[VMIN] = 1;
  121.   termios.c_cc[VTIME] = 0;
  122.  
  123.   if (cfsetospeed(&termios, B9600)
  124.       || cfsetispeed(&termios, B9600))
  125.     sys_error("cfset{i|o}speed failed");
  126.  
  127.   if (tcsetattr(fileno(ttyf), TCSANOW, &termios))
  128.     sys_error("tcsetattr failed");
  129.  
  130.   sendex("", 1, "\xaa", 1, "alive?");
  131.   sendex("\x55", 1, "\x55", 1, "alive");
  132.   printf("[SPARClite appears to be alive]\n");
  133.  
  134.   if (!bfd_check_format (pbfd, bfd_object)) 
  135.     error ("It doesn't seem to be an object file");
  136.  
  137.   for (section = pbfd->sections; section; section = section->next) 
  138.     {
  139.       if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
  140.     {
  141.       bfd_vma section_address;
  142.       unsigned long section_size;
  143.       const char *section_name;
  144.  
  145.       section_name = bfd_get_section_name (pbfd, section);
  146.  
  147.       section_address = bfd_get_section_vma (pbfd, section);
  148.       /* Adjust sections from a.out files, since they don't
  149.          carry their addresses with.  */
  150.       if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
  151.         section_address += LOAD_ADDRESS;
  152.       section_size = bfd_section_size (pbfd, section);
  153.  
  154.       printf("[Loading section %s at %x (%d bytes)]\n",
  155.          section_name,
  156.          section_address,
  157.          section_size);
  158.  
  159.       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
  160.         {
  161.           file_ptr fptr;
  162.  
  163.           fptr = 0;
  164.  
  165.           while (section_size > 0)
  166.         {
  167.           char buffer[1024];
  168.           int count, i;
  169.           unsigned char checksum;
  170.           static char inds[] = "|/-\\";
  171.           static int k = 0;
  172.  
  173.           count = min (section_size, 1024);
  174.  
  175.           bfd_get_section_contents (pbfd, section, buffer, fptr,
  176.                         count);
  177.  
  178.           checksum = 0;
  179.           for (i=0; i < count; i++)
  180.             checksum += buffer[i];
  181.  
  182.           printf("\r%c", inds[k++ % 4]);
  183.           fflush(stdout);
  184.  
  185.           sendex("\001", 1, "\x5a", 1, "load command");
  186.           sendex(§ion_address, 4, NULL, 0, "load address");
  187.           sendex(&count, 4, NULL, 0, "program size");
  188.           sendex(buffer, count, &checksum, 1, "program");
  189.  
  190.           section_address += count;
  191.           fptr += count;
  192.           section_size -= count;
  193.         }
  194.         }
  195.       else            /* BSS */
  196.         printf ("Not loading BSS \n");
  197.     }
  198.     }
  199.  
  200.   entry = bfd_get_start_address (pbfd);
  201.   
  202.   printf("[Starting %s at 0x%x]\n", argv[1], entry);
  203.  
  204.   sendex("\003", 1, NULL, 0, "exec command");
  205.   sendex(&entry, 4, "\x55", 1, "program start");
  206. }
  207.