qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [kvm-devel] [PATCH] Memory Based Block Device


From: Anthony Liguori
Subject: [Qemu-devel] Re: [kvm-devel] [PATCH] Memory Based Block Device
Date: Wed, 25 Jul 2007 17:37:32 -0500
User-agent: Thunderbird 1.5.0.12 (X11/20070604)

Evan Felix wrote:
The Current way to boot a kernel and initrd is to use an option ROM,

Currently, the block infrastructure has this nasty hack that allows you to set an override of the first sector of the disk (which is the boot sector). It has the appropriate magic to do this in such a way that it preserves the partition table. -kernel uses this hack to override the boot sector with a specialized boot loader that boots a kernel from a special place that it's stashed in in physical memory.

A more elegant approach would be to do away with the boot sector hacks in the block code and to implement an option ROM. The option ROM code would hook the appropriate BIOS interrupts such that it could generate the fake boot sector for the first disk.

The advantage to such an approach is that you get rid of the nasty hacks in the block devices to make -kernel work. It also generalizes nicely to other things like SCSI boot.

Regards,

Anthony Liguori

bt it still needs a boot sector to hand to the bios so that it knows
where the code got loaded into ram.  This patch makes a fake one just
before its needed.

I never though of the /dev/null trick.  :)

Evan

On 7/25/07, Anthony Liguori <address@hidden> wrote:
Evan Felix wrote:
Folks here is a patch i've made for qemu that adds a memory based
block device, it utilizes memory on the Host side to emulate a block
device.

I often use -hda /dev/null for -kernel/-append.

If you really want to implement a "proper" solution for -kernel/-append,
I think the right thing to do would be to use an option ROM instead of a
fake boot sector.

Regards,

Anthony Liguori

I've tested this on a few boxes to allow a kernel/initramfs system to
boot without needing a specified block device(it automatically creates
a small one) and for installing a usable system on.  One note you can
never shut down the running system, but seems to work fine when only
re-boots are required.  I've installed debian on it a few times.

Some Things I'd like comments on:
- The auto-detection code in the block code causes the code to
allocate the memory used twice, even though it only gets used the
second time.
- using qemu_mallocz seems to pre-allocate all the memory used, which
is fine, but my early code with calloc only allocated what blocks were
actually used. Does this bother people.

Evan Felix


diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/block.c kvm-28/qemu/block.c
--- kvm-28/qemu.orig/block.c  2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/block.c       2007-07-11 13:29:02.000000000 -0700
@@ -1244,6 +1244,7 @@ static int bdrv_write_em(BlockDriverStat
 void bdrv_init(void)
 {
     bdrv_register(&bdrv_raw);
+    bdrv_register(&bdrv_mem);
     bdrv_register(&bdrv_host_device);
 #ifndef _WIN32
     bdrv_register(&bdrv_cow);
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/block-mem.c kvm-28/qemu/block-mem.c
--- kvm-28/qemu.orig/block-mem.c      1969-12-31 16:00:00.000000000 -0800
+++ kvm-28/qemu/block-mem.c   2007-07-09 13:46:39.000000000 -0700
@@ -0,0 +1,129 @@
+/*
+ *  Block Driver for a Memory disk on the host side.
+ *
+ *  Copyright (c) 2007 Pacific Northwest National Laboratory
+ *                     and Evan Felix <address@hidden>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "vl.h"
+#include "block_int.h"
+
+//I took this from block-raw.c
+#ifdef __sun__
+#define _POSIX_PTHREAD_SEMANTICS 1
+#include <signal.h>
+#include <sys/dkio.h>
+#endif
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+#include <linux/fd.h>
+#endif
+#ifdef __FreeBSD__
+#include <sys/disk.h>
+#endif
+
+#define DEBUG_MEM 0
+
+#ifdef DEBUG_MEM
+#define DEBUG(fmt,a...) printf("D:%s:%d> " fmt "\n",__FILE__,__LINE__,##a)
+#else
+#define DEBUG(fmt,a...)
+#endif
+
+typedef struct BDRVMemState {
+     void *memory;
+     int64_t length;
+} BDRVMemState;
+
+static int mem_open(BlockDriverState *bs, const char *filename, int flags)
+{
+     BDRVMemState *s = bs->opaque;
+
+     bs->locked = 1;
+     bs->type   = BDRV_TYPE_HD;
+     //Try to parse the filename as a number of bytes.  add recognize M,K,G 
laterz.
+     s->length = strtol(filename+4,NULL,0);
+     DEBUG("mem_open:Raw Image size: %s -> %ld\n",filename,s->length);
+
+     s->memory=qemu_mallocz(s->length);
+     if (! s->memory)
+             return -ENOMEM;
+     return 0;
+}
+
+static void mem_close(BlockDriverState *bs) {
+
+     BDRVMemState *s = bs->opaque;
+     DEBUG("mem_close: %lld\n",s->length);
+     qemu_free(s->memory);
+     s->length=0;
+}
+
+static int mem_pread(BlockDriverState *bs, int64_t offset,
+                     uint8_t *buf, int count)
+{
+    BDRVMemState *s = bs->opaque;
+
+     if (offset < 0 || (offset + count)>s->length) {
+             return -EINVAL;
+     }
+
+    memcpy(buf,(s->memory+offset),count);
+     return count;
+}
+
+static int mem_pwrite(BlockDriverState *bs, int64_t offset,
+                      const uint8_t *buf, int count)
+{
+     BDRVMemState *s = bs->opaque;
+
+     if (offset < 0 || (offset + count)>s->length) {
+             return -EINVAL;
+     }
+
+     memcpy((s->memory+offset),buf,count);
+     return count;
+}
+
+static void mem_flush(BlockDriverState *bs)
+{
+     //Do Nothing for now
+     DEBUG("mem_flush\n");
+}
+
+static int64_t  mem_getlength(BlockDriverState *bs)
+{
+    BDRVMemState *s = bs->opaque;
+
+     return s->length;
+}
+
+BlockDriver bdrv_mem = {
+     .format_name     = "mem",
+     .instance_size   = sizeof(BDRVMemState),
+     .protocol_name   = "mem",
+
+     .bdrv_open       = mem_open,
+     .bdrv_close      = mem_close,
+     .bdrv_flush      = mem_flush,
+
+     .bdrv_pread = mem_pread,
+    .bdrv_pwrite = mem_pwrite,
+    .bdrv_getlength = mem_getlength,
+};
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/hw/pc.c kvm-28/qemu/hw/pc.c
--- kvm-28/qemu.orig/hw/pc.c  2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/hw/pc.c       2007-07-06 16:48:12.000000000 -0700
@@ -583,8 +583,13 @@ static void pc_init1(int ram_size, int v
         uint8_t old_bootsect[512];

         if (bs_table[0] == NULL) {
-            fprintf(stderr, "A disk image must be given for 'hda'
when booting a Linux kernel\n");
-            exit(1);
+            fprintf(stderr, "A disk image must be given when booting
a Linux kernel....\n\tCreating Simple memory backed Disk\n");
+            bs_table[i] = bdrv_new("hda");
+            if (bdrv_open(bs_table[0], "mem:4096", 0) < 0) {
+                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
+                        "mem:512");
+                exit(1);
+            }
         }
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
         ret = load_image(buf, bootsect);
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/Makefile kvm-28/qemu/Makefile
--- kvm-28/qemu.orig/Makefile 2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/Makefile      2007-07-06 14:24:44.000000000 -0700
@@ -39,7 +39,7 @@ subdir-%: dyngen$(EXESUF)

 recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))

-qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c
block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c
block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c
+qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c
block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c
block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c block-mem.c
      $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS)
$(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)

 dyngen$(EXESUF): dyngen.c
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/Makefile.target kvm-28/qemu/Makefile.target
--- kvm-28/qemu.orig/Makefile.target  2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/Makefile.target       2007-07-06 13:43:31.000000000 -0700
@@ -326,7 +326,7 @@ endif
 VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o
 VL_OBJS+=cutils.o migration.o
 VL_OBJS+=block.o block-raw.o
-VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
+VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
block-mem.o
 ifdef CONFIG_WIN32
 VL_OBJS+=tap-win32.o
 endif
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/vl.h kvm-28/qemu/vl.h
--- kvm-28/qemu.orig/vl.h     2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/vl.h  2007-07-06 14:23:50.000000000 -0700
@@ -561,6 +561,7 @@ typedef struct BlockDriverState BlockDri
 typedef struct BlockDriver BlockDriver;

 extern BlockDriver bdrv_raw;
+extern BlockDriver bdrv_mem;
 extern BlockDriver bdrv_host_device;
 extern BlockDriver bdrv_cow;
 extern BlockDriver bdrv_qcow;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
kvm-devel mailing list
address@hidden
https://lists.sourceforge.net/lists/listinfo/kvm-devel



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
kvm-devel mailing list
address@hidden
https://lists.sourceforge.net/lists/listinfo/kvm-devel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]