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 | 45 +++++++++++++++++++++++++++++++++++++++-- memdisk/setup.c | 41 +++++++++++++++++++++++++++++++++++++- 3 files changed, 136 insertions(+), 4 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..8a4a2b4 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 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 --------------080104060006090907000304--
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 --------------010300080909010906030809--
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>
Actually, this is likely a better approach. From a14385850e5bf3e2f94e2f5a9f0197d29ba4ff9d 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 | 45 +++++++++++++++++++++++++++++++++++++++-- memdisk/setup.c | 41 +++++++++++++++++++++++++++++++++++++- 3 files changed, 136 insertions(+), 4 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..8a4a2b4 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 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/2b2fabfb/attachment.ksh>