Two additions to MEMDISK to support OS drivers.
The "safe hook" structure ("Safe Master Boot Record INT 13h Hook Routines")
is a means for an OS driver to follow a chain of INT 13h hooks, examining
the hooks' vendors and assuming responsibility for hook functionality along
the way. For MEMDISK, we guarantee an additional field which holds the
physical address for the mBFT.
The mBFT is an ACPI table which an OS driver can scan for. The mBFT
contains the official MEMDISK Info structure (MDI) which itself includes
parameters the OS will want to know about. The mBFT points back at the
"safe hook" structure's physical address so that an OS supporting both
"safe hook" chain-walking as well as mBFT-scanning can know that both
refer to the same MEMDISK instance.
Signed-off-by: Shao Miller <shao.miller@yrdsb.edu.on.ca>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
--- /dev/null
+/*
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
+ * This file derived almost in its entirety from gPXE.
+ *
+ * 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; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/** @file
+ *
+ * ACPI data structures
+ *
+ */
+
+#include <stdint.h>
+
+/**
+ * An ACPI description header
+ *
+ * This is the structure common to the start of all ACPI system
+ * description tables.
+ */
+struct acpi_description_header {
+ /** ACPI signature (4 ASCII characters) */
+ char signature[4];
+ /** Length of table, in bytes, including header */
+ uint32_t length;
+ /** ACPI Specification minor version number */
+ uint8_t revision;
+ /** To make sum of entire table == 0 */
+ uint8_t checksum;
+ /** OEM identification */
+ char oem_id[6];
+ /** OEM table identification */
+ char oem_table_id[8];
+ /** OEM revision number */
+ uint32_t oem_revision;
+ /** ASL compiler vendor ID */
+ char asl_compiler_id[4];
+ /** ASL compiler revision number */
+ uint32_t asl_compiler_revision;
+} __attribute__ (( packed ));
+
;
; Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
; Copyright 2009 Intel Corporation; author: H. Peter Anvin
-; Portions copyright 2009 Shao Miller [El Torito code]
+; Portions copyright 2009 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
IretPtr equ Int13Start.iret
Int13Start:
+ jmp Int13Start.SafeHookEnd
+ db 0 ; Pad to three bytes
+ db '$INT13SF' ; Signature for "safe hook"
+ db 'MEMDISK ' ; Vendor ID
+ dd 0 ; SEG:OFF of previous INT 13h hook
+ ; Must be filled in by installer
+ dd 0 ; "Safe hook" flags
+; ---- "Safe hook" structure ends here ---
+
+; This next field should be guaranteed at this position after the
+; "safe hook" structure. This allows for a MEMDISK OS driver to
+; immediately find out the particular parameters using the mBFT
+; and MDI structures. This binary will have the offset to the mBFT
+; in this field to begin with, so the installer knows where the mBFT
+; is. This is akin to the "Pointers" section above. The installer
+; will refill this field with the physical address of the mBFT for
+; future consumers, such as OS drivers.
+ dd mBFT ; Offset from hook to the mBFT
+
+.SafeHookEnd:
cmp word [cs:Recursive],0
jne recursive
Mover_dst2: db 0 ; High 8 bits of source addy
Mover_dummy2: dd 0, 0, 0, 0 ; More space for the BIOS
- alignb 4, db 0
+ alignb 16, db 0
+mBFT:
+; Fields common to all ACPI tables
+ dd ' ' ; ACPI signature ("mBFT")
+ ; This is filled-in by the installer
+ ; to avoid an accidentally valid mBFT
+ dd mBFT_Len ; ACPI table length
+ db 1 ; ACPI revision
+ db 0 ; ACPI table checksum
+ db 'MEMDSK' ; ACPI OEM ID
+ db 'Syslinux' ; ACPI OEM table ID
+ dd 0 ; ACPI OEM revision
+ dd 0 ; ACPI ASL compiler vendor ID
+ dd 0 ; ACPI ASL compiler revision
+; The next field is mBFT-specific and filled-in by the installer
+ dd 0 ; "Safe hook" physical address
+
+; Note that the above ends on a DWORD boundary.
+; The MDI has always started at such a boundary.
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
; Original DPT pointer follows
MDI_Len equ $-MemDisk_Info
+mBFT_Len equ $-mBFT ; mBFT includes the MDI
; ---- MDI structure ends here ---
-DriveShiftLimit db 0ffh ; Installer will [soon] probe for
+DriveShiftLimit db 0ffh ; Installer will probe for
; a range of contiguous drives.
; Any BIOS drives above this region
; shall not be impacted by our
*
* Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
* Copyright 2009 Intel Corporation; author: H. Peter Anvin
- * Portions copyright 2009 Shao Miller [El Torito code]
+ * Portions copyright 2009 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
* ----------------------------------------------------------------------- */
#include <stdint.h>
+#include "acpi.h"
#include "bda.h"
#include "dskprobe.h"
#include "e820.h"
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 {
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;
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;
/* 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);
}
}
+ /* 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++;
/* 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;
dpp = mempcpy(dpp, shdr->cmdline, cmdline_len);
}
+ /* Re-fill the "safe hook" mBFT field with the physical address */
+ safe_hook->mBFT += (uint32_t)hptr;
+
+ /* 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);
+ }
+
/* Update various BIOS magic data areas (gotta love this shit) */
if (geometry->driveno & 0x80) {