aboutsummaryrefslogtreecommitdiffstats
path: root/memdump/srecsend.c
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 /memdump/srecsend.c
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>
Diffstat (limited to 'memdump/srecsend.c')
-rw-r--r--memdump/srecsend.c80
1 files changed, 80 insertions, 0 deletions
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");
+}