-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix booting from cd while hda present, booting from hda while cd present #901
base: master
Are you sure you want to change the base?
Conversation
The Bochs BIOS does not like the empty cd-rom drive. I'll investigate how it should properly report being empty. If I keep the "empty drive" status register readout to 0, seaBIOS ignores the drive but bochs BIOS hangs. |
It looks like the ata command sending code in bochs doesn’t like how our buffer-less cdrom drive is reporting its state register, so it waits forever before sending the IDENTIFY PACKET DEVICE ATA command. I’ll investigate what’s going on Monday or Tuesday but my suspicion is that the current approach of hard coding one value to send for empty drives is not going work. Rough summary: bochs checks for the status to be not-busy, then sends a command and waits for the device to be not-busy and yes-drq. |
Sorry for the spam. I think the path of least resistance here is to add a setting for “wants_cdrom” which defaults to true if cdrom is non-null, and a cdrom device should only be created if cdrom is defined or wants_cdrom is true. The bochs empty cdrom boot behavior really should be a separate PR aimed at #900 . |
Whoops, and I’ll revert my changes to the html files and main.js. |
I’ve trimmed down the changes made by this commit (I left the changes to logging because they’re actually pretty useful) to just changing the BAR4 location for each IDE device and not asserting on a spurious dma control write that occurs before a dma start command arrives (this is something some OSes or maybe seabios seem to do but it doesn’t seem to cause any harm to allow it, I guess they’ll try to trigger it again after it doesn’t do anything the first time—I wonder if a better fix would be for the start dma commands to start the dma transfer immediately if the control start bit was set already). I’ll do some more testing locally (I figured out how to run the integration tests locally and added test machines with both hda and cdrom and booting from one or the other) and I’ll push a commit over the next day or two. |
The main changes necessary to make this work were, in the end:
The wants_cdrom change is not strictly necessary here but will be important for my next PR which will support empty CD-ROMs, so please consider rolling it in to this. |
I've gone ahead and added tests for booting with wants_cd true when Bochs bios is active (and inactive) and with varying permutations of hda, fda, and boot order in FreeDOS. It now boots successfully with an empty CD-ROM in both BIOSes. The problem is that Bochs was enumerating the slave device of every IDE device, but the slave device was seemingly never fully implemented (?)---so instead I have dummied out writes to slave devices when the slave buffer is null. |
With these changes, CDs are also readable by at least FreeDOS 13 with the UDVD2 driver. They don’t seem to be readable in win95. I’m going to see if I can implement inserting and ejecting disks later this week. |
I've rebased this branch on latest master and removed unnecessary changes. eject is still in progress, but insert seems to work (I can boot FreeDOS 1.3 with an empty CD-ROM, see |
48749a8
to
60a2f9d
Compare
… disk image is present
…h floppy eject insert
load_image takes an image file descriptor (like you'd find in a V86 option like `hda` or `cdrom`) and returns a Promise which will resolve with a full image description (including a `buffer` field which is a buffer type from buffer.js). This currently duplicates a bunch of logic from starter's `continue_init` function, but I hope in the future that could be refactored out. The main sticking point is progress reporting, which would need to do something like add up the total sizes across all images and increment a counter as new bytes come in, but I wanted to keep this commit focused.
Note that the progress indicator won't show the correct total number of files anymore. This should be fixed in the future by loading files in parallel and counting progress against the overall total number of bytes rather than the number of bytes in the current file.
60a2f9d
to
bdf6cce
Compare
@JoeOsborn Thanks! I will try to look into this in the coming days. |
I see my api-test is hanging, it was tricky to get the timing of abort/retry/fail and inserting the CD right. It works on my machine but I’m open to advice on getting it working in CI. |
Sorry @copy , I don’t want to use up your CI credits or whatever, but I don’t know how to kill the actions jobs from my end. |
After more testing, I see that ejecting a CD-ROM and inserting a new one also seems to work. |
This causes some problems on Linux: There are some 0-bytes drives:
There are some timeouts, e.g. running
You should be able to reproduce with tinycore (it can be used both as cdrom and hard drive disk). |
@@ -1369,6 +1372,7 @@ | |||
"hda": settings.hda, | |||
"hdb": settings.hdb, | |||
"cdrom": settings.cdrom, | |||
"wants_cdrom": settings.wants_cdrom, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think cdrom: { ejected: true }
would be a clearer api for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m happy to defer to you here, I’ll make that change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think cdrom: { ejected: true }
makes sense for the starter options, but it's a bit tricky inside of cpu and so on if the settings
object is either a buffer or null or {ejected: true}
. Should there be a new EmptyBuffer
buffer type? Or can wants_cdrom
continue to exist within the emulator settings, even if it's not part of public API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, internally wants_cdrom
is fine (it can be refactored at any point anyway)
<td> | ||
<input id="wants_cdrom" type="checkbox"><br> | ||
</td> | ||
</tr> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you revert this for now? It's confusingly named, can cause problems with the state saving mechanism, and I'd like to eventually redo the UI anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok!
To clarify on the linux issues, is this the set of test cases you’re using?
|
@JoeOsborn Sorry, here is a better reproduction: Boot with linux4.iso as cdrom and tinycore (or anything else) as hard drive, set boot order to CD first. |
Something I’m finding confusing here is that linux seems to be configuring the drive to use DMA even though the capabilities reported are lba-only. I think maybe the OS is waiting for some status flag to be set or something, or else it’s ignoring irqs that come in too soon after the command is sent, since liberally adding irqs didn’t seem to help. Any tips for triggering an IRQ after some delay? |
You can try |
Just posting to say I'm still investigating this, but the beginning of the semester has slowed down my experiments here. Once I've settled into teaching a little more I'll have another chance to get back to it. |
It’s not abandoned, but it is delayed. I likely won’t be able to pick it up until January—it is on my critical path for some preservation work, but other aspects of the project (and my other obligations) have taken the front seat for a while. |
That's fair enough, thank you for getting back to me. |
Does anyone know if this is still being actively worked on? |
Probably nobody, but feel free to pick it up. |
This is towards #900: We can now boot either from HDA or CDROM, with the other present, and it boots successfully. For testing I'm booting into Windows 3.0 (from CD) with Windows 3.1 on hda or from Windows 3.1 (on hda) with Windows 3.0 in the cdrom.
One big change here: The cd-rom device is now always present, either at ide0 or ide1 depending on whether hda/hdb are present. Of course we can still boot (at least into Windows) if you only have hda and an empty cdrom, or don't have hda and just have a cdrom.