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]>
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-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel