int (*open)(struct backend *, const char *argv[]);
int (*write)(struct backend *, const char *buf, size_t len);
-
+
z_stream zstream;
char *outbuf;
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);
ireg.ebx.w[0] = PXENV_UDP_WRITE;
ireg.es = SEG(uw);
ireg.edi.w[0] = OFFS(uw);
-
+
__intcall(0x22, &ireg, &oreg);
start = times(NULL);
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);
#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)
0, /* c_uid */
0, /* c_gid */
1, /* c_nlink */
- 0, /* c_mtime */
+ now, /* c_mtime */
datalen, /* c_filesize */
0, /* c_maj */
0, /* c_min */
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);
{
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);
}
{
return cpio_hdr(be, 0, 0, "TRAILER!!!", true);
}
-
--- /dev/null
+#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;
+}
--- /dev/null
+#ifndef CTIME_H
+#define CTIME_H
+
+#include <inttypes.h>
+
+uint32_t posix_time(void);
+
+#endif /* CTIME_H */
#ifndef DATA_H
#define DATA_H
-
#include <console.h>
#include <sys/cpu.h>
#include "backend.h"
+#include "sysdump.h"
const char *program = "sysdump";
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;
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);
len -= bytes;
printf("Sending block %d...\r", blk);
-
+
np = blk_buf;
while (bytes) {
chunk = bytes > 32 ? 32 : bytes;
--- /dev/null
+#ifndef SYSDUMP_H
+#define SYSDUMP_H
+
+struct backend;
+
+void dump_vesa_tables(struct backend *);
+
+#endif /* SYSDUMP_H */
--- /dev/null
+#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);
+ }
+}
{
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)) {