Patchwork fix the DOS port problems

login
register
about
Submitter Rudolf Marek
Date 2017-12-29 11:55:38
Message ID <3669ee86-d690-d905-0ea5-803de68aaeb8@assembler.cz>
Download mbox | patch
Permalink /patch/4516/
State New
Headers show

Comments

Rudolf Marek - 2017-12-29 11:55:38
Hi,

Attaching a patch which works around the valloc() issue in the DJGPP. 
Please apply before the flashrom 1.0. 

In the meanwhile, it would be great if someone could test it too,
if needed I will distribute the executable for a test to Rayer (on CC).

I will also try to get some help on DJGPP list, as this issue happens 
even with the official RPMs of DJGPP 2.05.

Signed-off-by: Rudolf Marek <r.marek@assembler.cz>

Fix the documentation and DOS port.

Update the DOS cross-compile documentation,
and workaround issue with valloc() with the
latest DJGPP.

Thanks
Rudolf

Patch

diff --git a/README b/README
index ab761f7..b23b315 100644
--- a/README
+++ b/README
@@ -95,30 +95,47 @@  To cross-compile on Linux for DOS:
  Get packages of the DJGPP cross compiler and install them:
  djgpp-filesystem djgpp-gcc djgpp-cpp djgpp-runtime djgpp-binutils
  As an alternative, the DJGPP web site offers packages for download as well:
- djcross-binutils-2.19.1-10ap.i386.rpm
- djcross-gcc-4.3.2-8ap.i686.rpm
- djcrx-2.04pre_20090725-13ap.i386.rpm
+ djcross-binutils-2.29.1-1ap.x86_64.rpm
+ djcross-gcc-7.2.0-1ap.x86_64.rpm
+ djcrx-2.05-5.x86_64.rpm
  The cross toolchain packages for your distribution may have slightly different
  names (look for packages named *djgpp*).
 
- You will need the following library source trees containing their compiled
- static libraries either in the parent directory of the flashrom source or
- specify the base folder on compile time with the LIBS_BASE parameter.
- The default as described above is equal to calling
-   'make djgpp-dos LIBS_BASE=..'
+ Alternatively, you could use a script to build it from scratch:
+ https://github.com/andrewwutw/build-djgpp
+
+ You will need the libpci and libgetopt library source trees containing
+ their compiled static libraries and header files installed in some
+ directory say libpci-libgetopt/, which will be later specified with
+ LIBS_BASE parameter during flashrom compilation. Easiest way to
+ handle it is to put pciutils, libgetopt and flashrom directories
+ in one subdirectory. There will be extra subdirectory libpci-libgetopt
+ created, which will contain compiled libpci and libgetopt.
 
- To get and build said libraries...
  Download pciutils 3.1.5 and apply http://flashrom.org/File:Pciutils.patch.gz
- Compile pciutils, see README.DJGPP for instructions.
- Download and compile http://flashrom.org/File:Libgetopt.tar.gz
+ Compile pciutils, using following command line:
+
+ make ZLIB=no DNS=no HOST=i386-djgpp-djgpp CROSS_COMPILE=i586-pc-msdosdjgpp- \
+     PREFIX=/ DESTDIR=$PWD/../libpci-libgetopt  \
+     STRIP="--strip-program=i586-pc-msdosdjgpp-strip -s" install install-lib
+
+ Download and compile with 'make' http://flashrom.org/File:Libgetopt.tar.gz
+
+ Copy the libgetopt.a to ../libpci-libgetopt/lib and
+ getopt.h to ../libpci-libgetopt/include
+
  Enter the flashrom directory.
- Run either (change settings where appropriate)
- make CC=i586-pc-msdosdjgpp-gcc STRIP=i586-pc-msdosdjgpp-strip
- or (above settings hardcoded)
- make djgpp-dos
+
+ make CC=i586-pc-msdosdjgpp-gcc STRIP=i586-pc-msdosdjgpp-strip LIBS_BASE=../libpci-libgetopt/ strip
+
+ If you like can compress the resulting executable with UPX:
+
+ upx -9 flashrom.exe
+
  To run flashrom.exe, download http://flashrom.org/File:Csdpmi7b.zip and
  unpack CWSDPMI.EXE into the current directory or one in PATH.
 
+
 To cross-compile on Linux for Windows:
 
  Get packages of the MinGW cross compiler and install them:
diff --git a/physmap.c b/physmap.c
index a261ccd..3338b62 100644
--- a/physmap.c
+++ b/physmap.c
@@ -38,29 +38,40 @@ 
 
 #ifdef __DJGPP__
 #include <dpmi.h>
+#include <malloc.h>
 #include <sys/nearptr.h>
 
+#define ONE_MEGABYTE (1024 * 1024)
 #define MEM_DEV "dpmi"
 
-static void *realmem_map;
+static void *realmem_map_aligned;
 
 static void *map_first_meg(uintptr_t phys_addr, size_t len)
 {
-	if (realmem_map)
-		return realmem_map + phys_addr;
+	void *realmem_map;
+	size_t pagesize;
 
-	realmem_map = valloc(1024 * 1024);
+	if (realmem_map_aligned)
+		return realmem_map_aligned + phys_addr;
+
+	/* valloc() from DJGPP 2.05 does not work properly */
+	pagesize = getpagesize();
+
+	realmem_map = malloc(ONE_MEGABYTE + pagesize);
 
 	if (!realmem_map)
 		return ERROR_PTR;
 
-	if (__djgpp_map_physical_memory(realmem_map, (1024 * 1024), 0)) {
+	realmem_map_aligned = (void *)(((size_t) realmem_map +
+		(pagesize - 1)) & ~(pagesize - 1));
+
+	if (__djgpp_map_physical_memory(realmem_map_aligned, ONE_MEGABYTE, 0)) {
 		free(realmem_map);
-		realmem_map = NULL;
+		realmem_map_aligned = NULL;
 		return ERROR_PTR;
 	}
 
-	return realmem_map + phys_addr;
+	return realmem_map_aligned + phys_addr;
 }
 
 static void *sys_physmap(uintptr_t phys_addr, size_t len)
@@ -72,7 +83,7 @@  static void *sys_physmap(uintptr_t phys_addr, size_t len)
 	if (!__djgpp_nearptr_enable())
 		return ERROR_PTR;
 
-	if ((phys_addr + len - 1) < (1024 * 1024)) {
+	if ((phys_addr + len - 1) < ONE_MEGABYTE) {
 		/* We need to use another method to map first 1MB. */
 		return map_first_meg(phys_addr, len);
 	}
@@ -97,8 +108,8 @@  void sys_physunmap_unaligned(void *virt_addr, size_t len)
 	/* There is no known way to unmap the first 1 MB. The DPMI server will
 	 * do this for us on exit.
 	 */
-	if ((virt_addr >= realmem_map) &&
-	    ((virt_addr + len) <= (realmem_map + (1024 * 1024)))) {
+	if ((virt_addr >= realmem_map_aligned) &&
+	    ((virt_addr + len) <= (realmem_map_aligned + ONE_MEGABYTE))) {
 		return;
 	}