All of lore.kernel.org
 help / color / mirror / Atom feed
From: haishan <haishan.bai@gmail.com>
To: malc <av1474@comtv.ru>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] Port codes from qemu-kvm to support boot from SCSI image
Date: Wed, 18 Aug 2010 09:39:47 +0800	[thread overview]
Message-ID: <4C6B39E3.5030607@gmail.com> (raw)
In-Reply-To: <alpine.LNX.2.00.1008172256250.1411@linmac>

malc wrote:
> On Tue, 17 Aug 2010, Haishan Bai wrote:
>
>   
>> Port codes from qemu-kvm to support boot from SCSI image
>>
>> Signed-off-by: Shan Hai <haishan.bai@gmail.com>
>> ---
>>  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
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index c8281e9..abba79c 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -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
>>
>> diff --git a/blockdev.c b/blockdev.c
>> index 01e402b..78c286c 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -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) {
>> diff --git a/blockdev.h b/blockdev.h
>> index 37f3a01..e707b87 100644
>> --- a/blockdev.h
>> +++ b/blockdev.h
>> @@ -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
>> diff --git a/hw/extboot.c b/hw/extboot.c
>> new file mode 100644
>> index 0000000..8ada21b
>> --- /dev/null
>> +++ b/hw/extboot.c
>> @@ -0,0 +1,123 @@
>> +/*
>> + * Extended boot option ROM support.
>> + *
>> + * Copyright IBM, Corp. 2007
>> + *
>> + * Authors:
>> + *  Anthony Liguori <aliguori@us.ibm.com>
>> + *
>> + * 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;
>> +    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?
>
>   
>> +
>> +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 {
>> +    *c >>= 4;
>> +    *h <<= 4;
>> +    }
>> +
>> +    /* what is the correct algorithm for this?? */
>> +    if (*h == 256) {
>> +    *h = 255;
>> +    *c = *c + 1;
>> +    }
>> +}
>>     
>
> And here.
>
>   
>> +
>> +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;
>> +    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.
>
>   
>> +
>> +    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);
>> +
>> +    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.
>
>   
>> +
>> +    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);
>> +}
>> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
>> index bbb5cba..e38ac2a 100644
>> --- a/hw/ivshmem.c
>> +++ b/hw/ivshmem.c
>> @@ -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;
>> diff --git a/hw/pc.c b/hw/pc.c
>> index 58dea57..88f43aa 100644
>> --- a/hw/pc.c
>> +++ b/hw/pc.c
>> @@ -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);
>> +    }
>>  }
>> diff --git a/hw/pc.h b/hw/pc.h
>> index 63b0249..61882db 100644
>> --- a/hw/pc.h
>> +++ b/hw/pc.h
>> @@ -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
>> diff --git a/qemu-config.c b/qemu-config.c
>> index 95abe61..0f3c775 100644
>> --- a/qemu-config.c
>> +++ b/qemu-config.c
>> @@ -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 */ }
>>      },
>>
>>     
>
>   


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

Best regards
Shan Hai

  reply	other threads:[~2010-08-18  1:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-17 15:59 [Qemu-devel] [PATCH] Port codes from qemu-kvm to support boot from SCSI image Haishan Bai
2010-08-17 18:57 ` malc
2010-08-18  1:39   ` haishan [this message]
2010-08-18  3:32   ` haishan
2010-08-18  3:43     ` malc
2010-08-18  3:47       ` haishan
2010-08-18  4:02         ` malc

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C6B39E3.5030607@gmail.com \
    --to=haishan.bai@gmail.com \
    --cc=av1474@comtv.ru \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.