--- hw/pc.c Mon Mar 5 14:44:02 2007 +++ hw/pc.c Wed Mar 7 13:37:37 2007 @@ -42,6 +42,24 @@ static IOAPICState *ioapic; static PCIDevice *i440fx_state; +#define LINUX_BOOT_TIME 1000 +static QEMUTimer *linux_boot_timer; +static void linux_boot_cleanup(void *opaque) +{ + if (opaque == NULL) + { + /* using ram bs */ + bdrv_close(fd_table[0]); + } + else + { + /* there is a real floppy underneath */ + bdrv_set_boot_sector(fd_table[0], opaque, 512); + qemu_free(opaque); + } + qemu_free_timer(linux_boot_timer); +} + static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { } @@ -457,6 +475,7 @@ int piix3_devfn = -1; CPUState *env; NICInfo *nd; + int using_ram_bs = 0; linux_boot = (kernel_filename != NULL); @@ -566,10 +585,10 @@ if (linux_boot) { uint8_t bootsect[512]; - uint8_t old_bootsect[512]; + uint8_t *old_bootsect = NULL; - if (bs_table[0] == NULL) { - fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n"); + if (fd_table[0] == NULL) { + fprintf(stderr, "This should never happen!\n"); exit(1); } snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME); @@ -580,12 +599,29 @@ exit(1); } - if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) { - /* copy the MSDOS partition table */ - memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40); + old_bootsect = qemu_mallocz(512); + if (old_bootsect == NULL) + { + fprintf(stderr, "qemu: not enough ram to allocate 512 bytes\n"); + exit(1); + } + if (bdrv_read(fd_table[0], 0, old_bootsect, 1) >= 0) { + using_ram_bs = 0; + } else { + using_ram_bs = 1; + if (bdrv_open(fd_table[0], "ram:63", 0) < 0) + { + printf("Another thing which should never happen, happened..\n"); + exit(1); + } + qemu_free(old_bootsect); + old_bootsect = NULL; } - bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect)); + bdrv_set_boot_sector(fd_table[0], bootsect, sizeof(bootsect)); + /* implied by using a kernel boot */ + boot_device = 'a'; + fd_bootchk = 0; /* now we can load the kernel */ ret = load_kernel(kernel_filename, @@ -618,6 +654,11 @@ KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR); /* loader type */ stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01); + + linux_boot_timer = qemu_new_timer(rt_clock, linux_boot_cleanup, + using_ram_bs ? NULL : old_bootsect); + qemu_mod_timer(linux_boot_timer, qemu_get_clock(rt_clock) + + LINUX_BOOT_TIME); } if (pci_enabled) {