[syslinux] Re: [Freedos-devel] Problem with FreeDOS + himem64 + PXELINUX + memdisk

Patrick J. LoPresti patl at users.sourceforge.net
Tue Jan 27 14:01:44 PST 2004


I believe I have solved my own problem.

(I am CC'ing syslinux at zytor.com for complete archives, but please
direct additional followups to freedos-devel since this is definitely
not a SYSLINUX problem.)

I have been experimenting with my own himem sources.  I applied the
following patch to himem64.asm:

======================================================================
--- himem64.asm	2004/01/27 20:42:43	1.1
+++ himem64.asm	2004/01/27 21:25:00	1.2
@@ -276,6 +276,8 @@
                             ; has to be requested
 a20_locks   dw  0           ; internal A20 lock count
 
+a20state    db  ?           ;  keeps A20 state across INT15h call
+
 xms_handle_start dw normal_driver_end
 
 
@@ -361,14 +363,27 @@
 proc enable_a20
 	push ax
 	mov  ah,2
-	jmp short disable_enable_a20
+	call disable_enable_a20
+        pop ax
+        ret
 
 disable_a20:
 	push ax
 	mov  ah,0
+	call disable_enable_a20
+        push cx
+        mov cx,32
+@@delayloop:
+        call test_a20
+        jz @@disabled
+        loop @@delayloop
+@@disabled:
+        pop cx
+        pop ax
+        ret
 
 disable_enable_a20:
-
+     push ax
      mov al,0d1h
      out 64h,al
      call delay
@@ -491,10 +506,35 @@
 ;
 
 proc    int15_handler
+    cmp ah,87h
+    je do_move
     cmp ah,88h              ; is it a ext. mem size req.?
     je  ext_mem_size
     jmp [cs:old_int15]          ; jump to old handler
 
+do_move:
+	call	test_a20			; check if A20 is on or off
+	jz	@@a20disabled
+	mov	[cs:a20state],1			; preserve state
+	jmp	@@call_old_mover
+@@a20disabled:
+	mov	[cs:a20state],0
+@@call_old_mover:
+	pushf					; simulate INT call
+	call	[cs:old_int15]
+	pushf					; save flags for return
+	push	ax
+	cmp	[cs:a20state],0			; see if A20 has to be switched
+	jz	@@disable_it
+	call	enable_a20
+	jmp	@@move_done
+@@disable_it:
+	call	disable_a20
+@@move_done:
+	pop	ax
+	popf
+	iret
+        
 ext_mem_size:
     xor ax,ax               ; no memory available
     clc                 ; no error

======================================================================

This patch does two things.

First, I stole the "save/restore A20 on INT15/AH=87" logic from FDXMS.
Judging by the comments at the top of himem64.asm, this logic used to
exist in himem64.exe as well; it is not clear why it was removed.
With this change, my "instant" crashes on the Thinkpad T20 went away!
But it still crashed somewhat later while running commands from
autoexec.bat.

Second, I stole the "delay on A20 disable" logic from memdisk.  This
made all of the crashes stop!  That is, it resulted in a himem64.exe
which works the same when invoked from PXELINUX+memdisk (with
DOS=HIGH) as it does from a floppy (or without DOS=HIGH).

Unfortunately, on my Thinkpad T20, the keyboard still locks up pretty
quickly in all of these scenarios.

The following additional patch fixes everything on my T20:

======================================================================
--- himem64.asm	2004/01/27 21:25:00	1.2
+++ himem64.asm	2004/01/27 21:37:33
@@ -362,15 +362,24 @@
 
 proc enable_a20
 	push ax
-	mov  ah,2
-	call disable_enable_a20
+        mov ax,2401h
+        pushf
+        int 15h
+        popf
+        
+;	mov  ah,2
+;	call disable_enable_a20
         pop ax
         ret
 
 disable_a20:
 	push ax
-	mov  ah,0
-	call disable_enable_a20
+        mov ax,2400h
+        pushf
+        int 15h
+        popf        
+;	mov  ah,0
+;	call disable_enable_a20
         push cx
         mov cx,32
 @@delayloop:
======================================================================

This patch uses the BIOS (INT15/AX=2400 and 2401) interface to
enable/disable A20.  With this additional patch, everything works
flawlessly on my T20.

...but it breaks on my Optiplex GX200, presumably because its BIOS
does not support INT15/AX=2400.

The ultimate solution, in my opinion, is to steal all of the logic
from memdisk (init32.asm) for doing A20 switching.  The logic goes:

  1) See if there is no A20 gate; if so, use NOOP to disable/enable
     A20

  2) See if the BIOS interface works (INT15/AX=2401); if so, use that.

  3) See if the keyboard controller mechanism works (this is the
     mechanism himem64.exe currently uses always); if so, use that.

  4) See if the "fast A20 gate" mechanism works; if so, use that.

  5) Retry steps 1-4 255 times...

  6) ...if that does not work, bomb out.

I believe himem64.exe would support the widest variety of systems if
it incorporated all of this logic.  But steps (2) and (3) are
mandatory for me.  I believe the BIOS interface is superior to using
PS/2 switching, since according to Ralf Brown's Interrupt List later
PS/2s support the BIOS interface anyway.

I am willing to write the code to support all this if the himem
maintainer(s) are amenable to accepting patches.  Although you will
probably want to clean up my assembly first :-).

Comments?

 - Pat




More information about the Syslinux mailing list