[syslinux:master] sysdump: actually make the new backend system work

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sun Feb 7 16:30:10 PST 2010


Commit-ID:  9bb975b60999ddd94610b2d66ac7b2b9bfaaea20
Gitweb:     http://syslinux.zytor.com/commit/9bb975b60999ddd94610b2d66ac7b2b9bfaaea20
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 7 Feb 2010 16:26:40 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 7 Feb 2010 16:26:40 -0800

sysdump: actually make the new backend system work

With these changes, both TFTP and Ymodem seem to actually work.

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


---
 com32/sysdump/backend.h   |    4 +++-
 com32/sysdump/be_tftp.c   |    1 +
 com32/sysdump/be_ymodem.c |   40 ++++++++++++++++++++++------------------
 com32/sysdump/cpio.c      |   10 +---------
 com32/sysdump/main.c      |    8 ++++----
 com32/sysdump/serial.c    |   30 +++++++++++++++++++++---------
 com32/sysdump/zout.c      |   36 ++++++++++++++++++++----------------
 7 files changed, 72 insertions(+), 57 deletions(-)

diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h
index 21a9ff8..0926c8d 100644
--- a/com32/sysdump/backend.h
+++ b/com32/sysdump/backend.h
@@ -19,6 +19,8 @@ struct backend {
     size_t zbytes;
     const char **argv;
 
+    uint32_t now;
+
     int (*write)(struct backend *);
 
     z_stream zstream;
@@ -32,9 +34,9 @@ int write_data(struct backend *be, const void *buf, size_t len);
 int flush_data(struct backend *be);
 
 /* cpio.c */
+#define cpio_init init_data
 int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
 	     const char *filename);
-int cpio_init(struct backend *be, const char *argv[]);
 int cpio_mkdir(struct backend *be, const char *filename);
 int cpio_writefile(struct backend *be, const char *filename,
 		   const void *data, size_t len);
diff --git a/com32/sysdump/be_tftp.c b/com32/sysdump/be_tftp.c
index 7964238..07fdb08 100644
--- a/com32/sysdump/be_tftp.c
+++ b/com32/sysdump/be_tftp.c
@@ -126,6 +126,7 @@ static int be_tftp_write(struct backend *be)
 	*((uint16_t *)(buffer+2)) = htons(++tftp.seq);
 	memcpy(buffer+4, data, chunk);
 	data += chunk;
+	len -= chunk;
 
 	if (send_ack_packet(&tftp, buffer, chunk+4))
 	    return -1;
diff --git a/com32/sysdump/be_ymodem.c b/com32/sysdump/be_ymodem.c
index b36bd03..fa2cc60 100644
--- a/com32/sysdump/be_ymodem.c
+++ b/com32/sysdump/be_ymodem.c
@@ -19,7 +19,7 @@ enum {
 
 struct ymodem_state {
     struct serial_if serial;
-    uint16_t seq;
+    unsigned int seq, blocks;
 };
 
 /*
@@ -75,7 +75,7 @@ static void send_ack(struct ymodem_state *ym, const uint8_t *blk,
 
 static void send_ack_blk(struct ymodem_state *ym, uint8_t *blk)
 {
-    printf("Sending block %u...\r", ym->seq);
+    printf("Sending block %u/%u...\r", ym->seq, ym->blocks);
 
     blk[0] = STX;
     blk[1] = ym->seq++;
@@ -106,13 +106,24 @@ static int be_ymodem_write(struct backend *be)
     struct ymodem_state ym;
     const char *buf;
     size_t len, chunk;
+    const char ymodem_banner[] = "Now begin Ymodem download...\r\n";
+
+    buf = be->outbuf;
+    len = be->zbytes;
+
+    putchar('\n');
 
     ym.seq = 0;
+    ym.blocks = (len+1023)/1024;
 
     /* Initialize serial port */
     if (serial_init(&ym.serial, &be->argv[1]))
 	return -1;
 
+    /* Write banner */
+    printf("Writing banner...\n");
+    serial_write(&ym.serial, ymodem_banner, sizeof ymodem_banner-1);
+
     /* Wait for initial handshake */
     printf("Waiting for handshake...\n");
     do {
@@ -120,20 +131,20 @@ static int be_ymodem_write(struct backend *be)
     } while (ack_buf != 'C');
 
     /* Send filename block */
-    snprintf((char *)blk_buf+3, 1024, "%s%c%zu", be->argv[0], 0, be->zbytes);
+    memset(blk_buf, 0, sizeof blk_buf);
+    snprintf((char *)blk_buf+3, 1024, "%s%c%zu 0%o 0644",
+	     be->argv[0], 0, be->zbytes, be->now);
     send_ack_blk(&ym, blk_buf);
 
-    buf = be->outbuf;
-    len = be->zbytes;
-
     while (len) {
 	chunk = len < 1024 ? len : 1024;
 
 	memcpy(blk_buf+3, buf, chunk);
 	if (chunk < 1024)
-	    memset(blk_buf+3+1024-chunk, 0x1a, 1024-chunk);
+	    memset(blk_buf+3+chunk, 0x1a, 1024-chunk);
 
 	send_ack_blk(&ym, blk_buf);
+	buf += chunk;
 	len -= chunk;
     }
 
@@ -147,17 +158,10 @@ static int be_ymodem_write(struct backend *be)
     ym.seq = 0;
 
     printf("Sending batch termination block...\n");
-    memset(blk_buf+3, 0, 128);
-    blk_buf[0] = SOH;
-    blk_buf[1] = 0;
-    blk_buf[2] = 0xff;
-    add_crc16(blk_buf + 3, 128);
-    serial_write(&ym.serial, blk_buf, 128 + 5);
-    /*
-     * rb doesn't seem to ack the EOT for an end batch transfer,
-     * contrary to spec.
-     */
-    printf("Done.\n");
+    memset(blk_buf+3, 0, 1024);
+    send_ack_blk(&ym, blk_buf);
+
+    printf("Cleaning up...             \n");
     serial_cleanup(&ym.serial);
 
     return 0;
diff --git a/com32/sysdump/cpio.c b/com32/sysdump/cpio.c
index dfc7c94..81d0d4b 100644
--- a/com32/sysdump/cpio.c
+++ b/com32/sysdump/cpio.c
@@ -12,8 +12,6 @@
 #include "backend.h"
 #include "ctime.h"
 
-static uint32_t now;
-
 int cpio_pad(struct backend *be)
 {
     static char pad[4];		/* Up to 4 zero bytes */
@@ -40,7 +38,7 @@ int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
 	    0,			/* c_uid */
 	    0,			/* c_gid */
 	    1,			/* c_nlink */
-	    now,		/* c_mtime */
+	    be->now,		/* c_mtime */
 	    datalen,		/* c_filesize */
 	    0,			/* c_maj */
 	    0,			/* c_min */
@@ -54,12 +52,6 @@ int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
     return rv;
 }
 
-int cpio_init(struct backend *be, const char *argv[])
-{
-    now = posix_time();
-    return init_data(be, argv);
-}
-
 int cpio_mkdir(struct backend *be, const char *filename)
 {
     return cpio_hdr(be, MODE_DIR, 0, filename);
diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c
index 1924506..f4b5ad9 100644
--- a/com32/sysdump/main.c
+++ b/com32/sysdump/main.c
@@ -24,6 +24,7 @@
 #include "sysdump.h"
 
 const char program[] = "sysdump";
+const char version[] = "SYSDUMP " VERSION_STR " " DATE "\n";
 
 __noreturn die(const char *msg)
 {
@@ -33,8 +34,6 @@ __noreturn die(const char *msg)
 
 static void dump_all(struct backend *be, const char *argv[])
 {
-    static const char version[] = "SYSDUMP " VERSION_STR " " DATE "\n";
-
     cpio_init(be, argv);
 
     cpio_writefile(be, "sysdump", version, sizeof version);
@@ -47,9 +46,7 @@ static void dump_all(struct backend *be, const char *argv[])
     dump_vesa_tables(be);
 
     cpio_close(be);
-    printf("Uploading data... ");
     flush_data(be);
-    printf("done.\n");
 }
 
 static struct backend *backends[] =
@@ -75,6 +72,7 @@ int main(int argc, char *argv[])
     struct backend **bep, *be;
 
     openconsole(&dev_null_r, &dev_stdcon_w);
+    fputs(version, stdout);
 
     if (argc < 2)
 	usage();
@@ -90,6 +88,8 @@ int main(int argc, char *argv[])
     /* Do this as early as possible */
     snapshot_lowmem();
 
+    printf("Backend: %s\n", be->name);
+
     /* Do the actual data dump */
     dump_all(be, (const char **)argv + 2);
 
diff --git a/com32/sysdump/serial.c b/com32/sysdump/serial.c
index 71b3067..03f6403 100644
--- a/com32/sysdump/serial.c
+++ b/com32/sysdump/serial.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/io.h>
+#include <sys/cpu.h>
 
 #include "serial.h"
 
@@ -28,8 +29,13 @@ int serial_init(struct serial_if *sif, const char *argv[])
     uint8_t dll, dlm, lcr;
 
     port = strtoul(argv[0], NULL, 0);
-    if (port <= 3)
-      port = *(uint16_t *)(0x400 + port*2);
+    if (port <= 3) {
+	uint16_t addr = ((uint16_t *)0x400)[port];
+	printf("Serial port %u is at 0x%04x\n", port, addr);
+	port = addr;
+    }
+
+    sif->port = port;
 
     if (argv[1])
 	speed = strtoul(argv[1], NULL, 0);
@@ -38,12 +44,14 @@ int serial_init(struct serial_if *sif, const char *argv[])
 
     divisor = 115200/speed;
 
+    cli();			/* Just in case... */
+
     /* Save old register settings */
     sif->old.lcr = inb(port + LCR);
     sif->old.mcr = inb(port + MCR);
     sif->old.iir = inb(port + IIR);
 
-    /* Set 115200n81 */
+    /* Set speed */
     outb(0x83, port + LCR);	/* Enable divisor access */
     sif->old.dll = inb(port + DLL);
     sif->old.dlm = inb(port + DLM);
@@ -54,17 +62,21 @@ int serial_init(struct serial_if *sif, const char *argv[])
     dll = inb(port + DLL);
     dlm = inb(port + DLM);
     lcr = inb(port + LCR);
-    outb(0x03, port + LCR);
+    outb(0x03, port + LCR);	/* Enable data access, n81 */
     (void)inb(port + IER);	/* Synchronize */
     sif->old.ier = inb(port + IER);
 
+    /* Disable interrupts */
+    outb(0, port + IER);
+
+    sti();
+
     if (dll != (uint8_t)divisor ||
 	dlm != (uint8_t)(divisor >> 8) ||
-	lcr != 0x83)
+	lcr != 0x83) {
+	printf("No serial port detected!\n");
 	return -1;		/* This doesn't look like a serial port */
-
-    /* Disable interrupts */
-    outb(0, port + IER);
+    }
 
     /* Enable 16550A FIFOs if available */
     outb(0x41, port + FCR);	/* Enable FIFO */
@@ -119,6 +131,6 @@ void serial_cleanup(struct serial_if *sif)
     (void)inb(port + IER);
     outb(sif->old.mcr, port + MCR);
     outb(sif->old.ier, port + IER);
-    if ((sif->old.iir & 0xc0) != 0xc0)
+    if (sif->old.iir < 0xc0)
 	outb(0x00, port + FCR);	/* Disable FIFOs */
 }
diff --git a/com32/sysdump/zout.c b/com32/sysdump/zout.c
index 61dd514..0334d80 100644
--- a/com32/sysdump/zout.c
+++ b/com32/sysdump/zout.c
@@ -9,23 +9,19 @@
 #include <stdbool.h>
 #include <zlib.h>
 #include "backend.h"
+#include "ctime.h"
 
 #define ALLOC_CHUNK	65536
 
 int init_data(struct backend *be, const char *argv[])
 {
+    be->now = posix_time();
     be->argv = argv;
 
-    be->alloc  = ALLOC_CHUNK;
-    be->outbuf = malloc(ALLOC_CHUNK);
-    if (!be->outbuf)
-	return -1;
-
     memset(&be->zstream, 0, sizeof be->zstream);
 
-    be->zstream.next_out  = (void *)be->outbuf;
-    be->zstream.avail_out = ALLOC_CHUNK;
-
+    be->zstream.next_out  = be->outbuf = NULL;
+    be->zstream.avail_out = be->alloc  = 0;
     be->dbytes = be->zbytes = 0;
 
     /* Initialize a gzip data stream */
@@ -39,20 +35,22 @@ int init_data(struct backend *be, const char *argv[])
 static int do_deflate(struct backend *be, int flush)
 {
     int rv;
+    char *buf;
+
+    while (1) {
+	rv = deflate(&be->zstream, flush);
+	be->zbytes = be->alloc - be->zstream.avail_out;
+	if (be->zstream.avail_out)
+	    return rv;		   /* Not an issue of output space... */
 
-    rv = deflate(&be->zstream, flush);
-    be->zbytes = be->alloc - be->zstream.avail_out;
-    if (be->zstream.avail_out == 0) {
-	char *buf;
 	buf = realloc(be->outbuf, be->alloc + ALLOC_CHUNK);
 	if (!buf)
 	    return Z_MEM_ERROR;
 	be->outbuf = buf;
+	be->alloc += ALLOC_CHUNK;
 	be->zstream.next_out = (void *)(buf + be->zbytes);
 	be->zstream.avail_out = be->alloc - be->zbytes;
     }
-
-    return rv;
 }
 
 
@@ -67,8 +65,10 @@ int write_data(struct backend *be, const void *buf, size_t len)
 
     while (be->zstream.avail_in) {
 	rv = do_deflate(be, Z_NO_FLUSH);
-	if (rv < 0)
+	if (rv < 0) {
+	    printf("do_deflate returned %d\n", rv);
 	    return -1;
+	}
     }
     return 0;
 }
@@ -78,17 +78,21 @@ int flush_data(struct backend *be)
 {
     int rv = Z_OK;
 
-    while (rv == Z_OK) {
+    while (rv != Z_STREAM_END) {
 	rv = do_deflate(be, Z_FINISH);
 	if (rv < 0)
 	    return -1;
     }
 
+    printf("Uploading data, %u bytes... ", be->zbytes);
+
     if (be->write(be))
 	return -1;
 
     free(be->outbuf);
     be->outbuf = NULL;
     be->dbytes = be->zbytes = be->alloc = 0;
+
+    printf("done.\n");
     return 0;
 }



More information about the Syslinux-commits mailing list