[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