[syslinux:master] sysdump: dump vesa modes, generate usable timestamps

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sat Feb 6 17:48:13 PST 2010


Commit-ID:  177148d253c6ca986ef94aa9b22ae377ddee828a
Gitweb:     http://syslinux.zytor.com/commit/177148d253c6ca986ef94aa9b22ae377ddee828a
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sat, 6 Feb 2010 17:43:11 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sat, 6 Feb 2010 17:44:29 -0800

sysdump: dump vesa modes, generate usable timestamps

Dump all the VESA modes; give functional timestamps for the cpio
members.

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


---
 com32/sysdump/backend.h  |    4 +-
 com32/sysdump/backends.c |    1 -
 com32/sysdump/be_tftp.c  |    4 +-
 com32/sysdump/cpio.c     |   15 +++++++--
 com32/sysdump/ctime.c    |   70 ++++++++++++++++++++++++++++++++++++++++++++++
 com32/sysdump/ctime.h    |    8 +++++
 com32/sysdump/data.h     |    1 -
 com32/sysdump/main.c     |    7 +++-
 com32/sysdump/srecsend.c |    4 +-
 com32/sysdump/sysdump.h  |    8 +++++
 com32/sysdump/vesa.c     |   56 ++++++++++++++++++++++++++++++++++++
 com32/sysdump/zout.c     |    2 +-
 12 files changed, 165 insertions(+), 15 deletions(-)

diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h
index eb6530e..a83e393 100644
--- a/com32/sysdump/backend.h
+++ b/com32/sysdump/backend.h
@@ -12,7 +12,7 @@ struct backend {
 
     int (*open)(struct backend *, const char *argv[]);
     int (*write)(struct backend *, const char *buf, size_t len);
-    
+
     z_stream zstream;
     char *outbuf;
 
@@ -32,7 +32,7 @@ int init_data(struct backend *be, const char *argv[]);
 int write_data(struct backend *be, const void *buf, size_t len, bool flush);
 
 /* cpio.c */
-#define cpio_init init_data
+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/backends.c b/com32/sysdump/backends.c
index 75f1d9d..4d95dbb 100644
--- a/com32/sysdump/backends.c
+++ b/com32/sysdump/backends.c
@@ -24,4 +24,3 @@ struct backend *get_backend(const char *name)
 
     return NULL;
 }
-
diff --git a/com32/sysdump/be_tftp.c b/com32/sysdump/be_tftp.c
index 17275b1..9d945f3 100644
--- a/com32/sysdump/be_tftp.c
+++ b/com32/sysdump/be_tftp.c
@@ -47,7 +47,7 @@ static int send_ack_packet(struct backend *be, const void *pkt, size_t len)
 	ireg.ebx.w[0] = PXENV_UDP_WRITE;
 	ireg.es = SEG(uw);
 	ireg.edi.w[0] = OFFS(uw);
-	
+
 	__intcall(0x22, &ireg, &oreg);
 
 	start = times(NULL);
@@ -60,7 +60,7 @@ static int send_ack_packet(struct backend *be, const void *pkt, size_t len)
 	    ur->d_port = be->tftp.my_port;
 	    ur->buffer_size = __com32.cs_bounce_size - sizeof *ur;
 	    ur->buffer = FAR_PTR(ur+1);
-	    
+
 	    ireg.ebx.w[0] = PXENV_UDP_READ;
 	    ireg.es = SEG(ur);
 	    ireg.edi.w[0] = OFFS(ur);
diff --git a/com32/sysdump/cpio.c b/com32/sysdump/cpio.c
index 984ed3c..79d01fc 100644
--- a/com32/sysdump/cpio.c
+++ b/com32/sysdump/cpio.c
@@ -10,8 +10,10 @@
 #include <stdbool.h>
 #include <zlib.h>
 #include "backend.h"
+#include "ctime.h"
 
 static char pad[4];		/* Up to 4 zero bytes */
+static uint32_t now;
 
 static int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
 		    const char *filename, bool flush)
@@ -28,7 +30,7 @@ static int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
 	    0,			/* c_uid */
 	    0,			/* c_gid */
 	    1,			/* c_nlink */
-	    0,			/* c_mtime */
+	    now,		/* c_mtime */
 	    datalen,		/* c_filesize */
 	    0,			/* c_maj */
 	    0,			/* c_min */
@@ -38,10 +40,16 @@ static int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
 	    0);			/* c_chksum */
     rv |= write_data(be, hdr, 6+13*8, false);
     rv |= write_data(be, filename, nlen, false);
-    rv |= write_data(be, pad, -nlen & 3, flush);
+    rv |= write_data(be, pad, (-nlen+6+13*8) & 3, flush);
     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, 0040755, 0, filename, false);
@@ -52,7 +60,7 @@ int cpio_writefile(struct backend *be, const char *filename,
 {
     int rv;
 
-    rv = cpio_hdr(be, 0100755, len, filename, false);
+    rv = cpio_hdr(be, 0100644, len, filename, false);
     rv |= write_data(be, data, len, false);
     rv |= write_data(be, pad, -len & 3, false);
 }
@@ -61,4 +69,3 @@ int cpio_close(struct backend *be)
 {
     return cpio_hdr(be, 0, 0, "TRAILER!!!", true);
 }
-
diff --git a/com32/sysdump/ctime.c b/com32/sysdump/ctime.c
new file mode 100644
index 0000000..5af8566
--- /dev/null
+++ b/com32/sysdump/ctime.c
@@ -0,0 +1,70 @@
+#include <com32.h>
+#include <string.h>
+#include "ctime.h"
+
+static uint8_t frombcd(uint8_t v)
+{
+    uint8_t a = v & 0x0f;
+    uint8_t b = v >> 4;
+
+    return a + b*10;
+}
+
+uint32_t posix_time(void)
+{
+    /* Days from March 1 for a specific month, starting in March */
+    static const unsigned int yday[12] =
+	{ 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 };
+    com32sys_t ir, d0, d1, t0;
+    unsigned int c, y, mo, d, h, m, s;
+    uint32_t t;
+
+    memset(&ir, 0, sizeof ir);
+
+    ir.eax.b[1] = 0x04;
+    __intcall(0x1A, &ir, &d0);
+
+    ir.eax.b[1] = 0x02;
+    __intcall(0x1A, &ir, &t0);
+
+    ir.eax.b[1] = 0x04;
+    __intcall(0x1A, &ir, &d1);
+
+    if (t0.ecx.b[1] < 0x12)
+	d0 = d1;
+
+    c  = frombcd(d0.ecx.b[1]);
+    y  = frombcd(d0.ecx.b[0]);
+    mo = frombcd(d0.edx.b[1]);
+    d  = frombcd(d0.edx.b[0]);
+
+    h  = frombcd(t0.ecx.b[1]);
+    m  = frombcd(t0.ecx.b[0]);
+    s  = frombcd(t0.edx.b[1]);
+
+    /* We of course have no idea about the timezone, so ignore it */
+
+    /*
+     * Look for impossible dates... this code was written in 2010, so
+     * assume any century less than 20 is just broken.
+     */
+    if (c < 20)
+	c = 20;
+    y += c*100;
+
+    /* Consider Jan and Feb as the last months of the previous year */
+    if (mo < 3) {
+	y--;
+	mo += 12;
+    }
+
+    t = y*365 + y/4 - y/100 + y/400 + yday[mo-3] + d - 719469;
+    t *= 24;
+    t += h;
+    t *= 60;
+    t += m;
+    t *= 60;
+    t += s;
+
+    return t;
+}
diff --git a/com32/sysdump/ctime.h b/com32/sysdump/ctime.h
new file mode 100644
index 0000000..e646125
--- /dev/null
+++ b/com32/sysdump/ctime.h
@@ -0,0 +1,8 @@
+#ifndef CTIME_H
+#define CTIME_H
+
+#include <inttypes.h>
+
+uint32_t posix_time(void);
+
+#endif /* CTIME_H */
diff --git a/com32/sysdump/data.h b/com32/sysdump/data.h
index 697b1a3..deacf72 100644
--- a/com32/sysdump/data.h
+++ b/com32/sysdump/data.h
@@ -1,3 +1,2 @@
 #ifndef DATA_H
 #define DATA_H
-
diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c
index 1390d5c..d2475c5 100644
--- a/com32/sysdump/main.c
+++ b/com32/sysdump/main.c
@@ -20,6 +20,7 @@
 #include <console.h>
 #include <sys/cpu.h>
 #include "backend.h"
+#include "sysdump.h"
 
 const char *program = "sysdump";
 
@@ -149,14 +150,16 @@ int main(int argc, char *argv[])
     if (!be)
 	die("unknown backend");
 
-    if (cpio_init(be, argv+2))
+    if (cpio_init(be, (const char **)argv+2))
 	die("backend initialization error");
 
     if (lowmem) {
 	cpio_writefile(be, "lowmem.bin", lowmem, lowmem_len);
 	free(lowmem);
     }
-    
+
+    dump_vesa_tables(be);
+
     cpio_close(be);
 
     return 0;
diff --git a/com32/sysdump/srecsend.c b/com32/sysdump/srecsend.c
index 5ca92c6..6abe32a 100644
--- a/com32/sysdump/srecsend.c
+++ b/com32/sysdump/srecsend.c
@@ -18,7 +18,7 @@ static void make_srec(struct serial_if *sif, char type, size_t addr,
 
     p = buf;
     p += sprintf(p, "S%c%02X%0*zX", type, len+alen+1, alen, addr);
-    
+
     csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
     while (len) {
 	p += sprintf(p, "%02X", *dp);
@@ -55,7 +55,7 @@ void send_srec(struct serial_if *sif, struct file_info *fileinfo,
 	len -= bytes;
 
 	printf("Sending block %d...\r", blk);
-	
+
 	np = blk_buf;
 	while (bytes) {
 	    chunk = bytes > 32 ? 32 : bytes;
diff --git a/com32/sysdump/sysdump.h b/com32/sysdump/sysdump.h
new file mode 100644
index 0000000..04f35b5
--- /dev/null
+++ b/com32/sysdump/sysdump.h
@@ -0,0 +1,8 @@
+#ifndef SYSDUMP_H
+#define SYSDUMP_H
+
+struct backend;
+
+void dump_vesa_tables(struct backend *);
+
+#endif /* SYSDUMP_H */
diff --git a/com32/sysdump/vesa.c b/com32/sysdump/vesa.c
new file mode 100644
index 0000000..3d72093
--- /dev/null
+++ b/com32/sysdump/vesa.c
@@ -0,0 +1,56 @@
+#include <string.h>
+#include <stdio.h>
+#include "../lib/sys/vesa/vesa.h"
+#include "backend.h"
+#include "sysdump.h"
+
+void dump_vesa_tables(struct backend *be)
+{
+    com32sys_t rm;
+    struct vesa_general_info *gip, gi;
+    struct vesa_mode_info *mip, mi;
+    uint16_t mode, *mode_ptr;
+    char modefile[64];
+
+    /* Allocate space in the bounce buffer for these structures */
+    gip = &((struct vesa_info *)__com32.cs_bounce)->gi;
+    mip = &((struct vesa_info *)__com32.cs_bounce)->mi;
+
+    memset(&rm, 0, sizeof rm);
+    memset(gip, 0, sizeof *gip);
+
+    gip->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+    rm.eax.w[0] = 0x4F00;		/* Get SVGA general information */
+    rm.edi.w[0] = OFFS(gip);
+    rm.es = SEG(gip);
+    __intcall(0x10, &rm, &rm);
+    memcpy(&gi, gip, sizeof gi);
+
+    if (rm.eax.w[0] != 0x004F)
+	return;		/* Function call failed */
+    if (gi.signature != VESA_MAGIC)
+	return;		/* No magic */
+
+    cpio_mkdir(be, "vesa");
+
+    cpio_writefile(be, "vesa/global.bin", &gi, sizeof gi);
+
+    mode_ptr = GET_PTR(gi.video_mode_ptr);
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+	memset(mip, 0, sizeof *mip);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mip);
+	rm.es = SEG(mip);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	memcpy(&mi, mip, sizeof mi);
+
+	sprintf(modefile, "vesa/mode%04x.bin", mode);
+	cpio_writefile(be, modefile, &mi, sizeof mi);
+    }
+}
diff --git a/com32/sysdump/zout.c b/com32/sysdump/zout.c
index 27e6669..6ba6a5c 100644
--- a/com32/sysdump/zout.c
+++ b/com32/sysdump/zout.c
@@ -36,7 +36,7 @@ int write_data(struct backend *be, const void *buf, size_t len, bool flush)
 {
     int rv = Z_OK;
 
-    be->zstream.next_in = buf;
+    be->zstream.next_in = (void *)buf;
     be->zstream.avail_in = len;
 
     while (be->zstream.avail_in || (flush && rv == Z_OK)) {



More information about the Syslinux-commits mailing list