[syslinux:pathbased] core: add a direct 32-bit API
syslinux-bot for H. Peter Anvin
hpa at zytor.com
Tue Feb 23 19:18:13 PST 2010
Commit-ID: 3cda063b8e079ee6518d3425650d800db4227585
Gitweb: http://syslinux.zytor.com/commit/3cda063b8e079ee6518d3425650d800db4227585
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Tue, 23 Feb 2010 18:14:12 -0800
Committer: H. Peter Anvin <hpa at zytor.com>
CommitDate: Tue, 23 Feb 2010 18:14:12 -0800
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 at zytor.com>
---
com32/include/com32.h | 5 ++-
.../video/forcetext.c => include/syslinux/pmapi.h} | 23 +++++----
com32/lib/sys/entry.S | 2 +-
com32/lib/sys/fileread.c | 49 +++++++++++---------
core/com32.inc | 10 +++-
core/fs/fs.c | 21 ++++++++
core/include/core.h | 1 +
core/include/fs.h | 1 +
core/include/pmapi.h | 8 +++
memdisk/dskprobe.h => core/pmapi.c | 22 +++++----
doc/comboot.txt | 45 +++++++++++++-----
11 files changed, 127 insertions(+), 60 deletions(-)
diff --git a/com32/include/com32.h b/com32/include/com32.h
index aa7fb4b..9334efb 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/lib/syslinux/video/forcetext.c b/com32/include/syslinux/pmapi.h
similarity index 80%
copy from com32/lib/syslinux/video/forcetext.c
copy to com32/include/syslinux/pmapi.h
index 136cb27..848a554 100644
--- a/com32/lib/syslinux/video/forcetext.c
+++ b/com32/include/syslinux/pmapi.h
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * 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
@@ -27,16 +27,19 @@
* ----------------------------------------------------------------------- */
/*
- * syslinux/video/forcetext.c
+ * pmapi.h
+ *
+ * Definitions for the Syslinux 4 protected-mode ABI
*/
-#include <syslinux/video.h>
-#include <com32.h>
+#ifndef _SYSLINUX_PMAPI_H
+#define _SYSLINUX_PMAPI_H
+
+#include <stddef.h>
+#include <inttypes.h>
-void syslinux_force_text_mode(void)
-{
- static com32sys_t ireg;
+struct com32_pmapi {
+ size_t (*read_file)(uint16_t *, void *, size_t);
+};
- ireg.eax.w[0] = 0x0005;
- __intcall(0x22, &ireg, NULL);
-}
+#endif /* _SYSLINUX_PMAPI_H */
diff --git a/com32/lib/sys/entry.S b/com32/lib/sys/entry.S
index a3a1eaa..629f336 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 54ff711..cfd4955 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 cb17279..810ee03 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 d67a87c..e0f469b 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 c955e73..e6364f8 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 8a173d9..1f4ad28 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 0000000..57d2e6f
--- /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/memdisk/dskprobe.h b/core/pmapi.c
similarity index 61%
copy from memdisk/dskprobe.h
copy to core/pmapi.c
index 99bfa66..f45a7fc 100644
--- a/memdisk/dskprobe.h
+++ b/core/pmapi.c
@@ -1,6 +1,7 @@
-/* ----------------------------------------------------------------------- *
+/* -----------------------------------------------------------------------
*
- * Copyright 2009 Shao Miller - All Rights Reserved
+ * 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
@@ -10,12 +11,13 @@
*
* ----------------------------------------------------------------------- */
-/*
- * dskprobe.h
- *
- * Routines for probing BIOS disk drives
- */
-
-#include <stdint.h>
+#include <inttypes.h>
+#include <com32.h>
+#include <syslinux/pmapi.h>
+#include "core.h"
+#include "fs.h"
-extern uint8_t probe_drive_range(uint8_t);
+const struct com32_pmapi pm_api_vector =
+{
+ .read_file = pmapi_read_file,
+};
diff --git a/doc/comboot.txt b/doc/comboot.txt
index 6d026aa..7950688 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
More information about the Syslinux-commits
mailing list