aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2003-07-01 00:42:12 +0000
committerhpa <hpa>2003-07-01 00:42:12 +0000
commit375e27432bd47011d4852621f9b1a3f5a8e1789d (patch)
tree592fea7166f5691568ce7e4e5dae5416730567b7
parent5248848c354a060c026e45598edf0b627abca117 (diff)
downloadsyslinux-elf-375e27432bd47011d4852621f9b1a3f5a8e1789d.tar.gz
syslinux-elf-375e27432bd47011d4852621f9b1a3f5a8e1789d.tar.xz
syslinux-elf-375e27432bd47011d4852621f9b1a3f5a8e1789d.zip
COM32: Try to support both farcall and intcall
-rw-r--r--com32.inc46
-rw-r--r--com32/include/com32.h3
-rw-r--r--comboot.doc22
-rw-r--r--isolinux.asm1
-rw-r--r--ldlinux.asm1
-rw-r--r--sample/c32entry.S57
-rw-r--r--sample/hello.c2
-rw-r--r--sample/hello2.c2
8 files changed, 104 insertions, 30 deletions
diff --git a/com32.inc b/com32.inc
index 3d445c10..969bfce4 100644
--- a/com32.inc
+++ b/com32.inc
@@ -1,7 +1,7 @@
;; $Id$
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2003 H. Peter Anvin - All Rights Reserved
;;
;; 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
@@ -140,12 +140,13 @@ com32_call_start:
; Now everything is set up for interrupts...
+ push dword com32_farcall ; Farcall entry point
push dword (1 << 16) ; 64K bounce buffer
push dword (comboot_seg << 4) ; Bounce buffer address
- push dword com32_syscall ; Syscall entry point
+ push dword com32_intcall ; Intcall entry point
movzx esi,word [word CmdOptPtr]
push esi ; Command line pointer
- push dword 4 ; Argument count
+ push dword 5 ; Argument count
sti ; Interrupts OK now
call pm_entry ; Run the program...
; ... on return, fall through to com32_exit ...
@@ -217,8 +218,12 @@ com32_sys_rm:
pop ds
popad
popfd
+ mov [cs:Com32SysSP],sp
retf ; Invoke routine
.return:
+ ; We clean up SP here because we don't know if the
+ ; routine returned with RET, RETF or IRET
+ mov sp,[cs:Com32SysSP]
pushfd
pushad
push ds
@@ -253,7 +258,7 @@ com32_int_resume:
iret
;
-; Syscall invocation. We manifest a structure on the real-mode stack,
+; Intcall/farcall invocation. We manifest a structure on the real-mode stack,
; containing the com32sys_t structure from <com32.h> as well as
; the following entries (from low to high address):
; - Target offset
@@ -262,27 +267,37 @@ com32_int_resume:
; - Return segment (== real mode cs == 0)
; - Return flags
;
+com32_farcall:
+ pushfd ; Save IF among other things...
+ pushad ; We only need to save some, but...
+
+ mov eax,[esp+10*4] ; CS:IP
+ jmp com32_syscall
+
+
+com32_intcall:
+ pushfd ; Save IF among other things...
+ pushad ; We only need to save some, but...
+
+ movzx eax,byte [esp+10*4] ; INT number
+ mov eax,[eax*4] ; Get CS:IP from low memory
+
com32_syscall:
- pushfd ; Save IF among other things...
- pushad ; We only need to save some, but...
cld
movzx edi,word [word SavedSSSP]
- movzx eax,word [word SavedSSSP+2]
+ movzx ebx,word [word SavedSSSP+2]
sub edi,54 ; Allocate 54 bytes
mov [word SavedSSSP],di
- shl eax,4
- add edi,eax ; Create linear address
+ shl ebx,4
+ add edi,ebx ; Create linear address
mov esi,[esp+11*4] ; Source regs
xor ecx,ecx
mov cl,11 ; 44 bytes to copy
rep movsd
- movzx eax,byte [esp+10*4] ; Interrupt number
- ; ecx == 0 here; adding it to the EA makes the
- ; encoding smaller
- mov eax,[ecx+eax*4] ; Get IVT entry
+ ; EAX is already set up to be CS:IP
stosd ; Save in stack frame
mov eax,com32_sys_rm.return ; Return seg:offs
stosd ; Save in stack frame
@@ -295,7 +310,8 @@ com32_syscall:
jmp com32_enter_rm ; Go to real mode
; On return, the 44-byte return structure is on the
- ; real-mode stack.
+ ; real-mode stack, plus the 10 additional bytes used
+ ; by the target address (see above.)
com32_sys_resume:
movzx esi,word [word SavedSSSP]
movzx eax,word [word SavedSSSP+2]
@@ -309,7 +325,7 @@ com32_sys_resume:
mov cl,11 ; 44 bytes
rep movsd ; Copy register block
- add dword [word SavedSSSP],44 ; Remove from stack
+ add dword [word SavedSSSP],54 ; Remove from stack
popad
popfd
diff --git a/com32/include/com32.h b/com32/include/com32.h
index c080ce7f..e61cb3c2 100644
--- a/com32/include/com32.h
+++ b/com32/include/com32.h
@@ -49,9 +49,10 @@ typedef struct {
extern struct com32_sys_args {
uint32_t cs_sysargs;
char *cs_cmdline;
- void (*cs_syscall)(uint8_t, com32sys_t *, com32sys_t *);
+ void (*cs_intcall)(uint8_t, com32sys_t *, com32sys_t *);
void *cs_bounce;
uint32_t cs_bounce_size;
+ void (*cs_farcall)(uint32_t, com32sys_t *, com32sys_t *);
} __com32;
/*
diff --git a/comboot.doc b/comboot.doc
index c66a179c..d262e562 100644
--- a/comboot.doc
+++ b/comboot.doc
@@ -79,11 +79,12 @@ notification to the program how much memory is available.
The following arguments are passed to the program on the stack:
Address Size Meaning
- [ESP+4] dword Number of additional arguments (currently 4)
+ [ESP+4] dword Number of additional arguments (currently 5)
[ESP+8] dword Pointer to the command line arguments (null-terminated string)
- [ESP+12] dword Pointer to system call helper function
+ [ESP+12] dword Pointer to INT call helper function
[ESP+16] dword Pointer to low memory bounce buffer
[ESP+20] dword Size of low memory bounce buffer
+ [ESP+24] dword Pointer to FAR call helper function (new in 2.05)
This corresponds to the following C prototype, available in the file
com32/include/com32.h:
@@ -91,14 +92,15 @@ com32/include/com32.h:
/* The standard prototype for _start() */
int _start(unsigned int __nargs,
char *__cmdline,
- void (*__syscall)(uint8_t, com32sys_t *, com32sys_t *),
+ void (*__intcall)(uint8_t, com32sys_t *, com32sys_t *),
void *__bounce_ptr,
- unsigned int __bounce_len);
+ unsigned int __bounce_len,
+ void (*__farcall)(uint32_t, uint16_t, com32sys_t *, com32sys_t *));
-The system call helper function can be used to issue BIOS or SYSLINUX
-API calls, and takes the interrupt number as first argument. The
-second argument is a pointer to the input register definition, an
-instance of the following structure (also available in com32.h):
+The intcall helper function can be used to issue BIOS or SYSLINUX API
+calls, and takes the interrupt number as first argument. The second
+argument is a pointer to the input register definition, an instance of
+the following structure (also available in com32.h):
typedef union {
uint32_t l;
@@ -132,6 +134,10 @@ Since BIOS or SYSLINUX API calls can generally only manipulate data
below address 0x100000, a "bounce buffer" in low memory, at least 64K
in size, is available, to copy data in and out.
+The farcall helper function behaves similarly, but takes as its first
+argument the CS:IP (in the form (CS << 16) + IP) of procedure to be
+invoked via a FAR CALL.
+
++++ SYSLINUX API CALLS +++
diff --git a/isolinux.asm b/isolinux.asm
index 22f78576..111e2796 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -170,6 +170,7 @@ GraphXSize resw 1 ; Width of splash screen file
VGAPos resw 1 ; Pointer into VGA memory
VGACluster resw 1 ; Cluster pointer for VGA image file
VGAFilePtr resw 1 ; Pointer into VGAFileBuf
+Com32SysSP resw 1 ; SP saved during COM32 syscall
ConfigFile resw 1 ; Socket for config file
PktTimeout resw 1 ; Timeout for current packet
KernelExtPtr resw 1 ; During search, final null pointer
diff --git a/ldlinux.asm b/ldlinux.asm
index d6c2b05e..b68d1998 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -172,6 +172,7 @@ GraphXSize resw 1 ; Width of splash screen file
VGAPos resw 1 ; Pointer into VGA memory
VGACluster resw 1 ; Cluster pointer for VGA image file
VGAFilePtr resw 1 ; Pointer into VGAFileBuf
+Com32SysSP resw 1 ; SP saved during COM32 syscall
TextAttrBX equ $
TextAttribute resb 1 ; Text attribute for message file
TextPage resb 1 ; Active display page
diff --git a/sample/c32entry.S b/sample/c32entry.S
index 251838d4..1ae57a2c 100644
--- a/sample/c32entry.S
+++ b/sample/c32entry.S
@@ -1,15 +1,64 @@
+#ident "$Id$"
+# -----------------------------------------------------------------------
+#
+# Copyright 2003 H. Peter Anvin - All Rights Reserved
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall
+# be included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# -----------------------------------------------------------------------
+
+# COM32 start up code - must be linked first in the binary
+
+
.section ".text","ax"
.globl _start
_start:
# This first instruction acts as COM32 magic number
movl $0x21cd4cff,%eax
+
+ # Upwards string operations
+ cld
+
+ # Zero the .bss segment
+ xorl %eax,%eax
+ movl $__bss_start,%edi # Symbol provided by linker
+ movl $_end+3,%ecx # Symbol provided by linker
+ subl %edi,%ecx
+ shrl $2,%ecx
+ rep ; stosl
+
+ # Copy COM32 invocation parameters
leal 4(%esp),%esi
movl $__com32,%edi
- mov $5,%ecx
- cld
- rep ; movsl
+ movl $6,%ecx
+ cmpl (%esi),%ecx
+ jbe 1f
+ movl (%esi),%ecx
+1: rep ; movsl
+
+ # Run program; we call this __start rather than main since we
+ # did not parse the command line or anything like that.
jmp __start
.section ".bss","a"
.globl __com32
-__com32: .space 20
+__com32: .space 24
diff --git a/sample/hello.c b/sample/hello.c
index a2b79dde..8730ba1a 100644
--- a/sample/hello.c
+++ b/sample/hello.c
@@ -38,7 +38,7 @@ int __start(void)
for ( p = msg ; *p ; p++ ) {
inreg.edx.b[0] = *p;
inreg.eax.b[1] = 0x02; /* Write Character */
- __com32.cs_syscall(0x21, &inreg, NULL);
+ __com32.cs_intcall(0x21, &inreg, NULL);
}
return 0;
diff --git a/sample/hello2.c b/sample/hello2.c
index 26a8a759..871ad047 100644
--- a/sample/hello2.c
+++ b/sample/hello2.c
@@ -48,7 +48,7 @@ static void writemsg(const char *msg)
inreg.eax.w[0] = 0x0002; /* Write string */
inreg.ebx.w[0] = OFFS(__com32.cs_bounce);
inreg.es = SEG(__com32.cs_bounce);
- __com32.cs_syscall(0x22, &inreg, NULL);
+ __com32.cs_intcall(0x22, &inreg, NULL);
};
int __start(void)