[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