[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