From 177148d253c6ca986ef94aa9b22ae377ddee828a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 6 Feb 2010 17:43:11 -0800 Subject: [PATCH] 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 --- 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(-) create mode 100644 com32/sysdump/ctime.c create mode 100644 com32/sysdump/ctime.h create mode 100644 com32/sysdump/sysdump.h create mode 100644 com32/sysdump/vesa.c 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 #include #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 +#include +#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 + +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 #include #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 +#include +#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)) { -- 2.7.4