summaryrefslogtreecommitdiff
path: root/memdisk
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-09-28 11:25:20 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-09-28 11:25:20 -0700
commit3748de36714958902ebaf0669e004ae4113204db (patch)
tree9000df597bd8dca5c4859cde368cee6e86631bd4 /memdisk
parenta584b423450923389f4dc25480e30472c8641d38 (diff)
downloadsyslinux-3748de36714958902ebaf0669e004ae4113204db.tar.gz
Add "safeint" mode to memdisk
Diffstat (limited to 'memdisk')
-rw-r--r--memdisk/memdisk.asm48
-rw-r--r--memdisk/memdisk.doc3
-rw-r--r--memdisk/setup.c9
3 files changed, 56 insertions, 4 deletions
diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm
index 5b6afcfa..7be5e25c 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 a9a43ac4..fdcc259e 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 76775fd4..2f41a4d9 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;
}