[syslinux] "isolinux.bin missing or corrupt" when booting USB flash drive in old PC
Gene Cumm
gene.cumm at gmail.com
Sun Mar 26 04:33:39 PDT 2017
On Fri, Mar 24, 2017 at 2:55 PM, Martin Str|mberg via Syslinux
<syslinux at zytor.com> wrote:
> 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 */
Martin/Thomas: Thank you for your troubleshooting efforts. Looks like
I jumped a little too soon. I started doing git blame on
core/isolinux.asm and mbr/isohdpfx.S and it seems the stack format got
set, changed, then mostly reverted back, with this code being the last
piece missing from 2009. I started second-guessing if there was yet
another but it appears fine. I just want to run some tests.
David, thank you for working with them to diagnose your computer. As
you're probably aware, diagnosing system-specific bugs are always
challenging and finding representative hardware to reproduce an issue
isn't always easy (or sometimes even feasible). Finding a system that
doesn't seem to properly support LBA/EBIOS reads is increasingly
difficult due to age.
--
-Gene
More information about the Syslinux
mailing list