From: "Jim C. Brown" <jma5@umd.edu>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] using partition images
Date: Sun, 7 May 2006 23:53:46 -0400 [thread overview]
Message-ID: <20060508035346.GA12697@jbrown.mylinuxbox.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 715 bytes --]
This is a preliminary patch that adds support for using a single partition
image as a hard disk image.
Syntax is: qemu -hdX part:file
E.g. qemu -hda part:/dev/hda1
qemu will see a hard disk with a single partition on it. Reading appears to work
ok, I haven't tested writing yet.
Writing to the MBR is allowed, but this is a bad idea as changes to the MBR
will be lost the moment qemu shuts down.
Known Issues:
booting is not supported - this will require passing a separate bootsector.
system id of the partition is always W95 FAT32 (LBA).
having multiple partition images in a single hard disk is not supported.
--
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.
[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 8677 bytes --]
--- vl.h Sun May 7 23:24:35 2006
+++ vl.h Sun May 7 23:24:47 2006
@@ -477,6 +477,7 @@
extern BlockDriver bdrv_bochs;
extern BlockDriver bdrv_vpc;
extern BlockDriver bdrv_vvfat;
+extern BlockDriver bdrv_part_raw;
void bdrv_init(void);
BlockDriver *bdrv_find_format(const char *format_name);
--- Makefile.target Sun May 7 23:25:52 2006
+++ Makefile.target Sun May 7 23:26:04 2006
@@ -273,7 +273,7 @@
# 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 loader.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-part-raw.o
ifdef CONFIG_WIN32
VL_OBJS+=tap-win32.o
endif
--- block.c Sun May 7 23:22:40 2006
+++ block.c Sun May 7 23:22:25 2006
@@ -794,4 +794,5 @@
bdrv_register(&bdrv_bochs);
bdrv_register(&bdrv_vpc);
bdrv_register(&bdrv_vvfat);
+ bdrv_register(&bdrv_part_raw);
}
--- Makefile Sun May 7 23:38:56 2006
+++ Makefile Sun May 7 23:16:20 2006
@@ -22,7 +22,7 @@
$(MAKE) -C $$d $@ || exit 1 ; \
done
-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-part-raw.c
$(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
dyngen$(EXESUF): dyngen.c
--- /dev/null Wed Apr 19 17:19:14 2006
+++ block-part-raw.c Sun May 7 23:21:52 2006
@@ -0,0 +1,249 @@
+/*
+ * Block driver to use partition images instead of whole hard disk images
+ *
+ * Copyright (c) 2006 Jim Brown
+ *
+ * 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"
+
+#ifdef __sun__
+#include <sys/dkio.h>
+#endif
+
+typedef struct BDRVPartRawState {
+ char mbr_data[63*512];
+ int fd;
+} BDRVPartRawState;
+
+static int part_raw_probe(const uint8_t *buf, int buf_size, const char *filename)
+{
+ if (strstart(filename, "part:", NULL))
+ return 100;
+ return 0;
+}
+
+static int part_raw_open(BlockDriverState *bs, const char *filename)
+{
+ BDRVPartRawState *s = bs->opaque;
+ int fd;
+ int64_t size;
+#ifdef _BSD
+ struct stat sb;
+#endif
+#ifdef __sun__
+ struct dk_minfo minfo;
+ int rv;
+#endif
+ int head, cylinder, sector;
+
+ fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+ if (fd < 0) {
+ fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+ if (fd < 0)
+ return -1;
+ bs->read_only = 1;
+ }
+#ifdef _BSD
+ if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
+#ifdef DIOCGMEDIASIZE
+ if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
+#endif
+#ifdef CONFIG_COCOA
+ size = LONG_LONG_MAX;
+#else
+ size = lseek(fd, 0LL, SEEK_END);
+#endif
+ } else
+#endif
+#ifdef __sun__
+ /*
+ * use the DKIOCGMEDIAINFO ioctl to read the size.
+ */
+ rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
+ if ( rv != -1 ) {
+ size = minfo.dki_lbsize * minfo.dki_capacity;
+ } else /* there are reports that lseek on some devices
+ fails, but irc discussion said that contingency
+ on contingency was overkill */
+#endif
+ {
+ size = lseek(fd, 0, SEEK_END);
+ }
+ bs->total_sectors = (size / 512) + 63;
+ s->fd = fd;
+
+ /* set up c/h/s */
+ size = size+(63*512);
+ cylinder = size/(63*16);
+ /* FIXME */
+ cylinder = cylinder + 1; /* add a cylinder just in case partition extends beyond the edge of the last cylinder/head/track */
+ head = 16;
+ sector = 63;
+ /* some bit twiddling here */
+ sector = (((cylinder >> 8) & 3) << 6) + sector;
+
+ /* set up fake MBR */
+ memset(s->mbr_data, 0, 63*512);
+ /* first partition is bootable */
+ s->mbr_data[446] = 0x80;
+ /* start head */
+ s->mbr_data[447] = 0x01;
+ /* start sector - only first 6 bits */
+ s->mbr_data[448] = 0x01;
+ /* start cylinder - this byte plus 2 bits from mbr_data[447] */
+ s->mbr_data[449] = 0x00;
+ /* system ID */
+ s->mbr_data[450] = 0x0C; /* say we're win98 fat32 */
+ /* ending head */
+ s->mbr_data[451] = head;
+ /* ending sector */
+ s->mbr_data[452] = sector;
+ /* ending cylinder */
+ s->mbr_data[453] = cylinder;
+ /* absolute start sector - 4 bytes/DWORD */
+ s->mbr_data[454] = 0x3F; // 3F = 63
+ /* absolute total number of sectors - 4 bytes/DWORD */
+ *((uint32_t*)(s->mbr_data+458)) = cpu_to_le32(bs->total_sectors - 63);
+ /* leave the other partitions blank - we only support the first one */
+
+ /* set the MBR sector signature */
+ s->mbr_data[510] = 0x55;
+ s->mbr_data[511] = 0xAA;
+
+ return 0;
+}
+
+static int part_raw_read(BlockDriverState *bs, int64_t sector_num,
+ uint8_t *buf, int nb_sectors)
+{
+ BDRVPartRawState *s = bs->opaque;
+ int ret,split;
+
+ if (sector_num >= 63)
+ {
+
+ lseek(s->fd, (sector_num - 63) * 512, SEEK_SET);
+ ret = read(s->fd, buf, nb_sectors * 512);
+ if (ret != nb_sectors * 512)
+ return -1;
+ return 0;
+
+ }
+ else
+ {
+
+ if ((nb_sectors + sector_num) > 63)
+ {
+ /* ah hell - we have to do both the fake part and the real part */
+
+ split = nb_sectors + sector_num - 63;
+ ret = part_raw_read(bs, 63, &buf[(nb_sectors-split)*512], split * 512);
+ if (ret != split * 512)
+ return -1;
+
+ /* this will always return 0 */
+ ret = part_raw_read(bs, sector_num, buf, (nb_sectors - split) * 512);
+ return 0;
+ }
+ else
+ {
+ memcpy(buf, &(s->mbr_data[sector_num*512]), nb_sectors*512);
+ return 0;
+ }
+
+ }
+}
+
+static int part_raw_write(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+ BDRVPartRawState *s = bs->opaque;
+ int ret, split;
+
+ if (sector_num >= 63)
+ {
+
+ lseek(s->fd, (sector_num - 63) * 512, SEEK_SET);
+ ret = write(s->fd, buf, nb_sectors * 512);
+ if (ret != nb_sectors * 512)
+ return -1;
+ return 0;
+
+ }
+ else
+ {
+
+ if ((nb_sectors + sector_num) > 63)
+ {
+ /* ah hell - we have to do both the fake part and the real part */
+
+ split = nb_sectors + sector_num - 63;
+ ret = part_raw_write(bs, 63, &buf[(nb_sectors-split)*512], split * 512);
+ if (ret != split * 512)
+ return -1;
+
+ /* this will always return 0 */
+ ret = part_raw_write(bs, sector_num, buf, (nb_sectors - split) * 512);
+ return 0;
+ }
+ else
+ {
+ memcpy(&(s->mbr_data[sector_num*512]), buf, nb_sectors*512);
+ return 0;
+ }
+
+ }
+}
+
+static void part_raw_close(BlockDriverState *bs)
+{
+ BDRVPartRawState *s = bs->opaque;
+ close(s->fd);
+}
+
+static int part_raw_create(const char *filename, int64_t total_size,
+ const char *backing_file, int flags)
+{
+ int fd;
+
+ if (flags || backing_file)
+ return -ENOTSUP;
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+ 0644);
+ if (fd < 0)
+ return -EIO;
+ ftruncate(fd, total_size * 512);
+ close(fd);
+ return 0;
+}
+
+BlockDriver bdrv_part_raw = {
+ "part_raw",
+ sizeof(BDRVPartRawState),
+ part_raw_probe,
+ part_raw_open,
+ part_raw_read,
+ part_raw_write,
+ part_raw_close,
+ part_raw_create,
+};
+
next reply other threads:[~2006-05-08 3:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-08 3:53 Jim C. Brown [this message]
2006-05-08 4:49 ` [Qemu-devel] using partition images Jim C. Brown
2006-05-08 10:20 ` Fabrice Bellard
2006-05-08 12:26 ` Jim C. Brown
2006-05-08 12:32 ` Johannes Schindelin
2006-05-08 13:11 ` Paul Brook
2006-05-08 14:19 ` Jim C. Brown
2006-05-08 14:28 ` Paul Brook
2006-05-08 14:59 ` Jim C. Brown
2006-05-08 15:09 ` Paul Brook
2006-05-08 14:49 ` Jim C. Brown
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=20060508035346.GA12697@jbrown.mylinuxbox.org \
--to=jma5@umd.edu \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).