📄 eload.c
字号:
/* Program to load an image into the SPARClite monitor board via Ethernet Copyright 1993 Free Software Foundation, Inc.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* Call with: eload PROG HOSTNAME(HOSTNAME is the name (or IP address) of your eval board)ie: eload hello sparky*/#include <stdio.h>#include "ansidecl.h"#ifdef ANSI_PROTOTYPES#include <stdarg.h>#else#include <varargs.h>#endif#include "libiberty.h"#include "bfd.h"#include <errno.h>#include <fcntl.h>#include <termios.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <sys/socket.h>#include <netinet/in.h>#include <fcntl.h>#include <sys/time.h>#define min(A, B) (((A) < (B)) ? (A) : (B))/* Where the code goes by default. */#ifndef LOAD_ADDRESS#define LOAD_ADDRESS 0x40000000#endifstatic voidusage(){ fprintf (stderr, "usage: eload executable-file network-name\n"); exit (1);}static void#ifdef ANSI_PROTOTYPESsys_error (char *msg, ...)#elsesys_error (va_alist) va_dcl#endif{ int e = errno; va_list args;#ifdef ANSI_PROTOTYPES va_start (args, msg);#else va_start (args);#endif#ifdef ANSI_PROTOTYPES vfprintf (stderr, msg, args);#else { char *msg1; msg1 = va_arg (args, char *); vfprintf (stderr, msg1, args); }#endif va_end (args); fprintf (stderr, ": %s\n", strerror(e)); exit (1);}static void#ifdef ANSI_PROTOTYPESerror (char *msg, ...)#elseerror (va_alist) va_dcl#endif{ va_list args; #ifdef ANSI_PROTOTYPES va_start (args, msg);#else va_start (args);#endif#ifdef ANSI_PROTOTYPES vfprintf (stderr, msg, args);#else { char *msg1; msg1 = va_arg (args, char *); vfprintf (stderr, msg1, args); }#endif va_end (args); fputc ('\n', stderr); exit (1);}int netfd;static intrecv_buf (fd, buf, len, timeout) int fd, len; unsigned char *buf; int timeout;{ int cc; fd_set readfds; FD_ZERO (&readfds); FD_SET (fd, &readfds); if (timeout >= 0) { struct timeval timebuf; timebuf.tv_sec = timeout; timebuf.tv_usec = 0; cc = select (fd + 1, &readfds, 0, 0, &timebuf); } else cc = select (fd + 1, &readfds, 0, 0, 0); if (cc == 0) return 0; if (cc != 1) sys_error ("recv_buf: Bad return value from select:"); cc = recv (fd, buf, len, 0); if (cc < 0) sys_error ("Got an error from recv: "); return cc;}static voidsend_buf (fd, buf, len) int fd, len; unsigned char *buf;{ int cc; cc = send (fd, buf, len, 0); if (cc == len) return; if (cc < 0) sys_error ("Got an error from send: "); printf ("Short count in send: tried %d, sent %d\n", len, cc);}static unsigned shortcalc_checksum (buffer, count) unsigned char *buffer; int count;{ unsigned short checksum; unsigned short *s; s = (unsigned short *)buffer; checksum = 0; for (; count > 0; count -= 2) checksum += *s++; if (count != 0) checksum += (*s & 0xff00); return checksum;}static voidsend_data (buffer, fd, addr, count) unsigned char *buffer; int fd; unsigned long addr; int count;{ int cc, i; static int pkt_num = 0; unsigned char snd_buf[2000]; unsigned short checksum; static unsigned long old_addr = -1; while (1) { if (addr != old_addr) { snd_buf[0] = 0x1; /* Load command */ snd_buf[1] = 0x1; /* Loading address */ snd_buf[2] = addr >> 24; snd_buf[3] = addr >> 16; snd_buf[4] = addr >> 8; snd_buf[5] = addr; checksum = 0; for (i = 0; i < 6; i++) checksum += snd_buf[i]; checksum &= 0xff; send_buf (fd, snd_buf, 6); cc = recv_buf (fd, snd_buf, sizeof snd_buf, -1); if (cc < 1) { fprintf (stderr, "Got back short checksum for load addr\n"); exit (1); } if (checksum != snd_buf[0]) { fprintf (stderr, "Got back bad checksum for load addr\n"); exit (1); } pkt_num = 0; /* Load addr resets packet seq # */ old_addr = addr; } memcpy (snd_buf + 6, buffer, count); checksum = calc_checksum (buffer, count); snd_buf[0] = 0x1; /* Load command */ snd_buf[1] = 0x2; /* Loading data */ snd_buf[2] = pkt_num >> 8; snd_buf[3] = pkt_num; snd_buf[4] = checksum >> 8; snd_buf[5] = checksum; send_buf (fd, snd_buf, count + 6); cc = recv_buf (fd, snd_buf, sizeof snd_buf, 3); if (cc == 0) { fprintf (stderr , "send_data: timeout sending %d bytes to addr 0x%lx, retrying\n", count, addr); continue; } if (cc < 1) { fprintf (stderr, "Got back short response for load data\n"); exit (1); } if (snd_buf[0] != 0xff) { fprintf (stderr, "Got back bad response for load data\n"); exit (1); } old_addr += count; pkt_num++; return; }}extern int optind;intmain (argc, argv) int argc; char **argv;{ int cc, c; unsigned char buf[10]; asection *section; bfd *pbfd; unsigned long entry; struct hostent *he; struct sockaddr_in sockaddr; while ((c = getopt(argc, argv, "")) != EOF) { switch (c) { default: usage(); } } argc -= optind; argv += optind; if (argc != 2) usage (); pbfd = bfd_openr (argv[1], 0); if (pbfd == NULL) sys_error ("Open of PROG failed"); /* Setup the socket. Must be raw UDP. */ he = gethostbyname (argv[2]); if (!he) sys_error ("No such host"); netfd = socket (PF_INET, SOCK_DGRAM, 0); sockaddr.sin_family = PF_INET; sockaddr.sin_port = htons(7000); memcpy (&sockaddr.sin_addr.s_addr, he->h_addr, sizeof (struct in_addr)); if (connect (netfd, &sockaddr, sizeof(sockaddr))) sys_error ("Connect failed"); buf[0] = 0x5; buf[1] = 0; send_buf (netfd, buf, 2); /* Request version */ cc = recv_buf (netfd, buf, sizeof(buf), -1); /* Get response */ if (cc < 3) { fprintf (stderr, "SPARClite appears to be ill\n"); exit (1); } printf ("[SPARClite appears to be alive]\n"); if (!bfd_check_format (pbfd, bfd_object)) error ("It doesn't seem to be an object file"); for (section = pbfd->sections; section; section = section->next) { if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC) { bfd_vma section_address; unsigned long section_size; const char *section_name; section_name = bfd_get_section_name (pbfd, section); section_address = bfd_get_section_vma (pbfd, section); /* Adjust sections from a.out files, since they don't carry their addresses with. */ if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour) section_address += LOAD_ADDRESS; section_size = bfd_section_size (pbfd, section); printf("[Loading section %s at %lx (%ld bytes)]\n", section_name, section_address, section_size); /* Text, data or lit */ if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) { file_ptr fptr; fptr = 0; while (section_size > 0) { char buffer[1024]; int count; static char inds[] = "|/-\\"; static int k = 0; count = min (section_size, 1024); bfd_get_section_contents (pbfd, section, buffer, fptr, count);#if 0 { int i; unsigned char checksum; checksum = 0; for (i=0; i < count; i++) checksum += buffer[i]; }#endif printf ("\r%c", inds[k++ % 4]); fflush (stdout); send_data (buffer, netfd, section_address, count); section_address += count; fptr += count; section_size -= count; } } else /* BSS */ printf ("Not loading BSS \n"); } } entry = bfd_get_start_address (pbfd); printf ("[Starting %s at 0x%lx]\n", argv[1], entry); buf[0] = 0x3; buf[1] = 0; buf[2] = entry >> 24; buf[3] = entry >> 16; buf[4] = entry >> 8; buf[5] = entry; send_buf (netfd, buf, 6); /* Send start addr */ cc = recv_buf (netfd, buf, sizeof(buf), -1); /* Get response */ if (cc < 1 || buf[0] != 0x55) { fprintf (stderr, "Failed to take start address\n"); exit (1); } exit (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -