Yes, we did replace the IDE driver with our own implementation. But you
can apply this patch that was posted long ago on the list that takes
care of it on regular QEMU. It will slow things down a bit, so you may
want to disable it, so you may want to optimize it or disable it after
you get Windows 2000 installed, but it works. The issue seems to be the
fact that the install-time Windows 2000 IDE driver doesn't like write
operations generating an interrupt too quickly (i.e. before the "out" or
DMA transfer returns). It doesn't seem to have this issue after the
base OS is installed and booted however, but your experience may vary.
Attached is the patch that we found on the list. It applies both to
0.6.1 and 0.6.2, albeit with some possible hunks.
Best regards,
Leo Reiter
Hetz Ben Hamo wrote:
Hi Leonardo,
I have tried to install win2k from various CD's I have here around and
I stumbled on one really weird thing..
Disk space issues. I have tried with 1GB, 2GB and 4GB virtual disks,
and all of them seems to be quickly filled by the win2k installer and
then the install fails..
Do you also have the same problem there at win4lin? or is it only
happening with QEMU's internal IDE drive emulation? (since I recall
that win4lin replaced the IDE driver with their own's one)..
Thanks,
Hetz
------------------------------------------------------------------------
diff -rbu qemu.orig/hw/ide.c qemu/hw/ide.c
--- qemu.orig/hw/ide.c 2004-12-02 23:20:21.000000000 +0300
+++ qemu/hw/ide.c 2004-12-17 14:06:15.000000000 +0300
@@ -332,8 +332,12 @@
uint8_t *data_ptr;
uint8_t *data_end;
uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
+ int ide_set_irq_from_timer;
} IDEState;
+volatile int ide_set_irq_from_timer;
+static IDEState *IDEStates[4];
+
#define BM_STATUS_DMAING 0x01
#define BM_STATUS_ERROR 0x02
#define BM_STATUS_INT 0x04
@@ -512,6 +516,21 @@
}
}
+void make_ide_set_irq(void)
+{
+ int i;
+ IDEState *s;
+
+ ide_set_irq_from_timer--;
+ for(i = 0; (s=IDEStates[i]) != NULL; i++) {
+ if(s->ide_set_irq_from_timer) {
+ s->ide_set_irq_from_timer--;
+ ide_set_irq(s);
+ break;
+ }
+ }
+}
+
/* prepare data transfer and tell what to do after */
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
EndTransferFunc *end_transfer_func)
@@ -667,7 +686,11 @@
ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
}
ide_set_sector(s, sector_num + n);
+ if(s->ide_set_irq_from_timer) {
+ ide_set_irq_from_timer++;
+ } else {
ide_set_irq(s);
+ }
}
static int ide_write_dma_cb(IDEState *s,
@@ -1511,6 +1534,7 @@
s->error = 0;
s->status = SEEK_STAT | READY_STAT;
s->req_nb_sectors = 1;
+ s->ide_set_irq_from_timer = 1;
ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
break;
case WIN_MULTREAD:
@@ -1528,6 +1552,7 @@
n = s->nsector;
if (n > s->req_nb_sectors)
n = s->req_nb_sectors;
+ s->ide_set_irq_from_timer = 1;
ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
break;
case WIN_READDMA:
@@ -1883,6 +1908,7 @@
for(i = 0; i < 2; i++) {
s = ide_state + i;
+ IDEStates[drive_serial-1] = s;
if (i == 0)
s->bs = hd0;
else
diff -rbu qemu.orig/vl.c qemu/vl.c
--- qemu.orig/vl.c 2004-12-13 01:20:04.000000000 +0300
+++ qemu/vl.c 2004-12-17 12:41:16.000000000 +0300
@@ -911,7 +911,7 @@
/* timer signal */
sigfillset(&act.sa_mask);
- act.sa_flags = 0;
+ act.sa_flags = SA_RESTART;
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
act.sa_flags |= SA_ONSTACK;
#endif
@@ -2403,7 +2403,12 @@
int n, max_size;
#endif
int ret;
+ /* ide.c hack */
+ extern volatile int ide_set_irq_from_timer;
+ extern void make_ide_set_irq(void);
+ if(ide_set_irq_from_timer)
+ make_ide_set_irq();
#ifdef _WIN32
if (timeout > 0)
Sleep(timeout);
@@ -2449,8 +2454,6 @@
n = read(ioh->fd, buf, ioh->max_size);
if (n >= 0) {
ioh->fd_read(ioh->opaque, buf, n);
- } else if (errno != EAGAIN) {
- ioh->fd_read(ioh->opaque, NULL, -errno);
}
}
}
------------------------------------------------------------------------
_______________________________________________
Qemu-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/qemu-devel