Port codes from qemu-kvm to support booting from SCSI disk image
PATCH v2 1/1 Port codes from qemu-kvm to support booting from SCSI disk image
The qemu-kvm could boot from SCSI disk image by utilizing seabios, this patch ported codes from qemu-kvm to let upstream qemu to support booting from SCSI disk image.
Add 'boot=on' option to qemu command line like following, qemu-system-x86_64 -drive file=scsi-disk.img,if=scsi,boot=on
---
Makefile.target | 1 + blockdev.c | 13 ++++++ blockdev.h | 2 + hw/extboot.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pc.c | 17 ++++++++ hw/pc.h | 4 ++ qemu-config.c | 4 ++ 7 files changed, 164 insertions(+), 0 deletions(-)
create mode 100644 hw/extboot.c
Makefile.target +0 -0
@@ -199,6 +199,7 @@ obj-i386-y += mc146818rtc.o i8259.o pc.o
obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o obj-i386-y += vmmouse.o vmport.o hpet.o applesmc.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o +obj-i386-y += extboot.o
obj-i386-y += debugcon.o multiboot.o
obj-i386-y += pc_piix.o
blockdev.c +0 -0
@@ -15,6 +15,8 @@
#include "qemu-config.h"
#include "sysemu.h"
+DriveInfo *extboot_drive = NULL;
+
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
/*
@@ -150,6 +152,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
int on_read_error, on_write_error;
const char *devaddr;
DriveInfo *dinfo;
+ int is_extboot = 0;
int snapshot = 0;
int ret;@@ -311,6 +314,12 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
}
}+ is_extboot = qemu_opt_get_bool(opts, "boot", 0);
+ if (is_extboot && extboot_drive) {
+ fprintf(stderr, "qemu: two bootable drives specified\n");
+ return NULL;
+ }
+
on_write_error = BLOCK_ERR_STOP_ENOSPC;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO &&
type != IF_NONE) {
@@ -421,6 +430,10 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);
QTAILQ_INSERT_TAIL(&drives, dinfo, next);+ if (is_extboot) {
+ extboot_drive = dinfo;
+ }
+
bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
switch(type) {blockdev.h +0 -0
@@ -59,4 +59,6 @@ int do_block_set_passwd(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_change_block(Monitor *mon, const char *device,
const char *filename, const char *fmt);
+extern DriveInfo *extboot_drive;
+
#endif
hw/extboot.c new file +123 -0
123 lines not on this page · raw message
hw/pc.c +0 -0
@@ -54,6 +54,7 @@
#endif
#define BIOS_FILENAME "bios.bin"
+#define EXTBOOT_FILENAME "extboot.bin"
#define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
@@ -953,6 +954,10 @@ void pc_memory_init(ram_addr_t ram_size,
isa_bios_size, (bios_offset + bios_size -isa_bios_size) | IO_MEM_ROM);
+ if (extboot_drive) {
+ option_rom[nb_option_roms++] = qemu_strdup(EXTBOOT_FILENAME);
+ }
+
option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
@@ -1074,4 +1079,16 @@ void pc_pci_device_init(PCIBus *pci_bus)
for (bus = 0; bus <= max_bus; bus++) {
pci_create_simple(pci_bus, -1, "lsi53c895a");
}+
+ if (extboot_drive) {
+ DriveInfo *info = extboot_drive;
+ int cyls, heads, secs;
+
+ if (info->type != IF_IDE && info->type != IF_VIRTIO) {
+ bdrv_guess_geometry(info->bdrv, &cyls, &heads, &secs);
+ bdrv_set_geometry_hint(info->bdrv, cyls, heads, secs);
+ }
+
+ extboot_init(info->bdrv);
+ }
}
hw/pc.h +0 -0
@@ -167,6 +167,10 @@ void isa_cirrus_vga_init(void);
void isa_ne2000_init(int base, int irq, NICInfo *nd);
+/* extboot.c */
+ +void extboot_init(BlockDriverState *bs);
+
/* e820 types */
#define E820_RAM 1
#define E820_RESERVED 2
qemu-config.c +4 -0
@@ -79,6 +79,10 @@ QemuOptsList qemu_drive_opts = { },{ .name = "readonly", .type = QEMU_OPT_BOOL, + },{ + .name = "boot", + .type = QEMU_OPT_BOOL, + .help = "make this a boot drive", }, {/* end if list */ } },
Signature · 1 line
1.7.0.4