From 3748de36714958902ebaf0669e004ae4113204db Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 28 Sep 2006 11:25:20 -0700 Subject: [PATCH] Add "safeint" mode to memdisk --- memdisk/memdisk.asm | 48 ++++++++++++++++++++++++++++++++++++++++++++---- memdisk/memdisk.doc | 3 +++ memdisk/setup.c | 9 +++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm index 5b6afcf..7be5e25 100644 --- a/memdisk/memdisk.asm +++ b/memdisk/memdisk.asm @@ -6,7 +6,7 @@ ; A program to emulate an INT 13h disk BIOS from a "disk" in extended ; memory. ; -; Copyright (C) 2001-2005 H. Peter Anvin +; Copyright (C) 2001-2006 H. Peter Anvin ; ; 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 @@ -44,6 +44,7 @@ %define CONFIG_READONLY 0x01 %define CONFIG_RAW 0x02 +%define CONFIG_SAFEINT 0x04 %define CONFIG_BIGRAW 0x08 ; MUST be 8! org 0h @@ -605,7 +606,9 @@ bcopy: push edx push ebp - test byte [ConfigFlags],CONFIG_RAW + mov bx, real_int15_stub + + test byte [ConfigFlags], CONFIG_RAW|CONFIG_SAFEINT jz .anymode smsw ax ; Unprivileged! @@ -613,6 +616,33 @@ bcopy: jnz .protmode .realmode: + test byte [ConfigFlags], CONFIG_RAW + jnz .raw + + ; We're in real mode with CONFIG_SAFEINT, invoke INT 15h + ; directly if the vector is unchanged, otherwise invoke + ; the *old* INT 15h vector. + + push ds + xor ax, ax + mov fs,ax + + cmp word [4*0x15], Int15Start + jne .changed + + mov ax, cs + cmp word [4*0x15+2], ax + jne .changed + + pop ds + jmp .anymode ; INT 15h unchanged, safe to execute + +.changed: ; INT 15h modified, execute *old* INT 15h + pop ds + mov bx, fake_int15_stub + jmp .anymode + +.raw: TRACER 'r' ; We're in real mode, do it outselves @@ -716,8 +746,7 @@ bcopy: mov si,Mover mov ah, 87h shl cx,1 ; Convert to 16-bit words - int 15h - cli ; Some BIOSes enable interrupts on INT 15h + call bx ; INT 15h stub pop eax ; Transfer size this cycle pop ecx pop edi @@ -736,6 +765,17 @@ bcopy: pop eax ret +real_int15_stub: + int 15h + cli ; Some BIOSes enable interrupts on INT 15h + ret + +fake_int15_stub: + pushf + call far [OldInt15] + cli + ret + %ifdef DEBUG_TRACERS debug_tracer: pushad pushfd diff --git a/memdisk/memdisk.doc b/memdisk/memdisk.doc index a9a43ac..fdcc259 100644 --- a/memdisk/memdisk.doc +++ b/memdisk/memdisk.doc @@ -86,6 +86,9 @@ d) MEMDISK normally uses the BIOS "INT 15h mover" API to access high bigraw Use raw access to protected mode memory, and leave the CPU in "big real" mode afterwards. + safeint Use INT 15h access to protected memory, but invoke + INT 15h the way it was *before* MEMDISK was loaded. + Some interesting things to note: diff --git a/memdisk/setup.c b/memdisk/setup.c index 76775fd..2f41a4d 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -85,8 +85,10 @@ struct patch_area { 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! */ uint16_t mystack; @@ -586,10 +588,17 @@ uint32_t setup(syscall_t cs_syscall, void *cs_bounce) } if ( getcmditem("raw") != CMD_NOTFOUND ) { puts("Using raw access to high memory\n"); + pptr->configflags &= ~CONFIG_SAFEINT|CONFIG_BIGRAW; pptr->configflags |= CONFIG_RAW; } + if ( getcmditem("safeint") != CMD_NOTFOUND ) { + puts("Using safe INT 15h access to high memory\n"); + pptr->configflags &= ~CONFIG_RAW|CONFIG_BIGRAW; + pptr->configflags |= CONFIG_SAFEINT; + } if ( getcmditem("bigraw") != CMD_NOTFOUND ) { puts("Using raw access to high memory - assuming big real mode\n"); + pptr->configflags &= ~CONFIG_SAFEINT; pptr->configflags |= CONFIG_BIGRAW|CONFIG_RAW; } -- 2.7.4