diff options
author | hpa <hpa> | 2003-07-01 00:42:12 +0000 |
---|---|---|
committer | hpa <hpa> | 2003-07-01 00:42:12 +0000 |
commit | 375e27432bd47011d4852621f9b1a3f5a8e1789d (patch) | |
tree | 592fea7166f5691568ce7e4e5dae5416730567b7 | |
parent | 5248848c354a060c026e45598edf0b627abca117 (diff) | |
download | syslinux-375e27432bd47011d4852621f9b1a3f5a8e1789d.tar.gz |
COM32: Try to support both farcall and intcall
-rw-r--r-- | com32.inc | 46 | ||||
-rw-r--r-- | com32/include/com32.h | 3 | ||||
-rw-r--r-- | comboot.doc | 22 | ||||
-rw-r--r-- | isolinux.asm | 1 | ||||
-rw-r--r-- | ldlinux.asm | 1 | ||||
-rw-r--r-- | sample/c32entry.S | 57 | ||||
-rw-r--r-- | sample/hello.c | 2 | ||||
-rw-r--r-- | sample/hello2.c | 2 |
8 files changed, 104 insertions, 30 deletions
@@ -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) |