8
#include <netinet/in.h>
12
#include <sys/types.h>
16
#include <sys/ioctl.h>
20
#include "bootbytes.h"
22
static int debug_hex=0;
23
static int debug_dtr=0;
24
static int debug_flush=0;
26
static int debug_poll=0;
28
static int debug_rw=0;
30
static void dtr_ctl(int fd, int dtrval)
34
ioctl(fd, TIOCMGET, &dtrflags);
35
if (debug_dtr) fprintf(stderr, "dtrFlags are %x.\n", dtrflags);
39
dtrflags |= TIOCM_DTR;
43
dtrflags &= ~TIOCM_DTR;
46
ioctl(fd, TIOCMSET, &dtrflags);
47
if (debug_dtr) fprintf(stderr, "Setting %x.\n", dtrflags);
49
ioctl(fd, TIOCMGET, &dtrflags);
50
if (debug_dtr) fprintf(stderr, "dtrFlags are %x.\n", dtrflags);
55
static void change_baudrate(int fd, int baudr)
59
memset(&ios, 0, sizeof(ios));
63
if (debug_flush) fprintf(stderr, "IBaud=%d\n", cfgetispeed(&ios));
64
if (debug_flush) fprintf(stderr, "OBaud=%d\n", cfgetospeed(&ios));
70
cfsetospeed(&ios, B2400);
75
cfsetospeed(&ios, B57600);
80
fprintf(stderr, "Illegal baudrate: %d\n", baudr);
85
tcsetattr(fd, TCSADRAIN, &ios);
89
static void msleep(int msec)
95
/** Will wait indefinately for either stdin or serial data */
96
static void do_poll(int serfd)
100
memset(fds, 0, 2*sizeof(struct pollfd));
102
if (debug_poll) fprintf(stderr, "Entering do_poll()\n");
105
fds[1].fd=0; /* stdin */
107
fds[0].events=POLLIN;
108
fds[1].events=POLLIN;
115
if (debug_poll) fprintf(stderr, "Leaving do_poll()\n");
118
static int check_fd(int anfd)
129
if (fds.revents & POLLIN)
131
if (debug_poll) fprintf(stderr, "fd=%d, we have pollin data\n", anfd);
135
if (debug_poll) fprintf(stderr, "fd=%d, we have NO pollin data\n", anfd);
139
return (fds.revents & POLLIN);
142
/** Code below here should be fairly portable **/
144
static void usage(const char* argv0)
146
fprintf(stderr, "Usage: %s -r <ttydev> <coldload binfile>\n", argv0);
147
fprintf(stderr, " or\n", argv0);
148
fprintf(stderr, "Usage: %s -b <ttydev> <divisor> <binfile>\n", argv0);
154
static void talk(int tty)
160
do_poll(tty); /** Infinite wait for either stdin or data from serial */
164
if (debug_rw) fprintf(stderr, " Before read serial...\n");
166
if (debug_rw) fprintf(stderr, " After read serial...\n");
168
if (debug_hex) fprintf(stderr, "Got: %.2x (hex))\n", ch);
170
/** Print unprintables as stars '*' */
171
if (ch>=' ' && ch<='~')
185
printf("<%.2X>", ch);
189
else if (check_fd(0))
191
if (debug_rw) fprintf(stderr, " Before read stdin...\n");
195
if (debug_rw) fprintf(stderr, " After read stdin...\n");
197
if (debug_rw) fprintf(stderr, " Read stdin=%d\n", ch);
203
msleep(100); /** Just sleep to give target a chance to respond */
212
int main(int argc, char *argv[])
214
/** Assume hex-ascii */
217
/** This flag is set if we communicate raw with the target */
236
/** To keep the size of the .bin file */
243
if (argc!=4 && argc!=5)
248
if (0==strncmp(argv[1], "-b", 2))
250
if (argc!=5) usage(argv[0]);
253
divisor=atoi(argv[3]);
257
binfile=fopen(binfilename, "rb");
261
fprintf(stderr, "Could not open %s\n", binfilename);
265
else if (0==strncmp(argv[1], "-r", 2))
267
if (argc!=4) usage(argv[0]);
283
coldboot=fopen(fname, "rb");
286
fprintf(stderr, "Could not open %s\n", fname);
291
tty=open(ttyname, O_RDWR|O_NOCTTY);
294
fprintf(stderr, "Could not open device: %s\n", ttyname);
298
change_baudrate(tty, 2400);
303
/** Reset turned off */
306
/** Time to stabilize */
309
/** Flush serial port */
310
while (check_fd(tty))
314
if (debug_flush) fprintf(stderr, "Flushed %.2x off serial line\n", junk);
317
if (is_raw) /** Take whole file from coldboot file @ 2400 */
319
printf("Using the -r (raw) option means that we will download the whole program\n");
320
printf("with the ultra slow bootstrap utility @ 2400 baud, this means even\n");
321
printf("the smallest hello-world program will take about 13-14 seconds to\n");
322
printf("complete, please be patient.\n");
323
printf("Also note that stdout will not work until it is set up in user code!!!\n");
326
while (!feof(coldboot))
328
fread(&ch, 1, 1, coldboot);
329
if (feof(coldboot)) break;
331
/** Make the rawmode target code bypass the handshake BA BE etc. */
334
/** Are we the dummy mnemonic ld hl,NN ??? */
337
ch=0xc3; /** jp NN mnemonic, address is same */
338
fprintf(stderr, "Changing to jp at address 0x03h\n");
342
fprintf(stderr, "Wrong magic pattern in .LOD file, have you changed rcmx000_boot.asm???\n");
349
if (debug_hex) fprintf(stderr, "wrote: %.2x \n", ch);
355
else /** We take the cold boot section from this binaries own data... */
357
for (i=0;i<s_num_bytes;i++)
361
/** Patch the divisor in... */
367
fprintf(stderr, "Changing divisor to: %d\n", ch);
371
fprintf(stderr, "Wrong magic pattern in .LOD file, have you changed rcmx000_boot.asm???\n");
377
if (debug_hex) fprintf(stderr, "(raw) wrote: %.2x \n", ch);
384
fprintf(stderr, "Waiting indefinately for reply...\n");
389
/** Handshake protocol to bump baudrate */
392
if (debug_hex) fprintf(stderr, "Got: %.2x (hex))\n", ch);
395
fprintf(stderr, "Wrong magic pattern\n");
400
if (debug_hex) fprintf(stderr, "Got: %.2x (hex))\n", ch);
403
fprintf(stderr, "Wrong magic pattern\n");
409
if (debug_hex) fprintf(stderr, "wrote: %.2x \n", ch);
411
/** Bump the actual baudrate */
412
change_baudrate(tty, 57600);
417
if (debug_hex) fprintf(stderr, "wrote: %.2x \n", ch);
420
if (debug_hex) fprintf(stderr, "Got: %.2x (hex))\n", ch);
423
fprintf(stderr, "Wrong value returned from target\n");
428
if (debug_hex) fprintf(stderr, "Got: %.2x (hex))\n", ch);
429
if (ch!=(divisor/24)-1)
431
fprintf(stderr, "Wrong baudrate divisor in return\n");
436
if (debug_hex) fprintf(stderr, "Got: %.2x (hex))\n", ch);
437
if ( ch != (0xff^(divisor/24)-1) )
439
fprintf(stderr, "Wrong baudrate divisor in return\n");
445
/** Now we transfer the .bin file but first we find out its length */
447
fseek(binfile, 0, SEEK_END);
449
fsize=ftell(binfile);
451
if (debug_hex) fprintf(stderr, "fsize=%d\n", fsize);
453
/** Network order, two bytes size (max 64k ;-) */
456
if (debug_hex) fprintf(stderr, "wrote: %.2x \n", ch);
462
if (debug_hex) fprintf(stderr, "wrote: %.2x \n", ch);
467
fseek(binfile, 0, SEEK_SET);
469
for (i=0;i<fsize;i++)
471
fread(&ch, 1, 1, binfile);
477
fprintf(stderr, "Unexpected EOF in .bin file\n");
482
if (debug_hex) fprintf(stderr, "wrote: %.2x \n", ch);
485
if (debug_hex) fprintf(stderr, "Checksum lo: %.2x (hex))\n", csum&255);
486
if (debug_hex) fprintf(stderr, "Checksum hi: %.2x (hex))\n", (csum>>8)&255);
487
/** Read the checksum */
490
if (debug_hex) fprintf(stderr, "Got Checksum lo: %.2x (hex))\n", ch);
493
fprintf(stderr, "Wrong checksum\n");
498
if (debug_hex) fprintf(stderr, "Got Checksum hi: %.2x (hex))\n", ch);
499
if (ch!=((csum/256)&255))
501
fprintf(stderr, "Wrong checksum\n");
505
/** Start conversation with stdin/stdout of target */