[syslinux:master] sysdump: output S-records to the console

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Tue Jun 22 13:39:14 PDT 2010


Commit-ID:  77d76c3ff1d922cda47754bdce98807e9a560585
Gitweb:     http://syslinux.zytor.com/commit/77d76c3ff1d922cda47754bdce98807e9a560585
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Tue, 22 Jun 2010 13:35:29 -0700
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Tue, 22 Jun 2010 13:35:29 -0700

sysdump: output S-records to the console

Sometimes we have a console path that can be captured (virtual
machine, serial console, ...) but no realistic path for two-way or
binary communication.  Add an option to output S-records to the
console as an inefficient but hopefully reliable way to get data out.

Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>


---
 com32/sysdump/backend.h |    1 +
 com32/sysdump/be_srec.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++
 com32/sysdump/main.c    |    1 +
 3 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h
index 0926c8d..f2b3bc2 100644
--- a/com32/sysdump/backend.h
+++ b/com32/sysdump/backend.h
@@ -50,5 +50,6 @@ struct backend *get_backend(const char *name);
 /* backends */
 extern struct backend be_tftp;
 extern struct backend be_ymodem;
+extern struct backend be_srec;
 
 #endif /* BACKEND_H */
diff --git a/com32/sysdump/be_srec.c b/com32/sysdump/be_srec.c
new file mode 100644
index 0000000..3b52b1a
--- /dev/null
+++ b/com32/sysdump/be_srec.c
@@ -0,0 +1,84 @@
+/*
+ * S-records dump routine -- dumps S-records on the console
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <minmax.h>
+#include "backend.h"
+
+/* Write a single S-record */
+static int write_srecord(unsigned int len,  unsigned int alen,
+                         uint32_t addr, uint8_t type, const void *data)
+{
+    char buf[2+2+8+255*2+2+2];
+    char *p = buf;
+    uint8_t csum;
+    const uint8_t *dptr = data;
+    unsigned int i;
+
+    switch (alen) {
+    case 2:
+        addr &= 0xffff;
+        break;
+    case 3:
+        addr &= 0xffffff;
+        break;
+    case 4:
+        break;
+    }
+
+    csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
+    for (i = 0; i < len; i++)
+        csum += dptr[i];
+    csum = 0xff-csum;
+
+    p += sprintf(p, "S%c%02X%0*X", type, len+alen+1, alen*2, addr);
+    for (i = 0; i < len; i++)
+        p += sprintf(p, "%02X", dptr[i]);
+    p += sprintf(p, "%02X\n", csum);
+
+    fputs(buf, stdout);
+    return 0;
+}
+
+static int be_srec_write(struct backend *be)
+{
+    char name[33];
+    const char *buf;
+    size_t len, chunk, offset, hdrlen;
+
+    buf = be->outbuf;
+    len = be->zbytes;
+
+    putchar('\n');
+
+    hdrlen = snprintf(name, sizeof name, "%.32s",
+		      be->argv[0] ? be->argv[0] : "");
+
+    /* Write head record */
+    write_srecord(hdrlen, 2, 0, '0', name);
+
+    /* Write data records */
+    offset = 0;
+    while (len) {
+	chunk = min(len, (size_t)32);
+
+	write_srecord(chunk, 4, offset, '3', buf);
+	buf += chunk;
+	len -= chunk;
+    }
+
+    /* Write termination record */
+    write_srecord(0, 4, 0, '7', NULL);
+
+    return 0;
+}
+
+struct backend be_srec = {
+    .name       = "srec",
+    .helpmsg    = "[filename]",
+    .minargs    = 0,
+    .write      = be_srec_write,
+};
diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c
index 26f562b..d0d40a7 100644
--- a/com32/sysdump/main.c
+++ b/com32/sysdump/main.c
@@ -54,6 +54,7 @@ static struct backend *backends[] =
 {
     &be_tftp,
     &be_ymodem,
+    &be_srec,
     NULL
 };
 



More information about the Syslinux-commits mailing list