Thomas Schmitt
2017-Mar-24 09:32 UTC
[syslinux] "isolinux.bin missing or corrupt" when booting USB flash drive in old PC
Hi, C/H/S addressing and reading of first block seems to be ok in isohdpfd.bin. The main suspect for the failure of the attempt with isohdpfd.bin is the number or content of the blocks read after the first one. But i have no clue why isohdpfc.bin should do better than isohdpfd.bin. They differ just by one instruction (JC = 0x72 versus JMP = 0xEB) which both are performed before the reading and should actually be equivalent on David's BIOS. MartinS wrote:> Looking at the code I see there might be a difference in CX _if_ the > EBIOS check call succeeds but doesn't return correct value in BX.Can this cause a failure to read the further 79 blocks from isolinux.bin ? ------------------------------------------------------------------ Reasoning: David Christensen wrote:> Trying isohdpfd.bin: > attached picture IMG_1578-r.JPG:The data block shown is the correct start block of isolinux.bin. Whatever happened next, it is not due to failure to address the right block. (I did not compare byte by byte. But two start lines , two end lines, and magic number FBC07870 match.)> ISOLINUX 6.03 20150819 CHDDisolinux: Image checksum error, sorry...This error message stems from isolinux.bin, not from the MBR. So we really ended up in the running boot image program. The checksum is tested with all isolinux.bin starts. From CD too. It belongs to the Boot Info Table feature inside isolinux.bin (see "man mkisofs" or libisofs-*/doc/boot_sectors.txt): Byte Range | Value | Meaning ---------- | ---------- | ---------------------------------------------------- 8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor. | | This is the session start LBA + 16. | | 12 - 15 | file_lba | Block address of the start of the boot image file | | content. Block size is 2048. | | 16 - 19 | file_len | Number of bytes in boot image file content. | | 20 - 23 | checksum | The sum of all 32-bit words of the file content | | from byte 64 to file end. | | 24 - 63 | 0 | Reserved ---------- | ---------- | ---------------------------------------------------- All numbers are stored little-endian. In the shown data (and in isolinux.bin hexdump): pvd_lba = 10 00 00 00 = 0x10 = 16 file_lba = 3F 08 00 00 = 0x83f = 2111 = 8444 / 4 file_len = 00 A0 00 00 = 0xa000 = 40960 I can confirm that these table entrys are correct for this ISO. In question is only: checksum = 31 2C D2 93 The boot info table was written by xorriso. The boot success with many systems tells us that the checksum is ok in normal situations. "-ls -l" and field "file_len" both say that in total 80 blocks should be read by the MBR. ---------- The riddle of the all zero first block is now explainable: The address conversion 8444 -> 1/6/3 matches two geometries: H/C= 128 S/H= 63 H/C= 195 S/H= 42 I would assume the first one. It would yield with the MBR bug: 8444 -> 1/2/125 which is not a valid C/H/S address under S/H=63 and thus does not have to yield a successful read operation by the BIOS. ----------- MartinS wrote:> Amazingly the size of the code in isohdpfd decreased by one byte > although it's more informative!I still did not find the spot in the Intel manual which tells me the bytes sizes of instructions and their operands. Yesterday i riddled which bytes after the DIVB instruction are the stack address: f6 36 ee 7b and whether to add or to subtract 2 with that address. Finally isohdpfc.bin told me that "ee" must become "f0" to correct the bug. (This would mean we can correct existing ISOs by this bash command echo -n $'\xf0' | dd conv=notrunc bs=1 seek=256 count=1 of=the.iso ) ----------- All old riddles seem solved now. The confusion of the two stack addresses explains the failures. The new riddle is: Why did isohdpfd.bin not load correctly the content of the following 79 blocks of isolinux.bin ? Is this reproducible in multiple attempts ? ----------- Have a nice day :) Thomas
Thomas Schmitt
2017-Mar-24 09:39 UTC
[syslinux] "isolinux.bin missing or corrupt" when booting USB flash drive in old PC
Hi, correction: i wrote:> "-ls -l" and field "file_len" both say that in total 80 blocks should > be read by the MBR.This is wrong. Only four blocks are to be read by the MBR. The others are supposed to be read by isolinux.bin itself. This takes much of the suspicion away from the MBR code. Have a nice day :) Thomas
Thomas Schmitt
2017-Mar-24 13:12 UTC
[syslinux] "isolinux.bin missing or corrupt" when booting USB flash drive in old PC
Hi, i am looking now at the code which i assume loads the rest of isolinux.bin. The entry point for program execution from the MBR is obviously at http://git.zytor.com/syslinux/syslinux.git/tree/core/isolinux.asm#n186 (Do i get it right that this is the Intel syntax ? (Gronfff)) If POP yields the victim of the most recent not yet popped PUSH, then this does not look correctly coordinated with the MBR. isohdpfx.S has: 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 */ mulw %cx /* Heads*sectors -> sectors per cylinder */ pushw %bx /* -20: EBIOS flag */ isolinux.asm has: ; The following values will have been pushed onto the ; entry stack: ; - partition offset (qword) ; - ES ; - DI ; - DX (including drive number) ; - CBIOS Heads ; - CBIOS Sectors ; - EBIOS flag ; (top of stack) _start_hybrid: pop cx ; EBIOS flag pop word [cs:bsSecPerTrack] pop word [cs:bsHeads] pop dx pop di pop es Shouldn't the sequence of pop word [cs:bsSecPerTrack] pop word [cs:bsHeads] be the reverse sequence of pushw %cx /* -16: Save sectors on the stack */ pushw %ax /* -18: Save heads on the stack */ ? Can it be that the two POPW which would need to swap places are the two byte groups "8f 06 28 30 2e" and "8f 06 2a 30 5a" near byte position 64 of isolinux.bin : fb c0 78 70 59 2e 8f 06 28 30 2e 8f 06 2a 30 5a given that isohdpfx.S has: HYBRID_MAGIC = 0x7078c0fb isolinux_hybrid_signature = 0x7c00+64 isolinux_start_hybrid = 0x7c00+64+4 (One may guess that i will propose to patch the ISO at byte 8444*512+70, if i get a "yes" on this question.) --------------------------------------------------------------------- If this is indeed the wrong sequence in isolinux.bin then the riddle arises why the second try of David with isohdpfc.bin succeeded. And why do our virtual BIOSes work ? Don't they get the fake EBIOS flag ? Can it be that isolinux.bin unconditionally first tries "getlinsec_ebios" before it defaults to "getlinsec_cbios" which is a consumer of "bsSecPerTrack" and "bsHeads" ? How can so few bytes impose so many riddles ? Have a nice day :) Thomas
Maybe Matching Threads
- "isolinux.bin missing or corrupt" when booting USB flash drive in old PC
- where to swap
- "isolinux.bin missing or corrupt" when booting USB flash drive in old PC
- [PATCH] 4k_sector: Support dynamic sectors in GPT MBR
- "isolinux.bin missing or corrupt" when booting USB flash drive in old PC