-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Fabrice Bellard wrote: > > I like the idea, but your patch may not compile for win32. Maybe > creating a generic "dummy:[size]" block device would be interesting > instead ? > > Fabrice. >
How about this? With this patch you can specify e.g. '-hda dummy:256M' to create a 256 Mb hard disc on the fly, backed by a file in the temp directory which is deleted on exit. This patch uses this general mechanism to create the bogus 1-sector hard disc needed for booting a Linux kernel. This patch works on Linux and has been compile-tested on Mingw. Ross -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.7 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCcq1+9bR4xmappRARAtqgAKDkDHQjfIYeaPnn/wD3F+G44vvxsgCfUoDX gONMKl2/KFPHJjzJRHwC2yk= =6vTC -----END PGP SIGNATURE-----
Index: Makefile =================================================================== RCS file: /cvsroot/qemu/qemu/Makefile,v retrieving revision 1.87 diff -u -p -r1.87 Makefile --- Makefile 28 Apr 2005 21:15:08 -0000 1.87 +++ Makefile 29 Apr 2005 21:22:02 -0000 @@ -25,7 +25,7 @@ else endif endif -qemu-img$(EXESUF): qemu-img.c block.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 +qemu-img$(EXESUF): qemu-img.c block.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-dummy.c $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS) dyngen$(EXESUF): dyngen.c Index: Makefile.target =================================================================== RCS file: /cvsroot/qemu/qemu/Makefile.target,v retrieving revision 1.69 diff -u -p -r1.69 Makefile.target --- Makefile.target 28 Apr 2005 21:15:08 -0000 1.69 +++ Makefile.target 29 Apr 2005 21:22:03 -0000 @@ -314,7 +314,7 @@ endif # must use static linking to avoid leaving stuff in virtual address space VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.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 +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-dummy.o SOUND_HW = sb16.o AUDIODRV = audio.o noaudio.o wavaudio.o Index: block.c =================================================================== RCS file: /cvsroot/qemu/qemu/block.c,v retrieving revision 1.22 diff -u -p -r1.22 block.c --- block.c 28 Apr 2005 21:09:32 -0000 1.22 +++ block.c 29 Apr 2005 21:22:05 -0000 @@ -657,4 +657,5 @@ void bdrv_init(void) bdrv_register(&bdrv_bochs); bdrv_register(&bdrv_vpc); bdrv_register(&bdrv_vvfat); + bdrv_register(&bdrv_dummy); } Index: vl.h =================================================================== RCS file: /cvsroot/qemu/qemu/vl.h,v retrieving revision 1.73 diff -u -p -r1.73 vl.h --- vl.h 28 Apr 2005 21:15:08 -0000 1.73 +++ vl.h 29 Apr 2005 21:22:08 -0000 @@ -385,6 +385,7 @@ extern BlockDriver bdrv_dmg; extern BlockDriver bdrv_bochs; extern BlockDriver bdrv_vpc; extern BlockDriver bdrv_vvfat; +extern BlockDriver bdrv_dummy; void bdrv_init(void); BlockDriver *bdrv_find_format(const char *format_name); Index: hw/pc.c =================================================================== RCS file: /cvsroot/qemu/qemu/hw/pc.c,v retrieving revision 1.35 diff -u -p -r1.35 pc.c --- hw/pc.c 15 Jan 2005 12:02:56 -0000 1.35 +++ hw/pc.c 29 Apr 2005 21:22:08 -0000 @@ -446,8 +446,14 @@ void pc_init(int ram_size, int vga_ram_s 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, "qemu: Disk image not given for 'hda' when booting" + " a Linux kernel; inventing one\n"); + bs_table[0] = bdrv_new("hda"); + if (bdrv_open(bs_table[0], "dummy:512", 0) < 0) { + fprintf(stderr, "qemu: could not create temporary diskimage\n"); + exit(1); + } + boot_device = 'c'; } snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME); ret = load_image(buf, bootsect); --- /dev/null 2005-04-29 15:39:30.000000000 +0100 +++ block-dummy.c 2005-04-29 21:48:18.000000000 +0100 @@ -0,0 +1,148 @@ +/* + * QEMU dummy block device driver + * + * Copyright (C) 2005 Ross Kendall Axe <[EMAIL PROTECTED]> + * Portions copyright (c) 2003 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "vl.h" +#include "block_int.h" + +#define eprintf(...) fprintf(stderr, __VA_ARGS__) + +struct bdrv_dummy_state { + int fd; + char filename[PATH_MAX]; +}; + + +static int dummy_probe(const uint8_t *buf, int buf_size, const char *filename) +{ + return (0 == strncmp("dummy:", filename, 6)) ? 2 : 0; +} + +static int dummy_open(BlockDriverState *bs, const char *filename) +{ + struct bdrv_dummy_state *s = bs->opaque; + off_t size; +#ifdef WIN32 + char tmpname[L_tmpnam]; +#else + char tmpname[] = "/tmp/qemu-dummy.XXXXXX"; +#endif + char *ptr; + + size = strtoull(filename + 6, &ptr, 10); + if(ptr == (filename + 6)) { + eprintf("Size not given for dummy disc\n"); + return -1; + } + switch(*ptr) { + case 't': + case 'T': + size *= 1024; + case 'g': + case 'G': + size *= 1024; + case 'm': + case 'M': + size *= 1024; + case 'k': + case 'K': + size *= 1024; + case 'b': + case 'B': + case '\0': + break; + default: + eprintf("Unknown multiplicative suffix '%s'\n", ptr); + return -1; + } + +#ifdef WIN32 + if(tmpnam(tmpname)) + s->fd = open(tmpname, O_RDWR | O_BINARY | O_LARGEFILE); + else + s->fd = -1; +#else + s->fd = mkstemp(tmpname); +#endif + if(s->fd < 0) { + perror("Couldn't create dummy disc image"); + return -1; + } + s->filename[0] = '\0'; + strncat(s->filename, tmpname, sizeof s->filename); + + if(0 > ftruncate(s->fd, size)) { + perror("Couldn't size dummy disc image"); + close(s->fd); + unlink(s->filename); + return -1; + } + bs->total_sectors = size / 512; + return 0; +} + +static int dummy_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + struct bdrv_dummy_state *s = bs->opaque; + int ret; + + lseek(s->fd, sector_num * 512, SEEK_SET); + ret = read(s->fd, buf, nb_sectors * 512); + if (ret != nb_sectors * 512) + return -1; + return 0; +} + +static int dummy_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + struct bdrv_dummy_state *s = bs->opaque; + int ret; + + lseek(s->fd, sector_num * 512, SEEK_SET); + ret = write(s->fd, buf, nb_sectors * 512); + if (ret != nb_sectors * 512) + return -1; + return 0; +} + +static void dummy_close(BlockDriverState *bs) +{ + struct bdrv_dummy_state *s = bs->opaque; + + close(s->fd); + unlink(s->filename); +} + +BlockDriver bdrv_dummy = { + "dummy", + sizeof (struct bdrv_dummy_state), + dummy_probe, + dummy_open, + dummy_read, + dummy_write, + dummy_close, + NULL, +};
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel