[syslinux] [PATCH] memdisk: "safe hook" and mBFT

Shao Miller Shao.Miller at yrdsb.edu.on.ca
Sun Dec 6 17:15:46 PST 2009


 From 64aaec964e717a90193473b27d6a2efc113d1f59 Mon Sep 17 00:00:00 2001
From: Shao Miller <shao.miller at yrdsb.edu.on.ca>
Date: Sun, 6 Dec 2009 19:46:55 -0500
Subject: [PATCH] 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 at yrdsb.edu.on.ca>
---
 memdisk/acpi.h      |   54 
+++++++++++++++++++++++++++++++++++++++++++++++++++
 memdisk/memdisk.inc |   47 ++++++++++++++++++++++++++++++++++++++++---
 memdisk/setup.c     |   41 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 137 insertions(+), 5 deletions(-)
 create mode 100644 memdisk/acpi.h

diff --git a/memdisk/acpi.h b/memdisk/acpi.h
new file mode 100644
index 0000000..630c5f5
--- /dev/null
+++ b/memdisk/acpi.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 Michael Brown <mbrown at 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 a37218b..8be815c 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
@@ -117,13 +117,33 @@
         section .text
         ; These pointers are used by the installer and
         ; must be first in the binary
-Pointers:    dw Int13Start
+Pointers:    dw SafeHook
         dw Int15Start
         dw PatchArea
         dw TotalSize
         dw IretPtr
 
 IretPtr        equ Int13Start.iret
+SafeHook:
+        jmp Int13Start
+        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
+
 Int13Start:
         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 db986fa..ea17afd 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) {
-- 
1.5.6.3

- Shao Miller
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 0001-memdisk-safe-hook-and-mBFT.patch
URL: <http://www.zytor.com/pipermail/syslinux/attachments/20091206/2f4c0dcc/attachment.ksh>


More information about the Syslinux mailing list