[syslinux:master] memdump: allow outputting S-records

syslinux-bot for H. Peter Anvin hpa at zytor.com
Fri Feb 5 18:06:10 PST 2010


Commit-ID:  3dededd20d70d571268417dc41edc95f0fe6602e
Gitweb:     http://syslinux.zytor.com/commit/3dededd20d70d571268417dc41edc95f0fe6602e
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Fri, 5 Feb 2010 18:03:14 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Fri, 5 Feb 2010 18:03:14 -0800

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 at zytor.com>


---
 memdump/Makefile                     |    2 +-
 memdump/{ymsend.h => file.h}         |   10 ++---
 memdump/main.c                       |   30 ++++++++++---
 memdump/serial.c                     |    5 ++-
 memdump/srecsend.c                   |   80 ++++++++++++++++++++++++++++++++++
 memdump/srecsend.h                   |   10 ++++
 {com32/include => memdump}/stdbool.h |    0
 memdump/ymsend.h                     |   18 +-------
 8 files changed, 123 insertions(+), 32 deletions(-)

diff --git a/memdump/Makefile b/memdump/Makefile
index 05f2638..e56c7bd 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/ymsend.h b/memdump/file.h
similarity index 68%
copy from memdump/ymsend.h
copy to memdump/file.h
index daed627..8da6973 100644
--- a/memdump/ymsend.h
+++ b/memdump/file.h
@@ -1,5 +1,5 @@
-#ifndef YMSEND_H
-#define YMSEND_H
+#ifndef FILE_H
+#define FILE_H
 
 #include "mystuff.h"
 
@@ -12,16 +12,14 @@ struct serial_if {
 
 struct file_info {
     const char *name;
+    size_t base;
     size_t size;
     void *pvt;
 };
 
-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 */
+#endif /* FILE_H */
diff --git a/memdump/main.c b/memdump/main.c
index 02f2a4f..068f657 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 c8330f7..1c613d1 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 0000000..668d16c
--- /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 0000000..f2b0822
--- /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/com32/include/stdbool.h b/memdump/stdbool.h
similarity index 100%
copy from com32/include/stdbool.h
copy to memdump/stdbool.h
diff --git a/memdump/ymsend.h b/memdump/ymsend.h
index daed627..b0d7438 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 */



More information about the Syslinux-commits mailing list