If you don't mind me asking, do you have an offsite repository (on a hosting site such as GitHub, Sourceforge, or Gitlab) where we could look over your code? Keeping a VCS repo is highly recommended anyway, but if we have any reason to help you with the code itself, it would save you and us a lot of trouble. I know I harp on this topic a lot, but it really does help.
Also, what language are you implementing your OS in? This is just curiosity on my part, though it may be relevant W.R.T. how practical implementing a USB driver will be (e.g., if you are writing everything in assembly, it would be possible but would be a massive effort).
Finally, could you tell us a bit about your test platform? I am specifically wondering how old the PC (particularly the motherboard and CPU) is.
With that out of the way, back to the topic at hand.
One more option for the short term, if you aren't already doing so, is to hold off on physical hardware for the time being and use an emulator or virtualizer (Bochs, QEMU, VirtualBox, etc.) which allows you to treat a file image on your system storage as if it were a physical disk, which you can define as needed (floppy drive, hard disk, CD-ROM, USB drive, etc.). You can even mount the USB drive live on most virtualizers, though you'd have the same issue you are facing now.
While this is only a short term solution, it would allow you to test your OS's kernel drivers, and get your file system code in order, before then trying to
implement a USB stack.
I am guessing that this is what you've been doing already for developing your system to the point you have it at now, but I felt it would be remiss if I didn't at least bring this up. The file system code is (or usually should be)
largely independent of the storage drivers (I hope Ben appreciates me recommending his books), so it makes sense to get the high-level file system debugged before trying to implement the more complex drive interfaces.
That having been said, I wouldn't recommend using a FAT12 file system on real hardware today, anyway, if only because you'd be limited to a very small maximum disk size (127 MiB using a standard sector size of 512). Even older USB drives are generally a great deal larger than that.
As for the other options:
- I would recommend against implementing V86 mode for the purpose of accessing the BIOS; it is almost as difficult to implement as the USB drivers you are hoping to avoid writing. In any case, as I explain below regarding UEFI, this isn't going to be feasible on newer systems anyway, as they don't have any BIOS to call.
- A RAMDisk would be a good deal simpler to work with, but it leads to a chicken and egg problem: you'd need a RAMdisk large enough to hold the entire disk image, but you'd need to be able to do this in real mode, before you'd have access to the full 32-bit memory space. Unless you happen to be using an 360KiB disk image, this simply isn't going to be possible.
- UEFI is where all (or at least most) real hardware is going, and if you are intending to work on live machines newer than 2019, you won't have the Legacy BIOS available to you (since the Compatibility Support Module - the UEFI legacy boot support - was phased out for new Intel and AMD firmware as of 2020). Sooner or later, you'll need to switch to UEFI booting, so it may be worth looking towards now - though in that case, you won't be using FAT12 anyway; my understanding is that UEFI GPT only works for partitionable drive types, and requires at least one 100MiB FAT32 partition for the GPT. The good news is, the UEFI Boot Services can start you directly in protected mode (or even long mode, for 64-bit systems), and at boot time will load any files you need to load for the OS itself; the bad news is that these services are only usable before you hand control over to the OS kernel.
In the end, I wouldn't see booting a FAT12 system on live hardware as a practical move, period. While it is good as an exercise (
which is why I am doing it now myself), it is something best relegated to emulation, as it won't even be feasible on most modern computer hardware.