[syslinux:firmware] dos: We cannot use memset() for a far object, introduce memset_sl()

syslinux-bot for H. Peter Anvin hpa at zytor.com
Thu Jan 16 11:00:06 PST 2014


Commit-ID:  1d01a26f07910da394a733421f1308830d490e94
Gitweb:     http://www.syslinux.org/commit/1d01a26f07910da394a733421f1308830d490e94
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Thu, 16 Jan 2014 10:54:02 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Thu, 16 Jan 2014 10:56:29 -0800

dos: We cannot use memset() for a far object, introduce memset_sl()

We started using memset() on the extents buffer in ldlinux.sys, which
doesn't reside in the main segment, which worked on all the installer
platforms except DOS.  Fix DOS by introducing memset_sl() for this
case.

Reported-by: Ady <ady-sf at hotmail.com>
Signed-off-by: H. Peter Anvin <hpa at zytor.com>

---
 dos/getsetsl.c          | 17 +++++++++++++++++
 libinstaller/syslxint.h |  2 ++
 libinstaller/syslxmod.c |  2 +-
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/dos/getsetsl.c b/dos/getsetsl.c
index fadef43..5260a2a 100644
--- a/dos/getsetsl.c
+++ b/dos/getsetsl.c
@@ -123,3 +123,20 @@ void memcpy_from_sl(void *dst, const void *src, size_t len)
 		 : "r" (seg)
 		 : "memory");
 }
+
+void memset_sl(void *dst, int c, size_t len)
+{
+    uint16_t seg;
+    uint16_t off;
+
+    seg = ds() + ((size_t)dst >> 4);
+    off = (size_t)dst & 15;
+
+    asm volatile("pushw %%es ; "
+		 "movw %3,%%es ; "
+		 "rep ; stosb ; "
+		 "popw %%es"
+		 : "+D" (off), "+c" (len)
+		 : "a" (c), "r" (seg)
+		 : "memory");
+}
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h
index 59e3e5e..ce9cb20 100644
--- a/libinstaller/syslxint.h
+++ b/libinstaller/syslxint.h
@@ -134,6 +134,7 @@ void set_32_sl(uint32_t * p, uint32_t v);
 void set_64_sl(uint64_t * p, uint64_t v);
 void memcpy_to_sl(void *dst, const void *src, size_t len);
 void memcpy_from_sl(void *dst, const void *src, size_t len);
+void memset_sl(void *dst, int c, size_t len);
 
 #else
 
@@ -148,6 +149,7 @@ void memcpy_from_sl(void *dst, const void *src, size_t len);
 #define set_64_sl(x,y) 		set_64(x,y)
 #define memcpy_to_sl(d,s,l)	memcpy(d,s,l)
 #define memcpy_from_sl(d,s,l)	memcpy(d,s,l)
+#define memset_sl(d,c,l)	memset(d,c,l)
 
 #endif
 
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index 98e2710..197261c 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -41,7 +41,7 @@ static void generate_extents(struct syslinux_extent *ex, int nptrs,
     base = addr;
     len = lba = 0;
 
-    memset(ex, 0, nptrs * sizeof *ex);
+    memset_sl(ex, 0, nptrs * sizeof *ex);
 
     while (nsect) {
 	sect = *sectp++;


More information about the Syslinux-commits mailing list