aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-06-17 18:09:46 -0700
committerH. Peter Anvin <hpa@zytor.com>2010-06-17 18:09:46 -0700
commite554f2fadd8d7a79a0f84707e545c31997c93528 (patch)
tree0093dfbecdb34541617abc1f0157578b08588f75
parent53b3ca9c57fd6fc66738ae0157c77432b22bf3a9 (diff)
parentf23e586f898704626b4db5287a1c70cdfb11af5d (diff)
downloadsyslinux-e554f2fadd8d7a79a0f84707e545c31997c93528.tar.gz
syslinux-e554f2fadd8d7a79a0f84707e545c31997c93528.tar.xz
syslinux-e554f2fadd8d7a79a0f84707e545c31997c93528.zip
Merge branch 'pathbased' of ssh://terminus.zytor.com/pub/git/syslinux/syslinux into pathbased
-rw-r--r--com32/modules/ifcpu.c9
-rw-r--r--com32/modules/ifcpu64.c9
-rw-r--r--dosutil/eltorito.asm8
-rw-r--r--dosutil/mdiskchk.c249
-rw-r--r--dosutil/mdiskchk.combin7273 -> 8184 bytes
-rw-r--r--memdisk/acpi.h3
-rw-r--r--memdisk/eltorito.h28
-rw-r--r--memdisk/memdisk.h4
-rw-r--r--memdisk/memdisk.inc8
-rw-r--r--memdisk/mstructs.h183
-rw-r--r--memdisk/setup.c199
11 files changed, 489 insertions, 211 deletions
diff --git a/com32/modules/ifcpu.c b/com32/modules/ifcpu.c
index 8a9a5f4f..1e57f088 100644
--- a/com32/modules/ifcpu.c
+++ b/com32/modules/ifcpu.c
@@ -71,20 +71,23 @@ static unsigned char sleep(unsigned int msec)
/* XXX: this really should be librarized */
static void boot_args(char **args)
{
- int len = 0;
+ int len = 0, a = 0;
char **pp;
const char *p;
char c, *q, *str;
for (pp = args; *pp; pp++)
- len += strlen(*pp);
+ len += strlen(*pp) + 1;
- q = str = alloca(len + 1);
+ q = str = alloca(len);
for (pp = args; *pp; pp++) {
p = *pp;
while ((c = *p++))
*q++ = c;
+ *q++ = ' ';
+ a = 1;
}
+ q -= a;
*q = '\0';
if (!str[0])
diff --git a/com32/modules/ifcpu64.c b/com32/modules/ifcpu64.c
index 6d566a25..e123922e 100644
--- a/com32/modules/ifcpu64.c
+++ b/com32/modules/ifcpu64.c
@@ -73,20 +73,23 @@ static bool __constfunc cpu_has_feature(int x)
/* XXX: this really should be librarized */
static void boot_args(char **args)
{
- int len = 0;
+ int len = 0, a = 0;
char **pp;
const char *p;
char c, *q, *str;
for (pp = args; *pp; pp++)
- len += strlen(*pp);
+ len += strlen(*pp) + 1;
- q = str = alloca(len + 1);
+ q = str = alloca(len);
for (pp = args; *pp; pp++) {
p = *pp;
while ((c = *p++))
*q++ = c;
+ *q++ = ' ';
+ a = 1;
}
+ q -= a;
*q = '\0';
if (!str[0])
diff --git a/dosutil/eltorito.asm b/dosutil/eltorito.asm
index eabda126..96cfd9ba 100644
--- a/dosutil/eltorito.asm
+++ b/dosutil/eltorito.asm
@@ -1029,7 +1029,7 @@ SpecGo: mov si,SpecPkt
ScanDrives: push ax ; at df3 in 1.4
push si
- mov dl, 0ffh ;Start at Drive 0xff
+ mov dl, 80h ;Start at Drive 0x80
NextDrv: mov ax,4B01h ;Get Bootable CD-ROM Status
mov BYTE [SpecPkt],0 ;Clear 1st byte of SpecPkt
call SpecGo
@@ -1044,9 +1044,9 @@ NextDrv: mov ax,4B01h ;Get Bootable CD-ROM Status
ja FindFail ; in 1.4 at e16
jmp short SendFound ; in 1.4 at e26
-FindFail: dec dl ;Next drive
- cmp dl, 80h
- jb SendFail ; Check from ffh..80h
+FindFail: inc dl ;Next drive
+ cmp dl, 0ffh
+ jb SendFail ; Check from 80h..ffh
jmp short NextDrv
SendFail: xor dl,dl
stc
diff --git a/dosutil/mdiskchk.c b/dosutil/mdiskchk.c
index 42aa5119..ddc57632 100644
--- a/dosutil/mdiskchk.c
+++ b/dosutil/mdiskchk.c
@@ -1,6 +1,7 @@
/* -*- c -*- ------------------------------------------------------------- *
*
* Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ * Portions copyright 2010 Shao Miller
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +22,7 @@
* wcl -3 -osx -mt mdiskchk.c
*/
+#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <i86.h> /* For MK_FP() */
@@ -29,18 +31,15 @@ typedef unsigned long uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
+/* OpenWatcom uses a packed structure prefix */
+#define MEMDISK_PACKED_PREFIX _Packed
+#define MEMDISK_PACKED_POSTFIX
+
+/* Pull in MEMDISK common structures */
+#include "../memdisk/mstructs.h"
+
struct memdiskinfo {
- uint16_t bytes; /* Bytes from memdisk */
- uint16_t version; /* Memdisk version */
- uint32_t base; /* Base of disk in high memory */
- uint32_t size; /* Size of disk in sectors */
- char far *cmdline; /* Command line */
- void far *oldint13; /* Old INT 13h */
- void far *oldint15; /* Old INT 15h */
- uint16_t olddosmem;
- uint8_t bootloaderid;
-
- uint8_t _pad;
+ struct mdi mdi;
/* We add our own fields at the end */
int cylinders;
@@ -121,25 +120,233 @@ const char *bootloadername(uint8_t id)
}
}
+/* The function type for an output function */
+#define OUTPUT_FUNC_DECL(x) \
+void x(const int d, const struct memdiskinfo * const m)
+typedef OUTPUT_FUNC_DECL((*output_func));
+
+/* Show MEMDISK information for the passed structure */
+static OUTPUT_FUNC_DECL(normal_output)
+{
+ if (m == NULL)
+ return;
+ printf("Drive %02X is MEMDISK %u.%02u:\n"
+ "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n"
+ "\tloader = 0x%02x (%s),\n"
+ "\tcmdline = %Fs\n",
+ d, m->mdi.version_major, m->mdi.version_minor,
+ m->mdi.diskbuf, m->mdi.disksize, m->cylinders, m->heads, m->sectors,
+ m->mdi.bootloaderid, bootloadername(m->mdi.bootloaderid),
+ MK_FP(m->mdi.cmdline.seg_off.segment,
+ m->mdi.cmdline.seg_off.offset));
+}
+
+/* Yield DOS SET command(s) as output for each MEMDISK kernel argument */
+static OUTPUT_FUNC_DECL(batch_output)
+{
+ if (m != NULL) {
+ char buf[256], *bc;
+ const char far *c =
+ MK_FP(m->mdi.cmdline.seg_off.segment,
+ m->mdi.cmdline.seg_off.offset);
+ const char *have_equals, is_set[] = "=1";
+
+ while (*c != '\0') {
+ /* Skip whitespace */
+ while (isspace(*c))
+ c++;
+ if (*c == '\0')
+ /* Trailing whitespace. That's enough processing */
+ break;
+ /* Walk the kernel arguments while filling the buffer,
+ * looking for space or NUL or checking for a full buffer
+ */
+ bc = buf;
+ have_equals = is_set;
+ while ((*c != '\0') && !isspace(*c) &&
+ (bc < &buf[sizeof(buf) - 1])) {
+ /* Check if the param is "x=y" */
+ if (*c == '=')
+ /* "=1" not needed */
+ have_equals = &is_set[sizeof(is_set) - 1];
+ *bc = *c;
+ c++;
+ bc++;
+ }
+ /* Found the end of the parameter and optional value sequence */
+ *bc = '\0';
+ printf("set %s%s\n", buf, have_equals);
+ }
+ }
+}
+
+/* We do not output batch file output by default. We show MEMDISK info */
+static output_func show_memdisk = normal_output;
+
+/* A generic function type */
+#define MDISKCHK_FUNC_DECL(x) \
+void x(void)
+typedef MDISKCHK_FUNC_DECL((*mdiskchk_func));
+
+static MDISKCHK_FUNC_DECL(do_nothing)
+{
+ return;
+}
+
+static MDISKCHK_FUNC_DECL(show_usage)
+{
+ printf("\nUsage: mdiskchk [--safe-hooks] [--mbfts] [--batch-output]\n"
+ "\n"
+ "Action: --safe-hooks . . Will scan INT 13h \"safe hook\" chain\n"
+ " --mbfts . . . . Will scan memory for MEMDISK mBFTs\n"
+ " --batch-output . Will output SET command output based\n"
+ " on MEMDISK kernel arguments\n");
+}
+
+/* Search memory for mBFTs and report them via the output method */
+static MDISKCHK_FUNC_DECL(show_mbfts)
+{
+ const uint16_t far * const free_base_mem =
+ MK_FP(0x0040, 0x0013);
+ int seg;
+ uint8_t chksum;
+ uint32_t i;
+ const struct mBFT far *mbft;
+ struct memdiskinfo m;
+ struct patch_area far *patch_area;
+
+ for (seg = *free_base_mem / 16; seg < 0x9FFF; seg++) {
+ mbft = MK_FP(seg, 0);
+ /* Check for signature */
+ if (mbft->acpi.signature[0] != 'm' ||
+ mbft->acpi.signature[1] != 'B' ||
+ mbft->acpi.signature[2] != 'F' ||
+ mbft->acpi.signature[3] != 'T')
+ continue;
+ if (mbft->acpi.length != sizeof(struct mBFT))
+ continue;
+ /* Check sum */
+ chksum = 0;
+ for (i = 0; i < sizeof(struct mBFT); i++)
+ chksum += ((const uint8_t far *)mbft)[i];
+ if (chksum)
+ continue;
+ /* Copy the MDI from the mBFT */
+ _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi));
+ /* Adjust C/H/S since we actually know
+ * it directly for any MEMDISK with an mBFT
+ */
+ patch_area = (struct patch_area far *)&mbft->mdi;
+ m.cylinders = patch_area->cylinders;
+ m.heads = patch_area->heads;
+ m.sectors = patch_area->sectors;
+ show_memdisk(patch_area->driveno, &m);
+ }
+}
+
+/* Walk the "safe hook" chain as far as possible
+ * and report MEMDISKs that we find via the output method
+ */
+static MDISKCHK_FUNC_DECL(show_safe_hooks)
+{
+ const real_addr_t far * const int13 =
+ MK_FP(0x0000, 0x0013 * sizeof(real_addr_t));
+ const struct safe_hook far *hook =
+ MK_FP(int13->seg_off.segment, int13->seg_off.offset);
+
+ while ((hook->signature[0] == '$') &&
+ (hook->signature[1] == 'I') &&
+ (hook->signature[2] == 'N') &&
+ (hook->signature[3] == 'T') &&
+ (hook->signature[4] == '1') &&
+ (hook->signature[5] == '3') &&
+ (hook->signature[6] == 'S') &&
+ (hook->signature[7] == 'F')) {
+ /* Found a valid "safe hook" */
+ if ((hook->vendor[0] == 'M') &&
+ (hook->vendor[1] == 'E') &&
+ (hook->vendor[2] == 'M') &&
+ (hook->vendor[3] == 'D') &&
+ (hook->vendor[4] == 'I') &&
+ (hook->vendor[5] == 'S') &&
+ (hook->vendor[6] == 'K')) {
+ /* Found a valid MEMDISK "safe hook". It will have an mBFT */
+ const struct mBFT far *mbft;
+ struct memdiskinfo m;
+ struct patch_area far *patch_area;
+
+ /* Copy the MDI from the mBFT. Offset is a misnomer here */
+ mbft = MK_FP(hook->mBFT.offset >> 4, 0); /* Always aligned */
+ _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi));
+ /* Adjust C/H/S since we actually know
+ * it directly for any MEMDISK with an mBFT
+ */
+ patch_area = (struct patch_area far *)&mbft->mdi;
+ m.cylinders = patch_area->cylinders;
+ m.heads = patch_area->heads;
+ m.sectors = patch_area->sectors;
+ show_memdisk(patch_area->driveno, &m);
+ } /* if */
+ /* Step to the next hook in the "safe hook" chain */
+ hook = MK_FP(hook->old_hook.seg_off.segment,
+ hook->old_hook.seg_off.offset);
+ } /* while */
+}
+
int main(int argc, char *argv[])
{
int d;
int found = 0;
- struct memdiskinfo *m;
+ const struct memdiskinfo *m;
+ /* Default behaviour */
+ mdiskchk_func usage = do_nothing,
+ safe_hooks = do_nothing,
+ mbfts = do_nothing;
+
+ /* For each argument */
+ while (--argc) {
+ /* Argument should begin with one of these chars */
+ if ((*argv[argc] != '/') && (*argv[argc] != '-')) {
+ /* It doesn't. Print usage soon */
+ usage = show_usage;
+ break;
+ }
+ argv[argc]++;
+
+ /* Next char might be '-' as in "--safe-hooks" */
+ if (*argv[argc] == '-')
+ argv[argc]++;
+
+ switch (*argv[argc]) {
+ case 'S':
+ case 's':
+ safe_hooks = show_safe_hooks;
+ break;
+ case 'M':
+ case 'm':
+ mbfts = show_mbfts;
+ break;
+ case 'B':
+ case 'b':
+ show_memdisk = batch_output;
+ break;
+ default:
+ usage = show_usage;
+ } /* switch */
+ } /* while */
+
+ safe_hooks();
+ mbfts();
for (d = 0; d <= 0xff; d++) {
- if ((m = query_memdisk(d)) != NULL) {
- printf("Drive %02X is MEMDISK %u.%02u:\n"
- "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n"
- "\tloader = 0x%02x (%s),\n"
- "\tcmdline = %Fs\n",
- d, m->version >> 8, m->version & 0xff,
- m->base, m->size, m->cylinders, m->heads, m->sectors,
- m->bootloaderid, bootloadername(m->bootloaderid),
- m->cmdline);
+ m = query_memdisk(d);
+ if (m != NULL) {
found++;
+ show_memdisk(d, m);
}
}
+ usage();
return found;
}
+
diff --git a/dosutil/mdiskchk.com b/dosutil/mdiskchk.com
index 78257519..5a6cc8e7 100644
--- a/dosutil/mdiskchk.com
+++ b/dosutil/mdiskchk.com
Binary files differ
diff --git a/memdisk/acpi.h b/memdisk/acpi.h
index 630c5f57..732d116a 100644
--- a/memdisk/acpi.h
+++ b/memdisk/acpi.h
@@ -31,6 +31,7 @@
* This is the structure common to the start of all ACPI system
* description tables.
*/
+MEMDISK_PACKED_PREFIX
struct acpi_description_header {
/** ACPI signature (4 ASCII characters) */
char signature[4];
@@ -50,5 +51,5 @@ struct acpi_description_header {
char asl_compiler_id[4];
/** ASL compiler revision number */
uint32_t asl_compiler_revision;
-} __attribute__ (( packed ));
+} MEMDISK_PACKED_POSTFIX;
diff --git a/memdisk/eltorito.h b/memdisk/eltorito.h
index 7d46e1d9..27b570da 100644
--- a/memdisk/eltorito.h
+++ b/memdisk/eltorito.h
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2009 Shao Miller - All Rights Reserved
+ * Copyright 2009-2010 Shao Miller - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,17 +18,8 @@
#include <stdint.h>
-/*
- * Uncomment for El Torito debugging
- *
- * #define DBG_ELTORITO 1
- */
-
-#ifdef DBG_ELTORITO
-extern void eltorito_dump(uint32_t);
-#endif
-
/* EDD-4 Bootable Optical Disc Drive Boot Volume Descriptor */
+MEMDISK_PACKED_PREFIX
struct edd4_bvd {
uint8_t boot_rec_ind; /* Boot Record Indicator */
uint8_t iso9660_id[5]; /* ISO9660 ID */
@@ -37,8 +28,9 @@ struct edd4_bvd {
uint8_t res1[32]; /* Reserved */
uint32_t boot_cat; /* Boot catalog sector */
uint8_t res2[1973]; /* Reserved */
-} __attribute__ ((packed));
+} MEMDISK_PACKED_POSTFIX;
+MEMDISK_PACKED_PREFIX
struct validation_entry {
uint8_t header_id; /* Header ID */
uint8_t platform_id; /* Platform ID */
@@ -47,8 +39,9 @@ struct validation_entry {
uint16_t checksum; /* Sums with whole record to zero */
uint8_t key55; /* Key byte 0x55 */
uint8_t keyAA; /* Key byte 0xAA */
-} __attribute__ ((packed));
+} MEMDISK_PACKED_POSTFIX;
+MEMDISK_PACKED_PREFIX
struct initial_entry {
uint8_t header_id; /* Header ID */
uint8_t media_type; /* Media type */
@@ -58,15 +51,17 @@ struct initial_entry {
uint16_t sect_count; /* Emulated sectors to load */
uint32_t load_block; /* Starting sector of image */
uint8_t res2[4]; /* Reserved */
-} __attribute__ ((packed));
+} MEMDISK_PACKED_POSTFIX;
/* EDD-4 Bootable Optical Disc Drive Boot Catalog (fixed-size portions) */
+MEMDISK_PACKED_PREFIX
struct edd4_bootcat {
struct validation_entry validation_entry;
struct initial_entry initial_entry;
-} __attribute__ ((packed));
+} MEMDISK_PACKED_POSTFIX;
/* EDD-4 CD Specification Packet */
+MEMDISK_PACKED_PREFIX
struct edd4_cd_pkt {
uint8_t size; /* Packet size */
uint8_t type; /* Boot media type (flags) */
@@ -80,4 +75,5 @@ struct edd4_cd_pkt {
uint8_t geom1; /* Cylinders bits 0 thru 7 */
uint8_t geom2; /* Sects/track 0 thru 5, cyls 8, 9 */
uint8_t geom3; /* Heads */
-} __attribute__ ((packed));
+} MEMDISK_PACKED_POSTFIX;
+
diff --git a/memdisk/memdisk.h b/memdisk/memdisk.h
index b6b277a8..af40823a 100644
--- a/memdisk/memdisk.h
+++ b/memdisk/memdisk.h
@@ -134,4 +134,8 @@ extern int check_zip(void *indata, uint32_t size, uint32_t * zbytes_p,
extern void *unzip(void *indata, uint32_t zbytes, uint32_t dbytes,
uint32_t orig_crc, void *target);
+/* Structure packing can be different for different compilers */
+#define MEMDISK_PACKED_PREFIX
+#define MEMDISK_PACKED_POSTFIX __attribute__ (( packed ))
+
#endif
diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc
index e1a0901b..90e6ef9f 100644
--- a/memdisk/memdisk.inc
+++ b/memdisk/memdisk.inc
@@ -119,7 +119,7 @@
; must be first in the binary
Pointers: dw Int13Start
dw Int15Start
- dw PatchArea
+ dw MemDisk_Info ; Portions are patched by installer
dw TotalSize
dw IretPtr
@@ -1076,12 +1076,11 @@ mBFT:
; Note that the above ends on a DWORD boundary.
; The MDI has always started at such a boundary.
+; Portions of the MDI are patched by the installer
MemDisk_Info equ $ ; Pointed to by installation check
MDI_Bytes dw MDI_Len ; Total bytes in MDI structure
MDI_Version db VERSION_MINOR, VERSION_MAJOR ; MEMDISK version
-PatchArea equ $ ; This gets filled in by the installer
-
DiskBuf dd 0 ; Linear address of high memory disk
DiskSize dd 0 ; Size of disk in blocks
CommandLine dw 0, 0 ; Far pointer to saved command line
@@ -1171,7 +1170,8 @@ CD_PKT:
%endif ; EDD
- ; End patch area
+; End patch area
+
alignb 4, db 0
Stack dd 0 ; Saved SS:ESP on invocation
dw 0
diff --git a/memdisk/mstructs.h b/memdisk/mstructs.h
new file mode 100644
index 00000000..e060aceb
--- /dev/null
+++ b/memdisk/mstructs.h
@@ -0,0 +1,183 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ * Portions copyright 2009-2010 Shao Miller
+ * [El Torito code, mBFT, "safe hook"]
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/* These structures are common to MEMDISK and MDISKCHK.COM */
+
+#include <stdint.h>
+
+struct seg_off {
+ uint16_t offset;
+ uint16_t segment;
+};
+
+typedef union {
+ struct seg_off seg_off;
+ uint32_t uint32;
+} real_addr_t;
+
+/* Forward declaration */
+struct mBFT;
+
+MEMDISK_PACKED_PREFIX
+struct safe_hook {
+ uint8_t jump[3]; /* Max. three bytes for jump */
+ uint8_t signature[8]; /* "$INT13SF" */
+ uint8_t vendor[8]; /* "MEMDISK " */
+ real_addr_t old_hook; /* SEG:OFF for previous INT 13h hook */
+ uint32_t flags; /* "Safe hook" flags */
+ /* The next field is a MEMDISK extension to the "safe hook" structure */
+ union {
+ uint32_t offset; /* Offset from hook to the mBFT; refilled */
+ struct mBFT *ptr; /* by setup() with the physical address */
+ } mBFT;
+} MEMDISK_PACKED_POSTFIX;
+
+struct memdisk_header {
+ uint16_t int13_offs;
+ uint16_t int15_offs;
+ uint16_t patch_offs;
+ uint16_t total_size;
+ uint16_t iret_offs;
+ struct safe_hook safe_hook;
+};
+
+MEMDISK_PACKED_PREFIX
+/* EDD disk parameter table */
+struct edd_dpt {
+ uint16_t len; /* Length of table */
+ uint16_t flags; /* Information flags */
+ uint32_t c; /* Physical cylinders (count!) */
+ uint32_t h; /* Physical heads (count!) */
+ uint32_t s; /* Physical sectors/track (count!) */
+ uint64_t sectors; /* Total sectors */
+ uint16_t bytespersec; /* Bytes/sector */
+ real_addr_t dpte; /* DPTE pointer */
+ uint16_t dpikey; /* Device Path Info magic */
+ uint8_t dpilen; /* Device Path Info length */
+ uint8_t res1; /* Reserved */
+ uint16_t res2; /* Reserved */
+ uint8_t bustype[4]; /* Host bus type */
+ uint8_t inttype[8]; /* Interface type */
+ uint64_t intpath; /* Interface path */
+ uint64_t devpath[2]; /* Device path (double QuadWord!) */
+ uint8_t res3; /* Reserved */
+ uint8_t chksum; /* DPI checksum */
+} MEMDISK_PACKED_POSTFIX;
+
+/* Requirement for struct edd4_cd_pkt */
+#include "../memdisk/eltorito.h"
+
+/* Official MEMDISK Info structure ("MDI") */
+MEMDISK_PACKED_PREFIX
+struct mdi {
+ const uint16_t bytes;
+ const uint8_t version_minor;
+ const uint8_t version_major;
+
+ uint32_t diskbuf;
+ uint32_t disksize;
+ real_addr_t cmdline;
+
+ real_addr_t oldint13;
+ real_addr_t oldint15;
+
+ uint16_t olddosmem;
+ uint8_t bootloaderid;
+ uint8_t _pad1;
+
+ uint16_t dpt_ptr;
+} MEMDISK_PACKED_POSTFIX;
+
+/* Requirement for struct acpi_description_header */
+#include "../memdisk/acpi.h"
+
+MEMDISK_PACKED_PREFIX
+struct mBFT {
+ struct acpi_description_header acpi;
+ union {
+ struct safe_hook *ptr;
+ uint32_t phys_addr;
+ } safe_hook; /* "Safe hook" physical address */
+ struct mdi mdi;
+} MEMDISK_PACKED_POSTFIX;
+
+/* The Disk Parameter Table may be required */
+typedef union {
+ struct hd_dpt {
+ uint16_t max_cyl; /* Max cylinder */
+ uint8_t max_head; /* Max head */
+ uint8_t junk1[5]; /* Obsolete junk, leave at zero */
+ uint8_t ctrl; /* Control byte */
+ uint8_t junk2[7]; /* More obsolete junk */
+ } hd;
+ struct fd_dpt {
+ uint8_t specify1; /* "First specify byte" */
+ uint8_t specify2; /* "Second specify byte" */
+ uint8_t delay; /* Delay until motor turn off */
+ uint8_t sectors; /* Sectors/track */
+
+ uint8_t bps; /* Bytes/sector (02h = 512) */
+ uint8_t isgap; /* Length of intersector gap */
+ uint8_t dlen; /* Data length (0FFh) */
+ uint8_t fgap; /* Formatting gap */
+
+ uint8_t ffill; /* Format fill byte */
+ uint8_t settle; /* Head settle time (ms) */
+ uint8_t mstart; /* Motor start time */
+ uint8_t maxtrack; /* Maximum track number */
+
+ uint8_t rate; /* Data transfer rate */
+ uint8_t cmos; /* CMOS type */
+ uint8_t pad[2];
+
+ uint32_t old_fd_dpt; /* Extension: pointer to old INT 1Eh */
+ } fd;
+} dpt_t;
+
+MEMDISK_PACKED_PREFIX
+struct patch_area {
+ struct mdi mdi;
+
+ uint8_t driveshiftlimit; /* Do not shift drives above this region */
+ uint8_t _pad2; /* Pad to DWORD */
+ uint16_t _pad3; /* Pad to QWORD */
+
+ uint16_t memint1588;
+
+ uint16_t cylinders;
+ uint16_t heads;
+ uint32_t sectors;
+
+ uint32_t mem1mb;
+ uint32_t mem16mb;
+
+ uint8_t driveno;
+ uint8_t drivetype;
+ uint8_t drivecnt;
+ uint8_t configflags;
+
+#define CONFIG_READONLY 0x01
+#define CONFIG_RAW 0x02
+#define CONFIG_SAFEINT 0x04
+#define CONFIG_BIGRAW 0x08 /* MUST be 8! */
+#define CONFIG_MODEMASK 0x0e
+
+ uint16_t mystack;
+ uint16_t statusptr;
+
+ dpt_t dpt;
+ struct edd_dpt edd_dpt;
+ struct edd4_cd_pkt cd_pkt; /* Only really in a memdisk_iso_* hook */
+} MEMDISK_PACKED_POSTFIX;
diff --git a/memdisk/setup.c b/memdisk/setup.c
index db1c4bcf..ffaa2c66 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -14,11 +14,9 @@
* ----------------------------------------------------------------------- */
#include <stdint.h>
-#include "acpi.h"
#include "bda.h"
#include "dskprobe.h"
#include "e820.h"
-#include "eltorito.h"
#include "conio.h"
#include "version.h"
#include "memdisk.h"
@@ -41,131 +39,8 @@ extern const char _binary_memdisk_iso_2048_bin_start[];
extern const char _binary_memdisk_iso_2048_bin_end[];
extern const char _binary_memdisk_iso_2048_bin_size[];
-struct memdisk_header {
- uint16_t int13_offs;
- uint16_t int15_offs;
- uint16_t patch_offs;
- uint16_t total_size;
- uint16_t iret_offs;
-};
-
-struct safe_hook {
- uint8_t jump[3]; /* Max. three bytes for jump */
- uint8_t signature[8]; /* "$INT13SF" */
- uint8_t vendor[8]; /* "MEMDISK " */
- uint32_t old_hook; /* SEG:OFF for previous INT 13h hook */
- uint32_t flags; /* "Safe hook" flags */
- /* The next field is a MEMDISK extension to the "safe hook" structure */
- uint32_t mBFT; /* Offset from hook to the mBFT; refilled
- * by setup() with the physical address
- */
-} __attribute__((packed));
-
-/* The Disk Parameter Table may be required */
-typedef union {
- struct hd_dpt {
- uint16_t max_cyl; /* Max cylinder */
- uint8_t max_head; /* Max head */
- uint8_t junk1[5]; /* Obsolete junk, leave at zero */
- uint8_t ctrl; /* Control byte */
- uint8_t junk2[7]; /* More obsolete junk */
- } hd;
- struct fd_dpt {
- uint8_t specify1; /* "First specify byte" */
- uint8_t specify2; /* "Second specify byte" */
- uint8_t delay; /* Delay until motor turn off */
- uint8_t sectors; /* Sectors/track */
-
- uint8_t bps; /* Bytes/sector (02h = 512) */
- uint8_t isgap; /* Length of intersector gap */
- uint8_t dlen; /* Data length (0FFh) */
- uint8_t fgap; /* Formatting gap */
-
- uint8_t ffill; /* Format fill byte */
- uint8_t settle; /* Head settle time (ms) */
- uint8_t mstart; /* Motor start time */
- uint8_t maxtrack; /* Maximum track number */
-
- uint8_t rate; /* Data transfer rate */
- uint8_t cmos; /* CMOS type */
- uint8_t pad[2];
-
- uint32_t old_fd_dpt; /* Extension: pointer to old INT 1Eh */
- } fd;
-} dpt_t;
-
-/* EDD disk parameter table */
-struct edd_dpt {
- uint16_t len; /* Length of table */
- uint16_t flags; /* Information flags */
- uint32_t c; /* Physical cylinders (count!) */
- uint32_t h; /* Physical heads (count!) */
- uint32_t s; /* Physical sectors/track (count!) */
- uint64_t sectors; /* Total sectors */
- uint16_t bytespersec; /* Bytes/sector */
- uint16_t dpte_off, dpte_seg; /* DPTE pointer */
- uint16_t dpikey; /* Device Path Info magic */
- uint8_t dpilen; /* Device Path Info length */
- uint8_t res1; /* Reserved */
- uint16_t res2; /* Reserved */
- uint8_t bustype[4]; /* Host bus type */
- uint8_t inttype[8]; /* Interface type */
- uint64_t intpath; /* Interface path */
- uint64_t devpath[2]; /* Device path (double QuadWord!) */
- uint8_t res3; /* Reserved */
- uint8_t chksum; /* DPI checksum */
-} __attribute__((packed));
-
-struct mBFT {
- struct acpi_description_header acpi;
- uint32_t safe_hook; /* "Safe hook" physical address */
-} __attribute__((packed));
-
-struct patch_area {
- uint32_t diskbuf;
- uint32_t disksize;
- uint16_t cmdline_off, cmdline_seg;
-
- uint32_t oldint13;
- uint32_t oldint15;
-
- uint16_t olddosmem;
- uint8_t bootloaderid;
- uint8_t _pad1;
-
- uint16_t dpt_ptr;
- /* End of the official MemDisk_Info */
- uint8_t driveshiftlimit; /* Do not shift drives above this region */
- uint8_t _pad2; /* Pad to DWORD */
- uint16_t _pad3; /* Pad to QWORD */
-
- uint16_t memint1588;
-
- uint16_t cylinders;
- uint16_t heads;
- uint32_t sectors;
-
- uint32_t mem1mb;
- uint32_t mem16mb;
-
- uint8_t driveno;
- uint8_t drivetype;
- uint8_t drivecnt;
- uint8_t configflags;
-
-#define CONFIG_READONLY 0x01
-#define CONFIG_RAW 0x02
-#define CONFIG_SAFEINT 0x04
-#define CONFIG_BIGRAW 0x08 /* MUST be 8! */
-#define CONFIG_MODEMASK 0x0e
-
- uint16_t mystack;
- uint16_t statusptr;
-
- dpt_t dpt;
- struct edd_dpt edd_dpt;
- struct edd4_cd_pkt cd_pkt; /* Only really in a memdisk_iso_* hook */
-} __attribute__((packed));
+/* Pull in structures common to MEMDISK and MDISKCHK.COM */
+#include "mstructs.h"
/* An EDD disk packet */
struct edd_dsk_pkt {
@@ -177,6 +52,13 @@ struct edd_dsk_pkt {
uint64_t buf64; /* 64-bit buf pointer */
} __attribute__ ((packed));
+/* Change to 1 for El Torito debugging */
+#define DBG_ELTORITO 0
+
+#if DBG_ELTORITO
+extern void eltorito_dump(uint32_t);
+#endif
+
/*
* Routine to seek for a command-line item and return a pointer
* to the data portion, if present
@@ -454,7 +336,7 @@ static const struct geometry *get_disk_image_geometry(uint32_t where,
hd_geometry.offset = offset;
if ((p = getcmditem("iso")) != CMD_NOTFOUND) {
-#ifdef DBG_ELTORITO
+#if DBG_ELTORITO
eltorito_dump(where);
#endif
struct edd4_bvd *bvd = (struct edd4_bvd *)(where + 17 * 2048);
@@ -835,7 +717,6 @@ void setup(const struct real_mode_args *rm_args_ptr)
unsigned int bin_size;
char *memdisk_hook;
struct memdisk_header *hptr;
- struct safe_hook *safe_hook;
struct patch_area *pptr;
uint16_t driverseg;
uint32_t driverptr, driveraddr;
@@ -919,11 +800,10 @@ void setup(const struct real_mode_args *rm_args_ptr)
/* Figure out where it needs to go */
hptr = (struct memdisk_header *)memdisk_hook;
- safe_hook = (struct safe_hook *)(memdisk_hook + hptr->int13_offs);
pptr = (struct patch_area *)(memdisk_hook + hptr->patch_offs);
dosmem_k = rdz_16(BIOS_BASEMEM);
- pptr->olddosmem = dosmem_k;
+ pptr->mdi.olddosmem = dosmem_k;
stddosmem = dosmem_k << 10;
/* If INT 15 E820 and INT 12 disagree, go with the most conservative */
if (stddosmem > dos_mem)
@@ -934,11 +814,11 @@ void setup(const struct real_mode_args *rm_args_ptr)
pptr->cylinders = geometry->c; /* Possible precision loss */
pptr->heads = geometry->h;
pptr->sectors = geometry->s;
- pptr->disksize = geometry->sectors;
- pptr->diskbuf = ramdisk_image + geometry->offset;
+ pptr->mdi.disksize = geometry->sectors;
+ pptr->mdi.diskbuf = ramdisk_image + geometry->offset;
pptr->statusptr = (geometry->driveno & 0x80) ? 0x474 : 0x441;
- pptr->bootloaderid = shdr->type_of_loader;
+ pptr->mdi.bootloaderid = shdr->type_of_loader;
pptr->configflags = CONFIG_SAFEINT; /* Default */
/* Set config flags */
@@ -1040,7 +920,7 @@ void setup(const struct real_mode_args *rm_args_ptr)
pptr->edd_dpt.flags |= 0x0014;
}
- pptr->edd_dpt.devpath[0] = pptr->diskbuf;
+ pptr->edd_dpt.devpath[0] = pptr->mdi.diskbuf;
pptr->edd_dpt.chksum = -checksum_buf(&pptr->edd_dpt.dpikey, 73 - 30);
}
@@ -1109,8 +989,8 @@ void setup(const struct real_mode_args *rm_args_ptr)
/* Anything beyond the end is for the stack */
pptr->mystack = (uint16_t) (stddosmem - driveraddr);
- pptr->oldint13 = rdz_32(BIOS_INT13);
- pptr->oldint15 = rdz_32(BIOS_INT15);
+ pptr->mdi.oldint13.uint32 = rdz_32(BIOS_INT13);
+ pptr->mdi.oldint15.uint32 = rdz_32(BIOS_INT15);
/* Adjust the E820 table: if there are null ranges (type 0)
at the end, change them to type end of list (-1).
@@ -1125,7 +1005,7 @@ void setup(const struct real_mode_args *rm_args_ptr)
bios_drives = 0;
pptr->drivecnt = 0;
no_bpt = 1;
- pptr->oldint13 = driverptr + hptr->iret_offs;
+ pptr->mdi.oldint13.uint32 = driverptr + hptr->iret_offs;
wrz_8(BIOS_EQUIP, rdz_8(BIOS_EQUIP) & ~0xc1);
wrz_8(BIOS_HD_COUNT, 0);
} else if (getcmditem("nopass") != CMD_NOTFOUND) {
@@ -1173,9 +1053,6 @@ void setup(const struct real_mode_args *rm_args_ptr)
}
}
- /* Note the previous INT 13h hook in the "safe hook" structure */
- safe_hook->old_hook = pptr->oldint13;
-
/* Add ourselves to the drive count */
pptr->drivecnt++;
@@ -1191,8 +1068,8 @@ void setup(const struct real_mode_args *rm_args_ptr)
pptr->driveshiftlimit);
/* Pointer to the command line */
- pptr->cmdline_off = bin_size + (nranges + 1) * sizeof(ranges[0]);
- pptr->cmdline_seg = driverseg;
+ pptr->mdi.cmdline.seg_off.offset = bin_size + (nranges + 1) * sizeof(ranges[0]);
+ pptr->mdi.cmdline.seg_off.segment = driverseg;
/* Copy driver followed by E820 table followed by command line */
{
@@ -1200,7 +1077,6 @@ void setup(const struct real_mode_args *rm_args_ptr)
/* Adjust these pointers to point to the installed image */
/* Careful about the order here... the image isn't copied yet! */
- safe_hook = (struct safe_hook *)(dpp + hptr->int13_offs);
pptr = (struct patch_area *)(dpp + hptr->patch_offs);
hptr = (struct memdisk_header *)dpp;
@@ -1210,8 +1086,12 @@ void setup(const struct real_mode_args *rm_args_ptr)
dpp = mempcpy(dpp, shdr->cmdline, cmdline_len);
}
+ /* Note the previous INT 13h hook in the "safe hook" structure */
+ hptr->safe_hook.old_hook.uint32 = pptr->mdi.oldint13.uint32;
+
/* Re-fill the "safe hook" mBFT field with the physical address */
- safe_hook->mBFT += (uint32_t)hptr;
+ hptr->safe_hook.mBFT.ptr =
+ (struct mBFT *)(((const char *)hptr) + hptr->safe_hook.mBFT.offset);
/* Update various BIOS magic data areas (gotta love this shit) */
@@ -1242,21 +1122,20 @@ void setup(const struct real_mode_args *rm_args_ptr)
if (getcmditem("dpt") != CMD_NOTFOUND ||
((nflop == 1 || no_bpt) && getcmditem("nodpt") == CMD_NOTFOUND)) {
/* Do install a replacement DPT into INT 1Eh */
- pptr->dpt_ptr = hptr->patch_offs + offsetof(struct patch_area, dpt);
+ pptr->mdi.dpt_ptr =
+ hptr->patch_offs + offsetof(struct patch_area, dpt);
}
}
/* Complete the mBFT */
- {
- struct mBFT *mBFT = (struct mBFT *)safe_hook->mBFT;
-
- mBFT->acpi.signature[0] = 'm'; /* "mBFT" */
- mBFT->acpi.signature[1] = 'B';
- mBFT->acpi.signature[2] = 'F';
- mBFT->acpi.signature[3] = 'T';
- mBFT->safe_hook = (uint32_t)safe_hook;
- mBFT->acpi.checksum = -checksum_buf(mBFT, mBFT->acpi.length);
- }
+ hptr->safe_hook.mBFT.ptr->acpi.signature[0] = 'm'; /* "mBFT" */
+ hptr->safe_hook.mBFT.ptr->acpi.signature[1] = 'B';
+ hptr->safe_hook.mBFT.ptr->acpi.signature[2] = 'F';
+ hptr->safe_hook.mBFT.ptr->acpi.signature[3] = 'T';
+ hptr->safe_hook.mBFT.ptr->safe_hook.ptr = &hptr->safe_hook;
+ hptr->safe_hook.mBFT.ptr->acpi.checksum =
+ -checksum_buf(hptr->safe_hook.mBFT.ptr,
+ hptr->safe_hook.mBFT.ptr->acpi.length);
/* Install the interrupt handlers */
printf("old: int13 = %08x int15 = %08x int1e = %08x\n",
@@ -1264,8 +1143,8 @@ void setup(const struct real_mode_args *rm_args_ptr)
wrz_32(BIOS_INT13, driverptr + hptr->int13_offs);
wrz_32(BIOS_INT15, driverptr + hptr->int15_offs);
- if (pptr->dpt_ptr)
- wrz_32(BIOS_INT1E, driverptr + pptr->dpt_ptr);
+ if (pptr->mdi.dpt_ptr)
+ wrz_32(BIOS_INT1E, driverptr + pptr->mdi.dpt_ptr);
printf("new: int13 = %08x int15 = %08x int1e = %08x\n",
rdz_32(BIOS_INT13), rdz_32(BIOS_INT15), rdz_32(BIOS_INT1E));
@@ -1291,7 +1170,8 @@ void setup(const struct real_mode_args *rm_args_ptr)
/* Reboot into the new "disk" */
puts("Loading boot sector... ");
- memcpy((void *)boot_base, (char *)pptr->diskbuf + geometry->boot_lba * 512,
+ memcpy((void *)boot_base,
+ (char *)pptr->mdi.diskbuf + geometry->boot_lba * 512,
boot_len);
if (getcmditem("pause") != CMD_NOTFOUND) {
@@ -1306,3 +1186,4 @@ void setup(const struct real_mode_args *rm_args_ptr)
shdr->esdi = pnp_install_check();
shdr->edx = geometry->driveno;
}
+