From: Anthony Liguori <[EMAIL PROTECTED]> This patch adds support to QEMU for extboot. It requires that an extboot.bin binary be copied into the pc-bios directory or else make install will not function properly.
To use extboot to boot from an arbitrary block device, simply append a ",boot=on" to the block device to boot from. For instance, to boot from a SCSI disk, one would use: -drive file=/path/to/image.img,if=scsi,boot=on Signed-off-by: Anthony Liguori <[EMAIL PROTECTED]> Signed-off-by: Avi Kivity <[EMAIL PROTECTED]> diff --git a/qemu/Makefile b/qemu/Makefile index ce76352..a3c6870 100644 --- a/qemu/Makefile +++ b/qemu/Makefile @@ -179,7 +179,7 @@ endif mkdir -p "$(DESTDIR)$(datadir)" for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ video.x openbios-sparc32 pxe-ne2k_pci.bin \ - pxe-rtl8139.bin pxe-pcnet.bin; do \ + pxe-rtl8139.bin pxe-pcnet.bin extboot.bin; do \ $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \ done ifndef CONFIG_WIN32 @@ -281,6 +281,7 @@ tarbin: $(datadir)/pxe-ne2k_pci.bin \ $(datadir)/pxe-rtl8139.bin \ $(datadir)/pxe-pcnet.bin \ + $(datadir)/extboot.bin \ $(docdir)/qemu-doc.html \ $(docdir)/qemu-tech.html \ $(mandir)/man1/qemu.1 $(mandir)/man1/qemu-img.1 ) diff --git a/qemu/Makefile.target b/qemu/Makefile.target index 0c5ca47..289cd18 100644 --- a/qemu/Makefile.target +++ b/qemu/Makefile.target @@ -471,7 +471,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o VL_OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o -VL_OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o +VL_OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE endif ifeq ($(TARGET_BASE_ARCH), ia64) diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c index 5a1b7d4..aa9e16e 100644 --- a/qemu/hw/pc.c +++ b/qemu/hw/pc.c @@ -43,6 +43,7 @@ extern int kvm_allowed; #define BIOS_FILENAME "bios.bin" #define VGABIOS_FILENAME "vgabios.bin" #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin" +#define EXTBOOT_FILENAME "extboot.bin" /* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */ #define ACPI_DATA_SIZE 0x10000 @@ -715,6 +716,37 @@ extern kvm_context_t kvm_context; extern int kvm_allowed; #endif +static int load_option_rom(const char *filename, int offset) +{ + ram_addr_t option_rom_offset; + int size, ret; + + size = get_image_size(filename); + if (size < 0) { + fprintf(stderr, "Could not load option rom '%s'\n", filename); + exit(1); + } + if (size > (0x10000 - offset)) + goto option_rom_error; + option_rom_offset = qemu_ram_alloc(size); + ret = load_image(filename, phys_ram_base + option_rom_offset); + if (ret != size) { + option_rom_error: + fprintf(stderr, "Too many option ROMS\n"); + exit(1); + } + size = (size + 4095) & ~4095; + cpu_register_physical_memory(0xd0000 + offset, + size, option_rom_offset | IO_MEM_ROM); +#ifdef USE_KVM + if (kvm_allowed) + kvm_cpu_register_physical_memory(0xd0000 + offset, + size, option_rom_offset | + IO_MEM_ROM); +#endif + return size; +} + /* PC hardware initialisation */ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, @@ -726,7 +758,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, int ret, linux_boot, i; ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset; ram_addr_t above_4g_mem_size = 0; - int bios_size, isa_bios_size, vga_bios_size; + int bios_size, isa_bios_size, vga_bios_size, opt_rom_offset; PCIBus *pci_bus; int piix3_devfn = -1; CPUState *env; @@ -869,40 +901,13 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, /* | IO_MEM_ROM */); #endif + opt_rom_offset = 0; + for (i = 0; i < nb_option_roms; i++) + opt_rom_offset += load_option_rom(option_rom[i], opt_rom_offset); - { - ram_addr_t option_rom_offset; - int size, offset; - - offset = 0; - for (i = 0; i < nb_option_roms; i++) { - size = get_image_size(option_rom[i]); - if (size < 0) { - fprintf(stderr, "Could not load option rom '%s'\n", - option_rom[i]); - exit(1); - } - if (size > (0x10000 - offset)) - goto option_rom_error; - option_rom_offset = qemu_ram_alloc(size); - ret = load_image(option_rom[i], phys_ram_base + option_rom_offset); - if (ret != size) { - option_rom_error: - fprintf(stderr, "Too many option ROMS\n"); - exit(1); - } - size = (size + 4095) & ~4095; - cpu_register_physical_memory(0xd0000 + offset, - size, option_rom_offset | IO_MEM_ROM); -#ifdef USE_KVM - if (kvm_allowed) - kvm_cpu_register_physical_memory(0xd0000 + offset, - size, option_rom_offset | - IO_MEM_ROM); -#endif - - offset += size; - } + if (extboot_drive != -1) { + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, EXTBOOT_FILENAME); + opt_rom_offset += load_option_rom(buf, opt_rom_offset); } /* map all the bios at the top of memory */ @@ -1117,6 +1122,18 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, unit_id++; } } + + if (extboot_drive != -1) { + DriveInfo *info = &drives_table[extboot_drive]; + int cyls, heads, secs; + + if (info->type != IF_IDE) { + bdrv_guess_geometry(info->bdrv, &cyls, &heads, &secs); + bdrv_set_geometry_hint(info->bdrv, cyls, heads, secs); + } + + extboot_init(info->bdrv, 1); + } } static void pc_init_pci(ram_addr_t ram_size, int vga_ram_size, diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h index 5d4c747..7d1832f 100644 --- a/qemu/hw/pc.h +++ b/qemu/hw/pc.h @@ -151,4 +151,8 @@ void virtio_net_poll(void); void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device, BlockDriverState *bs); +/* extboot.c */ + +void extboot_init(BlockDriverState *bs, int cmd); + #endif diff --git a/qemu/sysemu.h b/qemu/sysemu.h index b9f4b43..a72a4d6 100644 --- a/qemu/sysemu.h +++ b/qemu/sysemu.h @@ -148,6 +148,7 @@ typedef struct DriveInfo { int nb_drives; DriveInfo drives_table[MAX_DRIVES+1]; +int extboot_drive; extern int drive_get_index(BlockInterfaceType type, int bus, int unit); extern int drive_get_max_bus(BlockInterfaceType type); diff --git a/qemu/vl.c b/qemu/vl.c index c47b294..39b2e24 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -177,6 +177,7 @@ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; to store the VM snapshots */ DriveInfo drives_table[MAX_DRIVES+1]; int nb_drives; +int extboot_drive = -1; /* point to the block driver where the snapshots are managed */ BlockDriverState *bs_snapshots; int vga_ram_size; @@ -4930,7 +4931,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) int bdrv_flags; char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", "secs", "trans", "media", "snapshot", "file", - "cache", NULL }; + "cache", "boot", NULL }; if (check_params(buf, sizeof(buf), params, str) < 0) { fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", @@ -5101,6 +5102,19 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) } } + if (get_param_value(buf, sizeof(buf), "boot", str)) { + if (!strcmp(buf, "on")) { + if (extboot_drive != -1) { + fprintf(stderr, "qemu: two bootable drives specified\n"); + return -1; + } + extboot_drive = nb_drives; + } else if (strcmp(buf, "off")) { + fprintf(stderr, "qemu: '%s' invalid boot option\n", str); + return -1; + } + } + get_param_value(file, sizeof(file), "file", str); /* compute bus and unit according index */ @@ -7895,8 +7909,8 @@ static void help(int exitcode) "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" - " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]" - " [,cache=on|off]\n" + " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n" + " [,cache=on|off][,boot=on|off]\n" " use 'file' as a drive image\n" "-mtdblock file use 'file' as on-board Flash memory image\n" "-sd file use 'file' as SecureDigital card image\n" ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ kvm-commits mailing list kvm-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-commits