summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-23 18:14:12 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-23 18:14:12 -0800
commit3cda063b8e079ee6518d3425650d800db4227585 (patch)
tree5c31ff2924ad2d43e0174e1c7301e950543262d4
parent2e236fea2b554b7b72f66d96ceae9e3fa4da675a (diff)
downloadsyslinux-3cda063b8e079ee6518d3425650d800db4227585.tar.gz
core: add a direct 32-bit API
Add a direct 32-bit API to some functions; initially read file only. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/include/com32.h5
-rw-r--r--com32/include/syslinux/pmapi.h45
-rw-r--r--com32/lib/sys/entry.S2
-rw-r--r--com32/lib/sys/fileread.c49
-rw-r--r--core/com32.inc10
-rw-r--r--core/fs/fs.c21
-rw-r--r--core/include/core.h1
-rw-r--r--core/include/fs.h1
-rw-r--r--core/include/pmapi.h8
-rw-r--r--core/pmapi.c23
-rw-r--r--doc/comboot.txt45
11 files changed, 170 insertions, 40 deletions
diff --git a/com32/include/com32.h b/com32/include/com32.h
index aa7fb4b6..9334efb8 100644
--- a/com32/include/com32.h
+++ b/com32/include/com32.h
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2002-2009 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -92,6 +92,8 @@ typedef struct {
#define EFLAGS_VIP 0x00100000
#define EFLAGS_ID 0x00200000
+struct com32_pmapi;
+
extern struct com32_sys_args {
uint32_t cs_sysargs;
char *cs_cmdline;
@@ -101,6 +103,7 @@ extern struct com32_sys_args {
void __cdecl(*cs_farcall) (uint32_t, const com32sys_t *, com32sys_t *);
int __cdecl(*cs_cfarcall) (uint32_t, const void *, uint32_t);
uint32_t cs_memsize;
+ const struct com32_pmapi *cs_pm;
} __com32;
/*
diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h
new file mode 100644
index 00000000..848a5540
--- /dev/null
+++ b/com32/include/syslinux/pmapi.h
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2002-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pmapi.h
+ *
+ * Definitions for the Syslinux 4 protected-mode ABI
+ */
+
+#ifndef _SYSLINUX_PMAPI_H
+#define _SYSLINUX_PMAPI_H
+
+#include <stddef.h>
+#include <inttypes.h>
+
+struct com32_pmapi {
+ size_t (*read_file)(uint16_t *, void *, size_t);
+};
+
+#endif /* _SYSLINUX_PMAPI_H */
diff --git a/com32/lib/sys/entry.S b/com32/lib/sys/entry.S
index a3a1eaa8..629f336a 100644
--- a/com32/lib/sys/entry.S
+++ b/com32/lib/sys/entry.S
@@ -30,7 +30,7 @@
*/
/* Number of arguments in our version of the entry structure */
-#define COM32_ARGS 7
+#define COM32_ARGS 8
.section ".init","ax"
.globl _start
diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c
index 54ff7115..cfd49557 100644
--- a/com32/lib/sys/fileread.c
+++ b/com32/lib/sys/fileread.c
@@ -34,32 +34,23 @@
#include <errno.h>
#include <string.h>
#include <com32.h>
+#include <syslinux/pmapi.h>
#include <minmax.h>
#include "file.h"
int __file_get_block(struct file_info *fp)
{
- com32sys_t ireg, oreg;
+ ssize_t bytes_read;
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.w[0] = 0x0007; /* Read file */
- ireg.ebx.w[0] = OFFS(__com32.cs_bounce);
- ireg.es = SEG(__com32.cs_bounce);
- ireg.esi.w[0] = fp->i.filedes;
- ireg.ecx.w[0] = MAXBLOCK >> fp->i.blocklg2;
-
- __intcall(0x22, &ireg, &oreg);
-
- if (oreg.eflags.l & EFLAGS_CF) {
+ bytes_read = __com32.cs_pm->read_file(&fp->i.filedes, fp->i.buf,
+ MAXBLOCK >> fp->i.blocklg2);
+ if (!bytes_read) {
errno = EIO;
return -1;
}
-
- fp->i.filedes = oreg.esi.w[0];
- fp->i.nbytes = oreg.ecx.l;
- fp->i.datap = fp->i.buf;
- memcpy(fp->i.buf, __com32.cs_bounce, fp->i.nbytes);
-
+
+ fp->i.nbytes = bytes_read;
+ fp->i.datap = fp->i.buf;
return 0;
}
@@ -74,19 +65,33 @@ ssize_t __file_read(struct file_info * fp, void *buf, size_t count)
if (fp->i.offset >= fp->i.length || !fp->i.filedes)
return n; /* As good as it gets... */
- if (__file_get_block(fp))
- return n ? n : -1;
+ if (count > MAXBLOCK) {
+ /* Large transfer: copy directly, without buffering */
+ ncopy = __com32.cs_pm->read_file(&fp->i.filedes, bufp,
+ count >> fp->i.blocklg2);
+ if (!ncopy) {
+ errno = EIO;
+ return n ? n : -1;
+ }
+
+ goto got_data;
+ } else {
+ if (__file_get_block(fp))
+ return n ? n : -1;
+ }
}
ncopy = min(count, fp->i.nbytes);
memcpy(bufp, fp->i.datap, ncopy);
- n += ncopy;
- bufp += ncopy;
- count -= ncopy;
fp->i.datap += ncopy;
fp->i.offset += ncopy;
fp->i.nbytes -= ncopy;
+
+ got_data:
+ n += ncopy;
+ bufp += ncopy;
+ count -= ncopy;
}
return n;
diff --git a/core/com32.inc b/core/com32.inc
index cb172794..810ee036 100644
--- a/core/com32.inc
+++ b/core/com32.inc
@@ -1,7 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;; Copyright 2009-2010 Intel Corporation; author: 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
@@ -17,6 +17,8 @@
;; Common code for running a COM32 image
;;
+ extern pm_api_vector
+
;
; Load a COM32 image. A COM32 image is the 32-bit analogue to a DOS
; .com file. A COM32 image is loaded at address 0x101000, with %esp
@@ -82,6 +84,7 @@ com32_start:
.pm:
; Set up the calling stack frame
+ push dword pm_api_vector
push dword [HighMemSize] ; Memory managed by Syslinux
push dword core_cfarcall ; Cfarcall entry point
push dword core_farcall ; Farcall entry point
@@ -89,7 +92,7 @@ com32_start:
push dword core_real_mode ; Bounce buffer address
push dword core_intcall ; Intcall entry point
push dword command_line ; Command line pointer
- push dword 7 ; Argument count
+ push dword 8 ; Argument count
sti ; Interrupts OK now
call com32_entry ; Run the program...
; ... on return, fall through to com32_exit ...
@@ -123,7 +126,7 @@ not_com32r_msg db ': not a COM32R image', CR, LF, 0
global __com32
alignz 4
__com32:
- dd 7 ; Argument count
+ dd 8 ; Argument count
dd 0 ; No command line
dd core_intcall ; Intcall entry point
dd core_xfer_buf ; Bounce buffer address
@@ -131,3 +134,4 @@ __com32:
dd core_farcall ; Farcall entry point
dd core_cfarcall ; Cfarcall entry point
HighMemSize dd 0 ; End of memory pointer (bytes)
+ dd pm_api_vector ; Protected mode functions
diff --git a/core/fs/fs.c b/core/fs/fs.c
index d67a87ca..e0f469ba 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -137,6 +137,27 @@ void getfssec(com32sys_t *regs)
regs->ecx.l = bytes_read;
}
+size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors)
+{
+ bool have_more;
+ size_t bytes_read;
+ struct file *file;
+
+ file = handle_to_file(*handle);
+ bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more);
+
+ /*
+ * If we reach EOF, the filesystem driver will have already closed
+ * the underlying file... this really should be cleaner.
+ */
+ if (!have_more) {
+ _close_file(file);
+ *handle = 0;
+ }
+
+ return bytes_read;
+}
+
void pm_searchdir(com32sys_t *regs)
{
char *name = MK_PTR(regs->ds, regs->edi.w[0]);
diff --git a/core/include/core.h b/core/include/core.h
index c955e730..e6364f87 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -3,6 +3,7 @@
#include <klibc/compiler.h>
#include <com32.h>
+#include <syslinux/pmapi.h>
extern char core_xfer_buf[65536];
extern char core_cache_buf[65536];
diff --git a/core/include/fs.h b/core/include/fs.h
index 8a173d9f..1f4ad280 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -187,6 +187,7 @@ void mangle_name(char *, const char *);
char *unmangle_name(char *, const char *);
int searchdir(const char *name);
void _close_file(struct file *);
+size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors);
/* chdir.c */
void pm_realpath(com32sys_t *regs);
diff --git a/core/include/pmapi.h b/core/include/pmapi.h
new file mode 100644
index 00000000..57d2e6f7
--- /dev/null
+++ b/core/include/pmapi.h
@@ -0,0 +1,8 @@
+#ifndef PMAPI_H
+#define PMAPI_H
+
+#include <syslinux/pmapi.h>
+
+size_t pmapi_read_file(uint16_t *, void *, size_t);
+
+#endif /* PMAPI_H */
diff --git a/core/pmapi.c b/core/pmapi.c
new file mode 100644
index 00000000..f45a7fc6
--- /dev/null
+++ b/core/pmapi.c
@@ -0,0 +1,23 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009-2010 Intel Corporation; author: 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
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <inttypes.h>
+#include <com32.h>
+#include <syslinux/pmapi.h>
+#include "core.h"
+#include "fs.h"
+
+const struct com32_pmapi pm_api_vector =
+{
+ .read_file = pmapi_read_file,
+};
diff --git a/doc/comboot.txt b/doc/comboot.txt
index 6d026aab..79506887 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -90,19 +90,22 @@ The following arguments are passed to the program on the stack:
[ESP+24] dword Pointer to FAR call helper function (new in 2.05)
[ESP+28] dword Pointer to CDECL helper function (new in 3.54)
[ESP+32] dword Amount of memory controlled by the Syslinux core (new in 3.74)
-
-This corresponds to the following C prototype, available in the file
-com32/include/com32.h:
-
-/* The standard prototype for _start() */
-int _start(unsigned int __nargs,
- char *__cmdline,
- void (*__intcall)(uint8_t, com32sys_t *, com32sys_t *),
- void *__bounce_ptr,
- unsigned int __bounce_len,
- void (*__farcall)(uint32_t, com32sys_t *, com32sys_t *),
- int (*__cfarcall)(uint32_t, void *, size_t)
- );
+ [ESP+36] dword Pointer to protected-mode functions (new in 4.00)
+
+The libcom32 startup code loads this into a structure named __com32,
+defined in <com32.h>:
+
+extern struct com32_sys_args {
+ uint32_t cs_sysargs;
+ char *cs_cmdline;
+ void __cdecl(*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *);
+ void *cs_bounce;
+ uint32_t cs_bounce_size;
+ void __cdecl(*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *);
+ int __cdecl(*cs_cfarcall)(uint32_t, const void *, uint32_t);
+ uint32_t cs_memsize;
+ struct com32_pmapi *cs_pm;
+} __com32;
The intcall helper function can be used to issue BIOS or Syslinux API
calls, and takes the interrupt number as first argument. The second
@@ -149,6 +152,12 @@ The cfarcall helper function takes (CS << 16)+IP, a pointer to a stack
frame, a size of that stack frame, and returns the return value of EAX
(which may need to be appropriate truncated by the user.)
+Starting in version 4.00, some of these API calls are available as
+protected-mode function calls, using the regparm(3) calling convention
+(the first three argumetns in EAX, EDX, ECX; the rest on the stack.)
+Those functions are defined in struct com32_pmapi, defined in
+<syslinux/pmapi.h>.
+
++++ SYSLINUX API CALLS +++
@@ -342,6 +351,16 @@ AX=0007h [2.08] Read file
WARNING: Calling this function with an invalid file handle
will probably crash the system.
+ 32-BIT VERSION:
+
+ size_t cs_pm->read_file(uint16_t *handle, void *buf, size_t blocks)
+
+ handle - file handle (input and output, set to zero on end of file)
+ buf - buffer to write to
+ blocks - number of blocks to read
+
+ Returns number of bytes read, or 0 on failure.
+
AX=0008h [2.08] Close file