Opened 8 years ago
Closed 8 years ago
#15503 closed defect (invalid)
Floppy driver reads junk instead of real data (int 13h/0x2)
Reported by: | eider | Owned by: | |
---|---|---|---|
Component: | virtual disk | Version: | VirtualBox 5.0.20 |
Keywords: | bios, int13h, floppy | Cc: | |
Guest type: | other | Host type: | other |
Description
To begin with, here's the example code:
mov ax, 0x2000 ; 0x2000:0x0000 mov es, ax xor bx, bx ; bx == 0 mov ah, 2 ; read sectors into memory mov al, 0xCC ; magic value for build process nop nop mov ch, 0 mov cl, 2 mov dh, 0 int 13h
The code is supposed to read number of sectors starting from 0x2 using head 0 from floppy drive using floppy image file. Magic value (0xCC, nop, nop) is replaced by 0x26 in this example.
Before i go further i want to stress this out: it works on VMware and on real device!
This image shows that stage2 of bootloader was loaded correctly (0x20000)
This image shows that beginning of PE kernel file was loaded correctly (MZ header and stub). (0x24*)
This image shows that loaded data from this point is garbage. (0x24600)
This image shows rest of data that was supposed to be kernel code - somehow loaded data is stage1 (visible on previous image) and stage2 (visible on this image) of bootloader.
And finally this image compares data at 0x24600 with data from beginning of floppy disk - how the hell data from sector 0 found its way onto 0x24600 when BIOS was asked to load data starting from sector 2 into 0x20000?
I'm attaching VBox.log and ZIP archive containing floppy.flp image file i used and compressed memory dump of virtual machine you can examine.
Attachments (3)
Change History (4)
by , 8 years ago
Attachment: | osdev-2016-06-13-02-45-30.log added |
---|
by , 8 years ago
Attachment: | floppy.zip added |
---|
by , 8 years ago
Attachment: | memdump.xz added |
---|
comment:1 by , 8 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Thank you for providing the floppy image. The screenshots were really not useful, but the image was.
Your problem is that you're trying to read more sectors than there are on a track. According to Undocumented PC (2nd Ed.), the value passed in CL can not be greater than the number of sectors per track (SPT) on a given medium.
Ralf Brown's Interrupt List says: 'Most BIOSes support "multitrack" reads, where the value in AL exceeds the number of sectors remaining on the track [...]'. In other words, attempts to read past SPT will fail on some systems.
The IBM PC/AT BIOS listing says "(AL) - NUMBER OF SECTORS (NOT VALUE CHECKED)" for the value, which means the value will be given to the FDC without any validation.
FDCs can be run with the 'MT' or "Multi-Track" bit set which means they are able to start on side 0 and continue on side 1 of the same cylinder. But they do not automatically seek past that.
You are trying to read 38 sectors but the maximum that is likely to universally work is 36 (2 * 18) for a 1.44M medium and that only if you start at side 0/sector 1 of a given cylinder. But even reading past the end of a single track may fail.
As far as we know, no actual OS (Windows, DOS, Linux, OS/2, etc.) tries to do what you do, so we do not consider this a problem.