[syslinux] "isolinux.bin missing or corrupt" when booting USB flash drive in old PC

Martin Str|mberg
Fri, 24 Mar 2017 18:55:58 -0000

On Fri, Mar 24, 2017 at 05:38:31PM +0100, Thomas Schmitt via Syslinux
wrote:
> isohdpfc pushes the CX value to the stack which it gets from INT 13 AH 41.
> Quite surely bit 0 of that CX is not set. But bit 2 "Enhanced Disk
Drive"
> could be set.
>   https://en.wikipedia.org/wiki/INT_13H
>
> I understand on David's BIOS after
>
>         andw    $1,%cx          /* Bit 0 = fixed disk subset */
>         jz      1f
>
> jz jumps because CX is 0. This gets pushed to the stack.
> (So the code around the int 13 assumes that either int 13 fails and returns
>  CX == 0, or the reply is good enough to reach "andw 1,%cx". Ewww
...)

Well... I'm not quite following you.
If it reaches andw 1,%cx then CX will indicate if wanted EBIOS calls
are supported or not as the and will mask away all but the interesting
bit.


The code:
        /* Check to see if we have EBIOS */
        pushw   %dx             /* drive number */
        movb    $0x41, %ah      /* %al == 0 already */
        movw    $0x55aa, %bx
        xorw    %cx, %cx
        xorb    %dh, %dh
        stc
        int     $0x13
        jc      1f
        cmpw    $0xaa55, %bx
        jne     1f
        andw    $1,%cx
        /* Bit 0 = fixed disk subset */
        jz      1f

        /* We have EBIOS; patch in the following code at
           read_sector_cbios: movb $0x42, %ah ;  jmp read_common */
        movl    $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
                (read_sector_cbios)
        jmp     1f
1:


This is my interpretation:

David's machine's BIOS returns no carry indicating maybe
support. However it doesn't set BX to the correct value, so isohdpfx.S
jumps to 1f with some flags in CX set.

Or David's machine's BIOS returns carry but corrupts CX.

My versions of isohdpfc just replaced the first "jc 1f" above with
"jnc 1f" or with "jmp 1f", thus in the end possibly
indicating EBIOS
support to isolinux (assuming weird return status on the EBIOS check).

Then I interpret the code in isolinux that when EBIOS calls doesn't
work it will fall back to old not extended calls (CBIOS?). That's why
it worked after a delay.


Your findings in isohdpfx.S made clear it confused/is wrong with
regard to order of number of heads and sectors on the stack. Either
the declared offsets were wrong or the order of pushes. At that time I
choose the order of pushes as the correct way.

Good work digging in the code again (isolinux.asm). Yes, it's Intel
syntax, or more specifically nasm syntax (in case it matters).

Now given your findings in isolinux.asm  it seems that previous choice
was wrong and the declared offsets were correct.

Thus a new patch that corrects the order of pushes (instead of
offsets) _and_ setting CX to zero if EBIOS detection fails. Apply it
to orginal syslinux code.

diff --git a/mbr/isohdpfx.S b/mbr/isohdpfx.S
index 17e1efe..14eca14 100644
--- a/mbr/isohdpfx.S
+++ b/mbr/isohdpfx.S
@@ -151,7 +151,7 @@ next:

 	/* Check to see if we have EBIOS */
 	pushw	%dx		/* drive number */
-	movb	$0x41, %ah	/* %al == 0 already */
+	movb	$0x41, %ah
 	movw	$0x55aa, %bx
 	xorw	%cx, %cx
 	xorb	%dh, %dh
@@ -167,20 +167,22 @@ next:
 	   read_sector_cbios: movb $0x42, %ah ;  jmp read_common */
 	movl	$0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
 		(read_sector_cbios)
-	jmp	1f
+	jmp	2f
 1:
+	xor	%cx, %cx	/* Clear EBIOS flag. */
+2:
 	popw	%dx
 	pushw	%cx		/* EBIOS flag */

 	/* Get (C)HS geometry */
 	movb	$0x08, %ah
 	int	$0x13
-	andw	$0x3f, %cx	/* Sector count */
 	popw	%bx		/* EBIOS flag */
-	pushw	%cx		/* -16: Save sectors on the stack */
 	movzbw	%dh, %ax	/* dh = max head */
 	incw	%ax		/* From 0-based max to count */
-	pushw	%ax		/* -18: Save heads on the stack */
+	pushw	%ax		/* -16: Save heads on the stack */
+	andw	$0x3f, %cx	/* Sector count */
+	pushw	%cx		/* -18: Save sectors on the stack */
 	mulw	%cx		/* Heads*sectors -> sectors per cylinder */

 	pushw	%bx		/* -20: EBIOS flag */


I suppose you'd want a .bin as well:
<http://www.ludd.ltu.se/~ams/tmp/isohdpfx.bin.170324>


--
MartinS