In accord with the El Torito specification[1], SeaBIOS now signals
failure (AH=1 and CF) whenever attempts are made to terminate disk
emulation (0x4B) for non-emulated drives. The prior behavior of always
returning success caused the Solaris 9 Device Configuration
Assistant (DCA) diskette (d1_image) to fail to boot as it was unable
to access the non-existent underlying drive.
References:
[1]: "CF - Clear if system released
CF - Set if system not in emulation mode"
C. E. Stevens and S. Merkin, '"El Torito" Bootable CD-ROM Format
Specification', Phoenix Technologies and IBM, 1994, p. 17.
Signed-off-by: Lev Kujawski <[email protected]>
---
src/disk.c | 82 ++++++++++++++++++++++++++++++------------------------
1 file changed, 46 insertions(+), 36 deletions(-)
diff --git a/src/disk.c b/src/disk.c
index 14a99db..6a25015 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -568,6 +568,33 @@ disk_1349(struct bregs *regs, struct drive_s *drive_fl)
regs->ah = DISK_RET_ECHANGED;
}
+// El Torito - Terminate disk emulation
+static void
+disk_134b(struct bregs *regs, struct drive_s *drive_fl)
+{
+ if (CONFIG_CDROM_BOOT && regs->dl == GET_LOW(CDEmu.emulated_drive)) {
+ if ((regs->dl >= EXTSTART_CD) ||
+ (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)))
+ {
+ memcpy_far(regs->ds, (void*)(regs->si+0),
+ SEG_LOW, &CDEmu, sizeof(CDEmu));
+
+ // If we have to terminate emulation
+ if (regs->al == 0x00) {
+ // FIXME ElTorito Various. Should be handled accordingly to
spec
+ SET_LOW(CDEmu.media, 0x00); // bye bye
+
+ // XXX - update floppy/hd count.
+ }
+
+ disk_ret(regs, DISK_RET_SUCCESS);
+ return;
+ }
+ }
+
+ disk_ret(regs, DISK_RET_EPARAM);
+}
+
static void
disk_134e01(struct bregs *regs, struct drive_s *drive_fl)
{
@@ -650,6 +677,7 @@ disk_13(struct bregs *regs, struct drive_s *drive_fl)
case 0x47: disk_1347(regs, drive_fl); break;
case 0x48: disk_1348(regs, drive_fl); break;
case 0x49: disk_1349(regs, drive_fl); break;
+ case 0x4b: disk_134b(regs, drive_fl); break;
case 0x4e: disk_134e(regs, drive_fl); break;
default: disk_13XX(regs, drive_fl); break;
}
@@ -675,23 +703,6 @@ floppy_13(struct bregs *regs, struct drive_s *drive_fl)
}
}
-// ElTorito - Terminate disk emu
-static void
-cdemu_134b(struct bregs *regs)
-{
- memcpy_far(regs->ds, (void*)(regs->si+0), SEG_LOW, &CDEmu, sizeof(CDEmu));
-
- // If we have to terminate emulation
- if (regs->al == 0x00) {
- // FIXME ElTorito Various. Should be handled accordingly to spec
- SET_LOW(CDEmu.media, 0x00); // bye bye
-
- // XXX - update floppy/hd count.
- }
-
- disk_ret(regs, DISK_RET_SUCCESS);
-}
-
/****************************************************************
* Entry points
@@ -743,27 +754,26 @@ handle_13(struct bregs *regs)
debug_enter(regs, DEBUG_HDL_13);
u8 extdrive = regs->dl;
- if (CONFIG_CDROM_EMU) {
- if (regs->ah == 0x4b) {
- cdemu_134b(regs);
- return;
- }
- if (GET_LOW(CDEmu.media)) {
- u8 emudrive = GET_LOW(CDEmu.emulated_drive);
- if (extdrive == emudrive) {
- // Access to an emulated drive.
- struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf);
- if (regs->ah > 0x16) {
- // Only old-style commands supported.
- disk_13XX(regs, cdemu_gf);
- return;
- }
+ if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)) {
+ const u8 emudrive = GET_LOW(CDEmu.emulated_drive);
+
+ if (extdrive == emudrive) {
+ // Access to an emulated drive.
+ struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf);
+
+ if (regs->ah <= 0x16 || regs->ah == 0x4b) {
disk_13(regs, cdemu_gf);
- return;
+ } else {
+ // Only old-style commands supported.
+ disk_13XX(regs, cdemu_gf);
}
- if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0)
- // Adjust id to make room for emulated drive.
- extdrive--;
+
+ return;
+ }
+
+ if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0) {
+ // Adjust id to make room for emulated drive.
+ extdrive--;
}
}
handle_legacy_disk(regs, extdrive);
--
2.34.1
_______________________________________________
SeaBIOS mailing list -- [email protected]
To unsubscribe send an email to [email protected]