aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-05 18:03:14 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-05 18:03:14 -0800
commit3dededd20d70d571268417dc41edc95f0fe6602e (patch)
treea3c64b598884588323d6f0c08c9034a30f3f9b95
parent88c00aca310b7bade07833d3021cae9da266eae7 (diff)
downloadsyslinux.git-3dededd20d70d571268417dc41edc95f0fe6602e.tar.gz
syslinux.git-3dededd20d70d571268417dc41edc95f0fe6602e.tar.xz
syslinux.git-3dededd20d70d571268417dc41edc95f0fe6602e.zip
memdump: allow outputting S-records
Allow outputting S-records, for users who only have the capability of passively monitoring a serial port as opposed to being able to capture the contents directly. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--memdump/Makefile2
-rw-r--r--memdump/file.h25
-rw-r--r--memdump/main.c30
-rw-r--r--memdump/serial.c5
-rw-r--r--memdump/srecsend.c80
-rw-r--r--memdump/srecsend.h10
-rw-r--r--memdump/stdbool.h32
-rw-r--r--memdump/ymsend.h18
8 files changed, 176 insertions, 26 deletions
diff --git a/memdump/Makefile b/memdump/Makefile
index 05f26383..e56c7bd4 100644
--- a/memdump/Makefile
+++ b/memdump/Makefile
@@ -21,7 +21,7 @@ OPTFLAGS =
INCLUDES = -include code16.h -I.
LDFLAGS = -T com16.ld
-SRCS = main.c serial.c ymsend.c
+SRCS = main.c serial.c ymsend.c srecsend.c
OBJS = crt0.o $(patsubst %.c,%.o,$(notdir $(SRCS)))
LIBOBJS = conio.o memcpy.o memset.o skipatou.o strtoul.o \
argv.o printf.o __divdi3.o __udivmoddi4.o
diff --git a/memdump/file.h b/memdump/file.h
new file mode 100644
index 00000000..8da6973d
--- /dev/null
+++ b/memdump/file.h
@@ -0,0 +1,25 @@
+#ifndef FILE_H
+#define FILE_H
+
+#include "mystuff.h"
+
+struct serial_if {
+ int port;
+ void *pvt;
+ void (*read) (struct serial_if *, void *, size_t);
+ void (*write) (struct serial_if *, const void *, size_t);
+};
+
+struct file_info {
+ const char *name;
+ size_t base;
+ size_t size;
+ void *pvt;
+};
+
+
+int serial_init(struct serial_if *sif);
+void serial_read(struct serial_if *sif, void *data, size_t n);
+void serial_write(struct serial_if *sif, const void *data, size_t n);
+
+#endif /* FILE_H */
diff --git a/memdump/main.c b/memdump/main.c
index 02f2a4fc..068f657e 100644
--- a/memdump/main.c
+++ b/memdump/main.c
@@ -13,8 +13,10 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <stdbool.h>
#include "mystuff.h"
#include "ymsend.h"
+#include "srecsend.h"
#include "io.h"
const char *program = "memdump";
@@ -89,10 +91,17 @@ int main(int argc, char *argv[])
.write = serial_write,
};
struct file_info finfo;
- const char serial_banner[] = "Now begin Ymodem download...\r\n";
+ const char ymodem_banner[] = "Now begin Ymodem download...\r\n";
+ bool srec = false;
+
+ if (argv[1][0] == '-') {
+ srec = argv[1][1] == 's';
+ argc--;
+ argv++;
+ }
if (argc < 4)
- die("usage: memdump port prefix start,len...");
+ die("usage: memdump [-s] port prefix start,len...");
finfo.pvt = (void *)0x400;
get_bytes(bios_ports, 8, &finfo, 0); /* Get BIOS serial ports */
@@ -110,8 +119,10 @@ int main(int argc, char *argv[])
prefix = argv[2];
- puts("Printing prefix...\n");
- sif.write(&sif, serial_banner, sizeof serial_banner - 1);
+ if (!srec) {
+ puts("Printing prefix...\n");
+ sif.write(&sif, ymodem_banner, sizeof ymodem_banner - 1);
+ }
for (i = 3; i < argc; i++) {
uint32_t start, len;
@@ -131,11 +142,16 @@ int main(int argc, char *argv[])
puts(filename);
puts("...\n");
- send_ymodem(&sif, &finfo, get_bytes);
+ if (srec)
+ send_srec(&sif, &finfo, get_bytes);
+ else
+ send_ymodem(&sif, &finfo, get_bytes);
}
- puts("Sending closing signature...\n");
- end_ymodem(&sif);
+ if (!srec) {
+ puts("Sending closing signature...\n");
+ end_ymodem(&sif);
+ }
return 0;
}
diff --git a/memdump/serial.c b/memdump/serial.c
index c8330f71..1c613d17 100644
--- a/memdump/serial.c
+++ b/memdump/serial.c
@@ -1,5 +1,8 @@
+#include <stdbool.h>
+#include <stdio.h>
+
#include "mystuff.h"
-#include "ymsend.h"
+#include "file.h"
#include "io.h"
enum {
diff --git a/memdump/srecsend.c b/memdump/srecsend.c
new file mode 100644
index 00000000..668d16cb
--- /dev/null
+++ b/memdump/srecsend.c
@@ -0,0 +1,80 @@
+/*
+ * SREC send routine.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "srecsend.h"
+
+static void make_srec(struct serial_if *sif, char type, size_t addr,
+ const void *data, size_t len)
+{
+ char buf[80]; /* More than the largest possible size */
+ char *p;
+ const uint8_t *dp = data;
+ size_t alen = (type == '0') ? 4 : 8;
+ uint8_t csum;
+
+ p = buf;
+ *p++ = 'S';
+ *p++ = type;
+ if (type == '0')
+ p += sprintf(p, "%04zX", addr);
+ else
+ p += sprintf(p, "%08zX", addr);
+
+ csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
+ while (len) {
+ p += sprintf(p, "%02X", *dp);
+ csum += *dp;
+ dp++;
+ }
+ csum = 0xff - csum;
+ p += sprintf(p, "%02X\r\n", csum);
+
+ sif->write(sif, buf, p-buf);
+}
+
+void send_srec(struct serial_if *sif, struct file_info *fileinfo,
+ void (*gen_data) (void *, size_t, struct file_info *, size_t))
+{
+ uint8_t blk_buf[1024];
+ const uint8_t *np;
+ size_t addr, len, bytes, chunk, offset, pos;
+ int blk;
+
+ len = fileinfo->size;
+
+ make_srec(sif, '0', 0, NULL, 0);
+
+ blk = 0;
+ pos = 0;
+ addr = fileinfo->base;
+ while (len) {
+ gen_data(blk_buf, sizeof blk_buf, fileinfo, pos);
+ pos += sizeof blk_buf;
+ bytes = sizeof blk_buf;
+ if (bytes > len)
+ bytes = len;
+ len -= bytes;
+
+ printf("Sending block %d...\r", blk);
+
+ np = blk_buf;
+ while (bytes) {
+ chunk = bytes > 64 ? 64 : bytes;
+
+ make_srec(sif, '3', addr, np, chunk);
+
+ bytes -= chunk;
+ offset += chunk;
+ np += chunk;
+ addr += chunk;
+ }
+ blk++;
+ }
+
+ printf("\nSending EOT...\n");
+ make_srec(sif, '7', fileinfo->base, NULL, 0);
+ printf("Done.\n");
+}
diff --git a/memdump/srecsend.h b/memdump/srecsend.h
new file mode 100644
index 00000000..f2b08224
--- /dev/null
+++ b/memdump/srecsend.h
@@ -0,0 +1,10 @@
+#ifndef SRECSEND_H
+#define SRECSEND_H
+
+#include "mystuff.h"
+#include "file.h"
+
+void send_srec(struct serial_if *, struct file_info *,
+ void (*)(void *, size_t, struct file_info *, size_t));
+
+#endif /* SRECSEND_H */
diff --git a/memdump/stdbool.h b/memdump/stdbool.h
new file mode 100644
index 00000000..81cb05f5
--- /dev/null
+++ b/memdump/stdbool.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * stdbool.h
+ */
+
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
+# if !defined(__GNUC__) ||(__GNUC__ < 3)
+typedef char _Bool; /* For C compilers without _Bool */
+# endif
+#endif
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+#else
+
+/* C++ */
+#define bool bool
+#define true true
+#define false false
+
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H */
diff --git a/memdump/ymsend.h b/memdump/ymsend.h
index daed627d..b0d74384 100644
--- a/memdump/ymsend.h
+++ b/memdump/ymsend.h
@@ -2,26 +2,10 @@
#define YMSEND_H
#include "mystuff.h"
-
-struct serial_if {
- int port;
- void *pvt;
- void (*read) (struct serial_if *, void *, size_t);
- void (*write) (struct serial_if *, const void *, size_t);
-};
-
-struct file_info {
- const char *name;
- size_t size;
- void *pvt;
-};
+#include "file.h"
void send_ymodem(struct serial_if *, struct file_info *,
void (*)(void *, size_t, struct file_info *, size_t));
void end_ymodem(struct serial_if *);
-int serial_init(struct serial_if *sif);
-void serial_read(struct serial_if *sif, void *data, size_t n);
-void serial_write(struct serial_if *sif, const void *data, size_t n);
-
#endif /* YMSEND_H */