Thu 05 Feb 2004 02:08:29 PM UTC, comment #1:
Stage 1 has two flaws related to this bug:
1. stage1.S, Line 234
mov $8,%ah
int $13
jnc final_init
Int 13, function 8, returns the capacities of the device rather than that of the inserted floppy. Thus, if you insert a 1.44 MB 3.25" floppy disk into a 2.88 MB drive, this call returns the CHS value 7F/1/24 (valid for a 2.88 disk), and following load commands translating LBA will get the wrong sectors from the 18th on.
You must check the BL register for floppy drives:
pushw %dx /* save drive number in DL */
mov $8,%ah
int $13
popw %ax
jc jump_and_die /* unrecoverable error */
or %al,%al
js final_init /* HDD */
cmp $6,%bl
jle floppy_probe /* sort out floppy drives */
final_init:
The current implementation hardly ever probes a floppy, because the drive parameters (at least for drive 0 and 1) are read from CMOS, and INT 13 should succeed as long as the drive exists. Therefore, the following bug in the floppy_probe area now is rarely triggered, but it should be fixed before making the above changes:
2. stage1.S Line 478
1:
/* perform read */
movw $STAGE1_BUFFERSEG,%bx
There is some confusion about what a segment is throughout stage 1. For instance, STAGE1_STACKSEG is loaded into %sp and is thus rather an offset (in segment %ss=0000) than a segment. STAGE1_BUFFERSEG is once used as a true segment (Line 337,338), and, on the other hand, in line 478 as an offset into a segment (%es) setup by int 13, function 8, pointing to the disk drive parameter table. Segment and offset are completely unrelated. The BIOS presumely loaded something like 0000 or 0040 into %es, the default value for STAGE1_BUFFERSEG is 0x7000, the requested buffer size is 32 KB, so having the BIOS use this buffer may result in complete destruction of the running code at 0x7C00!!
Use
movw $STAGE1_BUFFERSEG,%bx
movw %bx,%es
xorw %bx,%bx
instead.
|