Skip to contentSkip to conversation

Port codes from qemu-kvm to support boot from SCSI image

PATCH Superseded Haishan Bai 2 participants 7 messages Aug 17, 2010 – Aug 18, 2010 Kbuild

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Port codes from qemu-kvm to support boot from SCSI image

Port codes from qemu-kvm to support boot from SCSI image

---
 Makefile.target |    1 +
 blockdev.c      |   13 ++++++
 blockdev.h      |    2 +
 hw/extboot.c    |  123 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ivshmem.c    |    2 +-
 hw/pc.c         |   17 ++++++++
 hw/pc.h         |    4 ++
 qemu-config.c   |    4 ++
 8 files changed, 165 insertions(+), 1 deletions(-)
 create mode 100644 hw/extboot.c
Makefile.target +1 -0
index c8281e9..abba79c 100644
@@ -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 +2 -0
index 01e402b..78c286c 100644
@@ -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 +2 -0
index 37f3a01..e707b87 100644
@@ -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/ivshmem.c +1 -1
index bbb5cba..e38ac2a 100644
@@ -353,7 +353,7 @@ static int check_shm_size(IVShmemState *s, int fd) {
     if (s->ivshmem_size > buf.st_size) {
         fprintf(stderr, "IVSHMEM ERROR: Requested memory size greater");
         fprintf(stderr, " than shared object size (%" PRIu64 " > %ld)\n",
-                                          s->ivshmem_size, buf.st_size);
+                s->ivshmem_size, (long int)buf.st_size);
         return -1;
     } else {
         return 0;
hw/pc.c +1 -0
index 58dea57..88f43aa 100644
@@ -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 +4 -0
index 63b0249..61882db 100644
@@ -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
index 95abe61..0f3c775 100644
@@ -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
#1 lore raw
Quoted 124 lines · Haishan Bai

Port codes from qemu-kvm to support boot from SCSI image

---
 Makefile.target |    1 +
 blockdev.c      |   13 ++++++
 blockdev.h      |    2 +
 hw/extboot.c    |  123
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ivshmem.c    |    2 +-
 hw/pc.c         |   17 ++++++++
 hw/pc.h         |    4 ++
 qemu-config.c   |    4 ++
 8 files changed, 165 insertions(+), 1 deletions(-)
 create mode 100644 hw/extboot.c
Makefile.target +1 -0
index c8281e9..abba79c 100644
@@ -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 +2 -0
index 01e402b..78c286c 100644
@@ -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);
 

/*

blockdev.c +7 -0
@@ -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) {

blockdev.c +4 -0
@@ -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 +2 -0
index 37f3a01..e707b87 100644
@@ -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 +28 -0
new file mode 100644
index 0000000..8ada21b
@@ -0,0 +1,123 @@
+/*
+ * Extended boot option ROM support.
+ *
+ * Copyright IBM, Corp. 2007
+ *
+ * Authors:
+ *  Anthony Liguori <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "isa.h"
+#include "block.h"
+
+/* Extended Boot ROM suport */
+
+union extboot_cmd
+{
+    uint16_t type;
+    struct {
+    uint16_t type;
+    uint16_t cylinders;
+    uint16_t heads;
+    uint16_t sectors;

hw/extboot.c line 38

Quoted 10 lines
hw/extboot.c new file +10 -0
+    uint64_t nb_sectors;
+    } query_geometry;
+    struct {
+    uint16_t type;
+    uint16_t nb_sectors;
+    uint16_t segment;
+    uint16_t offset;
+    uint64_t sector;
+    } xfer;
+};

What's with the indentation here?

Quoted 18 lines
hw/extboot.c new file +18 -0
+
+static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
+{
+    bdrv_get_geometry_hint(bs, c, h, s);
+
+    if (*c <= 1024) {
+    *c >>= 0;
+    *h <<= 0;
+    } else if (*c <= 2048) {
+    *c >>= 1;
+    *h <<= 1;
+    } else if (*c <= 4096) {
+    *c >>= 2;
+    *h <<= 2;
+    } else if (*c <= 8192) {
+    *c >>= 3;
+    *h <<= 3;
+    } else {

hw/extboot.c line 66

Quoted 10 lines
hw/extboot.c new file +10 -0
+    *c >>= 4;
+    *h <<= 4;
+    }
+
+    /* what is the correct algorithm for this?? */
+    if (*h == 256) {
+    *h = 255;
+    *c = *c + 1;
+    }
+}

And here.

Quoted 9 lines
hw/extboot.c new file +9 -0
+
+static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
+{
+    union extboot_cmd cmd;
+    BlockDriverState *bs = opaque;
+    int cylinders, heads, sectors, err;
+    uint64_t nb_sectors;
+    target_phys_addr_t pa = 0;
+    int blen = 0;

hw/extboot.c line 85

Quoted 10 lines
hw/extboot.c new file +10 -0
+    void *buf = NULL;
+
+    cpu_physical_memory_read((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+                             sizeof(cmd));
+
+    if (cmd.type == 0x01 || cmd.type == 0x02) {
+    pa = cmd.xfer.segment * 16 + cmd.xfer.offset;
+        blen = cmd.xfer.nb_sectors * 512;
+        buf = qemu_memalign(512, blen);
+    }

And here.

Quoted 17 lines
hw/extboot.c new file +17 -0
+
+    switch (cmd.type) {
+    case 0x00:
+        get_translated_chs(bs, &cylinders, &heads, &sectors);
+    bdrv_get_geometry(bs, &nb_sectors);
+    cmd.query_geometry.cylinders = cylinders;
+    cmd.query_geometry.heads = heads;
+    cmd.query_geometry.sectors = sectors;
+    cmd.query_geometry.nb_sectors = nb_sectors;
+    break;
+    case 0x01:
+    err = bdrv_read(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+    if (err)
+        printf("Read failed\n");
+
+        cpu_physical_memory_write(pa, buf, blen);
+

hw/extboot.c line 112

Quoted 10 lines
hw/extboot.c new file +10 -0
+    break;
+    case 0x02:
+        cpu_physical_memory_read(pa, buf, blen);
+
+    err = bdrv_write(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+    if (err)
+        printf("Write failed\n");
+
+    break;
+    }

And here.

Quoted 97 lines
hw/extboot.c new file +11 -0
+
+    cpu_physical_memory_write((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+                              sizeof(cmd));
+    if (buf)
+        qemu_free(buf);
+}
+
+void extboot_init(BlockDriverState *bs)
+{
+    register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);
+}
hw/ivshmem.c +1 -1
index bbb5cba..e38ac2a 100644
@@ -353,7 +353,7 @@ static int check_shm_size(IVShmemState *s, int fd) {
     if (s->ivshmem_size > buf.st_size) {
         fprintf(stderr, "IVSHMEM ERROR: Requested memory size greater");
         fprintf(stderr, " than shared object size (%" PRIu64 " > %ld)\n",
-                                          s->ivshmem_size, buf.st_size);
+                s->ivshmem_size, (long int)buf.st_size);
         return -1;
     } else {
         return 0;
hw/pc.c +5 -0
index 58dea57..88f43aa 100644
@@ -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);

hw/pc.c +12 -0
@@ -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 +4 -0
index 63b0249..61882db 100644
@@ -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
index 95abe61..0f3c775 100644
@@ -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
mailto:[email protected]
author
#2 lore raw
Quoted 321 lines · malc
Quoted 125 lines · Haishan Bai

Port codes from qemu-kvm to support boot from SCSI image

---
 Makefile.target |    1 +
 blockdev.c      |   13 ++++++
 blockdev.h      |    2 +
 hw/extboot.c    |  123
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ivshmem.c    |    2 +-
 hw/pc.c         |   17 ++++++++
 hw/pc.h         |    4 ++
 qemu-config.c   |    4 ++
 8 files changed, 165 insertions(+), 1 deletions(-)
 create mode 100644 hw/extboot.c
Makefile.target +1 -0
index c8281e9..abba79c 100644
@@ -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 +2 -0
index 01e402b..78c286c 100644
@@ -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);
 

/*

blockdev.c +7 -0
@@ -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) {

blockdev.c +4 -0
@@ -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 +2 -0
index 37f3a01..e707b87 100644
@@ -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 +28 -0
new file mode 100644
index 0000000..8ada21b
@@ -0,0 +1,123 @@
+/*
+ * Extended boot option ROM support.
+ *
+ * Copyright IBM, Corp. 2007
+ *
+ * Authors:
+ *  Anthony Liguori <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "isa.h"
+#include "block.h"
+
+/* Extended Boot ROM suport */
+
+union extboot_cmd
+{
+    uint16_t type;
+    struct {
+    uint16_t type;
+    uint16_t cylinders;
+    uint16_t heads;
+    uint16_t sectors;

hw/extboot.c line 38

Quoted 10 lines
hw/extboot.c new file +10 -0
+    uint64_t nb_sectors;
+    } query_geometry;
+    struct {
+    uint16_t type;
+    uint16_t nb_sectors;
+    uint16_t segment;
+    uint16_t offset;
+    uint64_t sector;
+    } xfer;
+};

What's with the indentation here?

Quoted 19 lines
hw/extboot.c new file +18 -0
+
+static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
+{
+    bdrv_get_geometry_hint(bs, c, h, s);
+
+    if (*c <= 1024) {
+    *c >>= 0;
+    *h <<= 0;
+    } else if (*c <= 2048) {
+    *c >>= 1;
+    *h <<= 1;
+    } else if (*c <= 4096) {
+    *c >>= 2;
+    *h <<= 2;
+    } else if (*c <= 8192) {
+    *c >>= 3;
+    *h <<= 3;
+    } else {

hw/extboot.c line 66

Quoted 10 lines
hw/extboot.c new file +10 -0
+    *c >>= 4;
+    *h <<= 4;
+    }
+
+    /* what is the correct algorithm for this?? */
+    if (*h == 256) {
+    *h = 255;
+    *c = *c + 1;
+    }
+}

And here.

Quoted 10 lines
hw/extboot.c new file +9 -0
+
+static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
+{
+    union extboot_cmd cmd;
+    BlockDriverState *bs = opaque;
+    int cylinders, heads, sectors, err;
+    uint64_t nb_sectors;
+    target_phys_addr_t pa = 0;
+    int blen = 0;

hw/extboot.c line 85

Quoted 10 lines
hw/extboot.c new file +10 -0
+    void *buf = NULL;
+
+    cpu_physical_memory_read((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+                             sizeof(cmd));
+
+    if (cmd.type == 0x01 || cmd.type == 0x02) {
+    pa = cmd.xfer.segment * 16 + cmd.xfer.offset;
+        blen = cmd.xfer.nb_sectors * 512;
+        buf = qemu_memalign(512, blen);
+    }

And here.

Quoted 18 lines
hw/extboot.c new file +17 -0
+
+    switch (cmd.type) {
+    case 0x00:
+        get_translated_chs(bs, &cylinders, &heads, &sectors);
+    bdrv_get_geometry(bs, &nb_sectors);
+    cmd.query_geometry.cylinders = cylinders;
+    cmd.query_geometry.heads = heads;
+    cmd.query_geometry.sectors = sectors;
+    cmd.query_geometry.nb_sectors = nb_sectors;
+    break;
+    case 0x01:
+    err = bdrv_read(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+    if (err)
+        printf("Read failed\n");
+
+        cpu_physical_memory_write(pa, buf, blen);
+

hw/extboot.c line 112

Quoted 10 lines
hw/extboot.c new file +10 -0
+    break;
+    case 0x02:
+        cpu_physical_memory_read(pa, buf, blen);
+
+    err = bdrv_write(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+    if (err)
+        printf("Write failed\n");
+
+    break;
+    }

And here.

Quoted 90 lines
hw/extboot.c new file +11 -0
+
+    cpu_physical_memory_write((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+                              sizeof(cmd));
+    if (buf)
+        qemu_free(buf);
+}
+
+void extboot_init(BlockDriverState *bs)
+{
+    register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);
+}
hw/ivshmem.c +1 -1
index bbb5cba..e38ac2a 100644
@@ -353,7 +353,7 @@ static int check_shm_size(IVShmemState *s, int fd) {
     if (s->ivshmem_size > buf.st_size) {
         fprintf(stderr, "IVSHMEM ERROR: Requested memory size greater");
         fprintf(stderr, " than shared object size (%" PRIu64 " > %ld)\n",
-                                          s->ivshmem_size, buf.st_size);
+                s->ivshmem_size, (long int)buf.st_size);
         return -1;
     } else {
         return 0;
hw/pc.c +5 -0
index 58dea57..88f43aa 100644
@@ -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);

hw/pc.c +12 -0
@@ -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 +4 -0
index 63b0249..61882db 100644
@@ -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 +1 -0
index 95abe61..0f3c775 100644
@@ -79,6 +79,10 @@ QemuOptsList qemu_drive_opts = {
         },{
             .name = "readonly",
             .type = QEMU_OPT_BOOL,
+        },{
Quoted 10 lines

qemu-config.c QemuOptsList qemu_drive_opts = { · line 88

Quoted 8 lines
qemu-config.c +3 -0
+      .name = "boot",
+      .type = QEMU_OPT_BOOL,
+      .help = "make this a boot drive",
         },
         { /* end if list */ }
     },

I am sorry about that, I will send V2, and believe me this will never can happen.

Best regards
Shan Hai

author
#3 lore raw
In reply to malc
Quoted 321 lines · malc
Quoted 125 lines · Haishan Bai

Port codes from qemu-kvm to support boot from SCSI image

---
 Makefile.target |    1 +
 blockdev.c      |   13 ++++++
 blockdev.h      |    2 +
 hw/extboot.c    |  123
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ivshmem.c    |    2 +-
 hw/pc.c         |   17 ++++++++
 hw/pc.h         |    4 ++
 qemu-config.c   |    4 ++
 8 files changed, 165 insertions(+), 1 deletions(-)
 create mode 100644 hw/extboot.c
Makefile.target +1 -0
index c8281e9..abba79c 100644
@@ -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 +2 -0
index 01e402b..78c286c 100644
@@ -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);
 

/*

blockdev.c +7 -0
@@ -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) {

blockdev.c +4 -0
@@ -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 +2 -0
index 37f3a01..e707b87 100644
@@ -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 +28 -0
new file mode 100644
index 0000000..8ada21b
@@ -0,0 +1,123 @@
+/*
+ * Extended boot option ROM support.
+ *
+ * Copyright IBM, Corp. 2007
+ *
+ * Authors:
+ *  Anthony Liguori <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "isa.h"
+#include "block.h"
+
+/* Extended Boot ROM suport */
+
+union extboot_cmd
+{
+    uint16_t type;
+    struct {
+    uint16_t type;
+    uint16_t cylinders;
+    uint16_t heads;
+    uint16_t sectors;

hw/extboot.c line 38

Quoted 10 lines
hw/extboot.c new file +10 -0
+    uint64_t nb_sectors;
+    } query_geometry;
+    struct {
+    uint16_t type;
+    uint16_t nb_sectors;
+    uint16_t segment;
+    uint16_t offset;
+    uint64_t sector;
+    } xfer;
+};

What's with the indentation here?

Quoted 19 lines
hw/extboot.c new file +18 -0
+
+static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
+{
+    bdrv_get_geometry_hint(bs, c, h, s);
+
+    if (*c <= 1024) {
+    *c >>= 0;
+    *h <<= 0;
+    } else if (*c <= 2048) {
+    *c >>= 1;
+    *h <<= 1;
+    } else if (*c <= 4096) {
+    *c >>= 2;
+    *h <<= 2;
+    } else if (*c <= 8192) {
+    *c >>= 3;
+    *h <<= 3;
+    } else {

hw/extboot.c line 66

Quoted 10 lines
hw/extboot.c new file +10 -0
+    *c >>= 4;
+    *h <<= 4;
+    }
+
+    /* what is the correct algorithm for this?? */
+    if (*h == 256) {
+    *h = 255;
+    *c = *c + 1;
+    }
+}

And here.

Quoted 10 lines
hw/extboot.c new file +9 -0
+
+static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
+{
+    union extboot_cmd cmd;
+    BlockDriverState *bs = opaque;
+    int cylinders, heads, sectors, err;
+    uint64_t nb_sectors;
+    target_phys_addr_t pa = 0;
+    int blen = 0;

hw/extboot.c line 85

Quoted 10 lines
hw/extboot.c new file +10 -0
+    void *buf = NULL;
+
+    cpu_physical_memory_read((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+                             sizeof(cmd));
+
+    if (cmd.type == 0x01 || cmd.type == 0x02) {
+    pa = cmd.xfer.segment * 16 + cmd.xfer.offset;
+        blen = cmd.xfer.nb_sectors * 512;
+        buf = qemu_memalign(512, blen);
+    }

And here.

Quoted 18 lines
hw/extboot.c new file +17 -0
+
+    switch (cmd.type) {
+    case 0x00:
+        get_translated_chs(bs, &cylinders, &heads, &sectors);
+    bdrv_get_geometry(bs, &nb_sectors);
+    cmd.query_geometry.cylinders = cylinders;
+    cmd.query_geometry.heads = heads;
+    cmd.query_geometry.sectors = sectors;
+    cmd.query_geometry.nb_sectors = nb_sectors;
+    break;
+    case 0x01:
+    err = bdrv_read(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+    if (err)
+        printf("Read failed\n");
+
+        cpu_physical_memory_write(pa, buf, blen);
+

hw/extboot.c line 112

Quoted 10 lines
hw/extboot.c new file +10 -0
+    break;
+    case 0x02:
+        cpu_physical_memory_read(pa, buf, blen);
+
+    err = bdrv_write(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+    if (err)
+        printf("Write failed\n");
+
+    break;
+    }

And here.

Quoted 90 lines
hw/extboot.c new file +11 -0
+
+    cpu_physical_memory_write((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+                              sizeof(cmd));
+    if (buf)
+        qemu_free(buf);
+}
+
+void extboot_init(BlockDriverState *bs)
+{
+    register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);
+}
hw/ivshmem.c +1 -1
index bbb5cba..e38ac2a 100644
@@ -353,7 +353,7 @@ static int check_shm_size(IVShmemState *s, int fd) {
     if (s->ivshmem_size > buf.st_size) {
         fprintf(stderr, "IVSHMEM ERROR: Requested memory size greater");
         fprintf(stderr, " than shared object size (%" PRIu64 " > %ld)\n",
-                                          s->ivshmem_size, buf.st_size);
+                s->ivshmem_size, (long int)buf.st_size);
         return -1;
     } else {
         return 0;
hw/pc.c +5 -0
index 58dea57..88f43aa 100644
@@ -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);

hw/pc.c +12 -0
@@ -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 +4 -0
index 63b0249..61882db 100644
@@ -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 +1 -0
index 95abe61..0f3c775 100644
@@ -79,6 +79,10 @@ QemuOptsList qemu_drive_opts = {
         },{
             .name = "readonly",
             .type = QEMU_OPT_BOOL,
+        },{
Quoted 10 lines

qemu-config.c QemuOptsList qemu_drive_opts = { · line 88

Quoted 8 lines
qemu-config.c +3 -0
+      .name = "boot",
+      .type = QEMU_OPT_BOOL,
+      .help = "make this a boot drive",
         },
         { /* end if list */ }
     },

BTW, I am just curious why I can not receive what I have sent to the list?

Best regards
Shan Hai

#4 lore raw
Quoted 3 lines · haishan
Quoted 2 lines · malc

On Tue, 17 Aug 2010, Haishan Bai wrote:

[..snip..]

Quoted 3 lines

BTW, I am just curious why I can not receive what I have sent to the list?

Because you overquote.

Beats me if that is not the real reason though.

Signature · 1 line
mailto:[email protected]
author
#5 lore raw
Quoted 9 lines · malc
Quoted 5 lines · haishan
Quoted 3 lines · malc

On Tue, 17 Aug 2010, Haishan Bai wrote:

Quoted 10 lines

[..snip..]

Quoted 3 lines

BTW, I am just curious why I can not receive what I have sent to the list?

Because you overquote.

What did you mean by "overquote"? I am new in this list and have lots of troubles about mailing list, so tried several times and found out sent out several same posts, that's scary.

Regards
Shan Hai

Quoted 3 lines

Beats me if that is not the real reason though.

#6 lore raw
Quoted 17 lines · haishan
Quoted 16 lines · malc
Quoted 5 lines · haishan
Quoted 3 lines · malc

On Tue, 17 Aug 2010, Haishan Bai wrote:

[..snip..]

Quoted 3 lines

BTW, I am just curious why I can not receive what I have sent to the list?

Quoted 7 lines
Quoted 3 lines

Because you overquote.

What did you mean by "overquote"? I am new in this list and have lots of troubles about mailing list, so tried several times and found out sent out several same posts, that's scary.

It was an attempt at humor, you posted your entire patch (see above, i've instead added a placeholder for irrelevant text)

Back to your question: i've no idea.

Signature · 1 line
mailto:[email protected]