Hello,
Not so long ago, I have stumbled upon some rather disappointing behaviour in the SeaBIOS floppy driver. After some investigations, I concluded it would in fact be worthy of a bug report. So here it is.
The problem is that when SeaBIOS starts, it looks up the type of the floppy drive in firmware configuration variables and internally stores a maximum disk geometry corresponding to the type of the drive. This geometry is later used to validate interrupt 0x13 requests and internally convert them to use LBA sector numbers, which are later converted back into CHS when communicating with the floppy controller. This design – apart from being somewhat silly in itself, with the shoehorned CHS-to-LBA-to-CHS conversion – prevents using SeaBIOS’s interrupt 0x13 service with superformatted floppies, i.e. those with geometries larger than typical for the initially detected drive type, even if the drive itself could handle such floppies without problems.
Originally I ran into this problem in a VM setting, as I wanted to create and use larger-than-usual floppy images (without ever actually writing them to physical media); in QEMU source code, I noticed a table of geometries⁰ that are matched against floppy image sizes so that QEMU knows which geometry to present via the virtual floppy controller. The largest image size that is transparently handled by QEMU is 3840 KiB, corresponding to a geometry 48 sectors per track × 80 tracks × 2 sides in a ‘2880 KiB’ drive. SeaBIOS will however refuse to access sectors beyond the 36th (on whichever track), no matter what I do. And unless I remember to configure the floppy drive to use the ‘2880 KiB’ type, I am unable to access even DMF disk images (21 sect/trk × 80 trk × 2 sides) that are apparently supposed to be readable in ‘1440 KiB’ drives.
So I would like to ask that for floppy drives, the interrupt 0x13 service should skip geometry validation and the back-and-forth address conversion, and pass the CHS coordinates unmodified to the floppy controller. As I have no idea how this change would impact real hardware (I have read some reports that superformatted floppies were less reliable than normal ones and sometimes even damaged the drive), I am not asking that validation be disabled on bare metal (!CONFIG_QEMU), although I suppose it would be useful there as well.
For completeness though, I would also like to highlight XDF, which is a superformat with a non-uniform sector size. With the appropriate drivers installed, XDF disks are treated by the operating system as relatively ordinary floppies with a virtual geometry of 23 sect/trk × 80 trk × 2 sides × 512 B/sect. A virtual machine is usually able to present this geometry directly via the floppy controller (since it operates on flat disk images anyway), obviating the need for the driver, so the abovementioned workaround should be enough for a VM. On real hardware though, things are a little more complicated. Following OS/2 Museum¹:
Given XDF’s highly non-standard format, one might think that the
DOS-based XDF utilities needed to use direct FDC access. They did not—instead, they showed just how far the standard floppy BIOS services can be convinced to go.
For formatting, the BIOS user supplies a buffer containing
per-sector parameters that the FDC then transfers during execution of the FORMAT TRACK command. For reads and writes, XDF dynamically changed the DPT (Diskette Parameter Table) and used the standard BIOS read/write services to access one sector at a time.
I skimmed SeaBIOS floppy code, and apparently SeaBIOS only *sets* the DPT once at boot time with parameters like the sector size hardcoded, and later ignores it completely. Which means that if the XDF driver operates as the blog post says, it is not going to work with SeaBIOS.
I imagine modifying the floppy driver to also take the DPT into account would be much more involved, so I am not requesting that. (Not to mention that I don’t even have the hardware to test.) But it sure would be nice, so it’s probably worth being written down in a TODO list somewhere. If there’s any.
Regards, —f
⁰: https://github.com/qemu/qemu/blob/eea8f5df4ecc607d64f091b8d916fcc11a697541/hw/block/fdc.c#L112-L163 ¹: http://www.os2museum.com/wp/the-xdf-diskette-format/
On Fri, Jun 12, 2020 at 08:26:49PM +0200, felix wrote:
Hello,
Not so long ago, I have stumbled upon some rather disappointing behaviour in the SeaBIOS floppy driver. After some investigations, I concluded it would in fact be worthy of a bug report. So here it is.
The problem is that when SeaBIOS starts, it looks up the type of the floppy drive in firmware configuration variables and internally stores a maximum disk geometry corresponding to the type of the drive. This geometry is later used to validate interrupt 0x13 requests and internally convert them to use LBA sector numbers, which are later converted back into CHS when communicating with the floppy controller. This design – apart from being somewhat silly in itself, with the shoehorned CHS-to-LBA-to-CHS conversion – prevents using SeaBIOS’s interrupt 0x13 service with superformatted floppies, i.e. those with geometries larger than typical for the initially detected drive type, even if the drive itself could handle such floppies without problems.
FYI, the SeaBIOS floppy code originates from the legacy "bochs bios" implementation, which was only targeted at VM setups. It has since been extended to work on real hardware. However, the goal has only been to get standard setups working as there isn't much demand for floppies these days (even emulated floppies).
It's fine if you (or someone else) wishes to submit code to extend the floppy code. I am aware that it isn't fully "standards compliant", but no one has yet cared enough to take on the substantial work of an upgrade. If you (or someone else) does wish to take this on, it will be necessary to identify several real-world test cases for the floppy driver - both for the new features and for existing support. And be willing to run all those test cases. Testing will be crucial for any work as we don't want to introduce a regression as a trade-off to adding support for a relatively rare use case
Cheers, -Kevin
there isn't much demand for floppies these days (even emulated floppies).
I disagree: There's a big demand for emulated floppies thanks to the unique capabilities provided by them! For example: if KolibriOS (http://kolibrios.org/en/) supports your Ethernet controller and you add a KolibriOS floppy, you can access the Internet right from your BIOS and IRCC chat with your friends (maybe using a custom encryption) - all while being under an OS that's not vulnerable to the holes of mainstream OS (like Linux). And there are no alternatives to "emulated floppies" when it comes to filling the free space of your CBFS with useful stuff.
Here's my csb_patcher.sh script - https://review.coreboot.org/c/coreboot/+/33509 . In addition to some coreboot patches, it offers to download a collection of floppy images (KolibriOS, FreeDOS, MichalOS, Snowdrop, Fiwix, Memtest, Tatos, Plop, FloppyBird) and apply the unofficial SeaBIOS patches from here - https://review.coreboot.org/c/coreboot/+/32351 (advanced_bootmenu, multiple_floppies, writeprotected_usb), as well as to easily add all these floppies to a coreboot image after its' compilation. This script went through 30 revisions and a lot of people already using it, judging by the feedback - so the installbase of coreboot+SeaBIOS with emulated floppies should be pretty significant.
So the floppy-related issues like those reported by Felix - are definitely worth fixing, considering its a core functionality of SeaBIOS and one of those great features which SeaBIOS can do that Tianocore couldn't
On Mon, Jun 15, 2020 at 8:07 PM Kevin O'Connor kevin@koconnor.net wrote:
On Fri, Jun 12, 2020 at 08:26:49PM +0200, felix wrote:
Hello,
Not so long ago, I have stumbled upon some rather disappointing behaviour in the SeaBIOS floppy driver. After some investigations, I concluded it would in fact be worthy of a bug report. So here it is.
The problem is that when SeaBIOS starts, it looks up the type of the floppy drive in firmware configuration variables and internally stores a maximum disk geometry corresponding to the type of the drive. This geometry is later used to validate interrupt 0x13 requests and internally convert them to use LBA sector numbers, which are later converted back into CHS when communicating with the floppy controller. This design – apart from being somewhat silly in itself, with the shoehorned CHS-to-LBA-to-CHS conversion – prevents using SeaBIOS’s interrupt 0x13 service with superformatted floppies, i.e. those with geometries larger than typical for the initially detected drive type, even if the drive itself could handle such floppies without problems.
FYI, the SeaBIOS floppy code originates from the legacy "bochs bios" implementation, which was only targeted at VM setups. It has since been extended to work on real hardware. However, the goal has only been to get standard setups working as there isn't much demand for floppies these days (even emulated floppies).
It's fine if you (or someone else) wishes to submit code to extend the floppy code. I am aware that it isn't fully "standards compliant", but no one has yet cared enough to take on the substantial work of an upgrade. If you (or someone else) does wish to take this on, it will be necessary to identify several real-world test cases for the floppy driver - both for the new features and for existing support. And be willing to run all those test cases. Testing will be crucial for any work as we don't want to introduce a regression as a trade-off to adding support for a relatively rare use case
Cheers, -Kevin _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Thu, Jun 18, 2020 at 01:37:04PM +0300, Mike Banon wrote:
there isn't much demand for floppies these days (even emulated floppies).
And there are no alternatives to "emulated floppies" when it comes to filling the free space of your CBFS with useful stuff.
Well, I suspect for these use cases it'll be *alot* easier to add emulated harddisk support instead. That'll give you more room without having to hoop through loops to support all those strange tricks superfloppies are using ...
cheers, Gerd
Well, I suspect for these use cases it'll be *alot* easier to add emulated harddisk support instead.
It requires coding for SeaBIOS + asking the floppy OS authors to release it as an HDD image (how many will do this?) . Meanwhile, support for floppies is already there - including the double sized ones (2.88MB), it just needs an improvement
On Sat, Jun 20, 2020 at 10:12:51PM +0300, Mike Banon wrote:
Well, I suspect for these use cases it'll be *alot* easier to add emulated harddisk support instead.
It requires coding for SeaBIOS
Same is true for superfloppy support. And testing this is much more difficult. Physical floppies are pretty much dead these days, and I doubt qemu can properly emulate all those tricks which superfloppy formats are using.
Also: why invest much effort to squeeze a limited amount of additional capacity out of floppies if you can effectively remove all your capacity issues by just using hd images instead?
- asking the floppy OS authors to
release it as an HDD image (how many will do this?).
Don't they already do this? How do you boot a floppy OS without a floppy drive? Don't they have usb stick images for that? Such an image effectively is an hd image ...
Meanwhile, support for floppies is already there - including the double sized ones (2.88MB), it just needs an improvement
The superfloppy improvements I remember (probably incomplete):
(1) Most floppies and drives are tolerant enough for a few extra tracks, so use -- say -- 82 instead of 80 tracks. (2) Tweak timings a bit to squeeze one or two more sectors on each track. (3) Use 2048-sized sectors instead of 512 (less sync info needed -> more space for data). (4) Booting from 2048 sector floppies doesn't work, so use a 512-sector format for track 0 with boot block and superfloppy driver and 2048 for all other tracks.
(1) looks easy, maybe even works without code changes, and given this is all virtual anyway if we are talking about floppy images you can probably add more than just 2-3 tracks without much trouble. (2) has effects on chs calculations, so I guess that one doesn't work with seabios right now. (4) is hard for images, and (3) without (4) is useless if you want boot from these floppies, so I guess that isn't used any more these days?
take care, Gerd
On Mon 22 Jun 2020 at 10:58, Gerd Hoffmann kraxel@redhat.com wrote:
On Sat, Jun 20, 2020 at 10:12:51PM +0300, Mike Banon wrote:
Well, I suspect for these use cases it'll be *alot* easier to add
emulated harddisk support instead.
It requires coding for SeaBIOS
Same is true for superfloppy support. And testing this is much more difficult. Physical floppies are pretty much dead these days, and I doubt qemu can properly emulate all those tricks which superfloppy formats are using.
That much is true: QEMU only supports logically-addressed disk images with a uniform sector size (and probably only 512-byte sectors, I have not checked thoroughly). The floppy controller emulation code looks at the size of the disk image and tries to match it against a table of known geometries I linked in my first message; a matched geometry is then presented to the guest – as in, if the guest assumes that geometry when accessing the drive, the accesses will be dispatched to the expected logical sectors of the image. Some of those known geometries correspond to superformats.
Meanwhile in the guest, SeaBIOS does the same thing in reverse: when the floppy driver is initialised, a fixed geometry is assigned to each floppy drive[0], which is later used to validate CHS addresses and convert them into LBA[1], before dispatching the access to the floppy driver which converts LBA back into CHS when communicating with the hardware[2]. Not only is this back-and-forth rather silly, it causes problems when the geometry of the actual diskette in the drive does not match this made-up logical geometry, like when a virtual 23 × 80 × 2 disk image appears in a 1440 KiB drive (which SeaBIOS thinks should only ever deal with 18 × 80 × 2 disks).
[0]: https://git.seabios.org/cgit/seabios.git/tree/src/hw/floppy.c?h=af0daeb2687a... [1]: https://git.seabios.org/cgit/seabios.git/tree/src/disk.c?h=af0daeb2687ad2595... [2]: https://git.seabios.org/cgit/seabios.git/tree/src/hw/floppy.c?h=af0daeb2687a...
Also: why invest much effort to squeeze a limited amount of additional capacity out of floppies if you can effectively remove all your capacity issues by just using hd images instead?
In my case, the effort wasn’t all that big; all I did was patch SeaBIOS not to convert CHS addresses to LBA and back when accessing floppy drives. Less than a 100 lines of code were changed. It’s a pretty dirty hack though, and you probably won’t take it, so I wrote this report to put the issue on the record so that it can be fixed properly. I realise supporting superformats on bare hardware would be much more effort and I’m not demanding it done immediately, but it’s probably worth having on the record too.
And the reason I want to have large floppy images is that I want to use hard disk images for something else.
Regards, —f