summaryrefslogtreecommitdiff
path: root/com32/sysdump
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-06 17:43:11 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-06 17:44:29 -0800
commit177148d253c6ca986ef94aa9b22ae377ddee828a (patch)
tree5d17f72138a66d8dc6b1005fc6beecce14d0b9c8 /com32/sysdump
parent0f4c904b628adb906a3d534b5efa031071ec6b5e (diff)
downloadsyslinux-177148d253c6ca986ef94aa9b22ae377ddee828a.tar.gz
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@zytor.com>
Diffstat (limited to 'com32/sysdump')
-rw-r--r--com32/sysdump/backend.h4
-rw-r--r--com32/sysdump/backends.c1
-rw-r--r--com32/sysdump/be_tftp.c4
-rw-r--r--com32/sysdump/cpio.c15
-rw-r--r--com32/sysdump/ctime.c70
-rw-r--r--com32/sysdump/ctime.h8
-rw-r--r--com32/sysdump/data.h1
-rw-r--r--com32/sysdump/main.c7
-rw-r--r--com32/sysdump/srecsend.c4
-rw-r--r--com32/sysdump/sysdump.h8
-rw-r--r--com32/sysdump/vesa.c56
-rw-r--r--com32/sysdump/zout.c2
12 files changed, 165 insertions, 15 deletions
diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h
index eb6530e1..a83e3938 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 75f1d9d9..4d95dbb5 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 17275b16..9d945f3f 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 984ed3cf..79d01fc2 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 00000000..5af85666
--- /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 00000000..e6461253
--- /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 697b1a34..deacf721 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 1390d5c2..d2475c59 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 5ca92c60..6abe32a8 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 00000000..04f35b5e
--- /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 00000000..3d72093a
--- /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 27e6669b..6ba6a5ca 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)) {