[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