aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-10-30 10:53:44 -0800
committerH. Peter Anvin <hpa@zytor.com>2006-10-30 10:53:44 -0800
commitb4764f968327b77178d0f8b21e65640420b8fec3 (patch)
tree716f69654f59b0e9be8850e4fe02e2f9041e2a68
parent02131f189f079ff3cbf0ad2cb6078ba28871b62f (diff)
downloadsyslinux-elf-syslinux-3.32-pre4.tar.gz
syslinux-elf-syslinux-3.32-pre4.tar.xz
syslinux-elf-syslinux-3.32-pre4.zip
memdisk: Constrain input drive numbers both by equipment byte and INT 13hsyslinux-3.32-pre4
Apparently on some BIOSes, INT 13h return a bogus number of floppy drives when the real value is zero (probably because the code doesn't check the validity bit in the equipment byte.) Do it ourselves if we need to.
-rw-r--r--memdisk/setup.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 556d1996..f29325a1 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -551,6 +551,7 @@ void setup(syscall_t cs_syscall, void *cs_bounce)
int total_size, cmdlinelen;
com32sys_t regs;
uint32_t ramdisk_image, ramdisk_size;
+ int bios_drives;
/* Set up global variables */
syscall = cs_syscall;
@@ -723,11 +724,28 @@ void setup(syscall_t cs_syscall, void *cs_bounce)
if ( regs.eflags.l & 1 ) {
printf("INT 13 08: Failure, assuming this is the only drive\n");
- pptr->drivecnt = 1;
+ pptr->drivecnt = 0;
} else {
printf("INT 13 08: Success, count = %u, BPT = %04x:%04x\n",
regs.edx.b[0], regs.es, regs.edi.w[0]);
- pptr->drivecnt = regs.edx.b[0]+1;
+ pptr->drivecnt = regs.edx.b[0];
+ }
+
+ /* Compare what INT 13h returned with the appropriate equipment byte */
+ if ( geometry->driveno & 0x80 ) {
+ bios_drives = rdz_8(BIOS_HD_COUNT);
+ } else {
+ uint8_t equip = rdz_8(BIOS_EQUIP);
+
+ if (equip & 1)
+ bios_drives = (equip >> 6)+1;
+ else
+ bios_drives = 0;
+ }
+
+ if (pptr->drivecnt > bios_drives) {
+ printf("BIOS equipment byte says count = %d, go with that\n", bios_drives);
+ pptr->drivecnt = bios_drives;
}
/* Discontiguous drive space. There is no really good solution for this. */