aboutsummaryrefslogtreecommitdiffstats
path: root/memdisk
diff options
context:
space:
mode:
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>2009-12-06 23:03:43 -0500
committerH. Peter Anvin <hpa@zytor.com>2009-12-07 15:00:54 -0800
commit569a7aa11d6ec9f93fb513fd55287afc785f2d9c (patch)
tree015c3c2741f594f8788171df3927508d81803513 /memdisk
parente0a9a74dd8a9c737541b5f3e150ff4316507377c (diff)
downloadsyslinux.git-569a7aa11d6ec9f93fb513fd55287afc785f2d9c.tar.gz
syslinux.git-569a7aa11d6ec9f93fb513fd55287afc785f2d9c.tar.xz
syslinux.git-569a7aa11d6ec9f93fb513fd55287afc785f2d9c.zip
memdisk: "safe hook" and mBFT
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>
Diffstat (limited to 'memdisk')
-rw-r--r--memdisk/acpi.h54
-rw-r--r--memdisk/memdisk.inc45
-rw-r--r--memdisk/setup.c41
3 files changed, 136 insertions, 4 deletions
diff --git a/memdisk/acpi.h b/memdisk/acpi.h
new file mode 100644
index 00000000..630c5f57
--- /dev/null
+++ b/memdisk/acpi.h
@@ -0,0 +1,54 @@
+/*
+ * 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 ));
+
diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc
index a37218b5..8a4a2b4a 100644
--- a/memdisk/memdisk.inc
+++ b/memdisk/memdisk.inc
@@ -8,7 +8,7 @@
;
; 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
@@ -125,6 +125,26 @@ Pointers: dw Int13Start
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
@@ -1038,7 +1058,25 @@ Mover_dst1: db 0, 0, 0 ; Low 24 bits of target addy
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
@@ -1060,9 +1098,10 @@ DPT_ptr dw 0 ; If nonzero, pointer to DPT
; 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
diff --git a/memdisk/setup.c b/memdisk/setup.c
index db986faa..ea17afda 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -2,7 +2,7 @@
*
* 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
@@ -13,6 +13,7 @@
* ----------------------------------------------------------------------- */
#include <stdint.h>
+#include "acpi.h"
#include "bda.h"
#include "dskprobe.h"
#include "e820.h"
@@ -47,6 +48,18 @@ struct memdisk_header {
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 {
@@ -102,6 +115,11 @@ struct edd_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;
@@ -816,6 +834,7 @@ 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;
@@ -899,6 +918,7 @@ 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);
@@ -1146,6 +1166,9 @@ 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++;
@@ -1170,6 +1193,7 @@ 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;
@@ -1179,6 +1203,21 @@ void setup(const struct real_mode_args *rm_args_ptr)
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) {