Skip to contentSkip to conversation

Remove requirement for -hda with -kernel

PATCH In review Ross Kendall Axe 3 participants 4 messages Apr 27, 2005 – May 1, 2005 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Remove requirement for -hda with -kernel

The requirement to provide an -hda argument when doing a direct boot of a linux kernel has irritated me for some time. This patch removes that requirement by creating a temporary 1 sector hda as needed.

Ross

Index: hw/pc.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/pc.c,v
retrieving revision 1.35

pc.c +20 -2
diff -u -p -r1.35 pc.c
@@ -446,8 +446,26 @@ 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);
+            char template[] = "/tmp/qemu.XXXXXX";
+            int tmpfile = mkstemp(template);
+
+            fprintf(stderr, "qemu: Disk image not given for 'hda' when booting"
+                    " a Linux kernel; inventing one\n");
+            if(tmpfile == -1) {
+                fprintf(stderr, "qemu: couldn't create temporary diskimage\n");
+                exit(1);
+            }
+            lseek(tmpfile, 511, SEEK_SET);
+            write(tmpfile, "", 1);
+            bs_table[0] = bdrv_new("hda");
+            if (bdrv_open(bs_table[0], template, snapshot) < 0) {
+                fprintf(stderr, "qemu: could not load temporary diskimage '%s'\n",
+                        template);
+                exit(1);
+            }
+            close(tmpfile);
+            unlink(template);
+            boot_device = 'c';
         }
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
         ret = load_image(buf, bootsect);
#1 lore raw

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.

Quoted 5 lines · Ross Kendall Axe

The requirement to provide an -hda argument when doing a direct boot of a linux kernel has irritated me for some time. This patch removes that requirement by creating a temporary 1 sector hda as needed.

Ross

#2 lore raw
Quoted 7 lines · Fabrice Bellard
Quoted 4 lines · Ross Kendall Axe

The requirement to provide an -hda argument when doing a direct boot of a linux kernel has irritated me for some time. This patch removes that requirement by creating a temporary 1 sector hda as needed.

Quoted 7 lines
Quoted 1 line

Ross

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.

Good point. It wouldn't compile, and, even if it did, it wouldn't run correctly. Attached is a patch that *should* work.

The dummy block device idea is interesting. I'll see if I can implement that; hopefully it won't be too difficult. However, IHMO a better, albeit more ambitious solution would be to load the Linux boot code into an emulated boot PROM.

Ross

Index: hw/pc.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/pc.c,v
retrieving revision 1.35

pc.c +34 -2
diff -u -p -r1.35 pc.c
@@ -446,8 +446,40 @@ 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);
+#ifdef WIN32
+	    char tmpfilename[L_tmpnam];
+#else
+	    char tmpfilename[] = "/tmp/qemu.XXXXXX";
+	    int tmpfilefd;
+#endif
+	    FILE *tmpfile;
+
+            fprintf(stderr, "qemu: Disk image not given for 'hda' when booting"
+                    " a Linux kernel; inventing one\n");
+#ifdef WIN32
+	    tmpnam(tmpfilename);
+	    tmpfile = fopen(tmpfilename, "wb");
+#else
+	    tmpfilefd = mkstemp(tmpfilename);
+	    tmpfile = (tmpfilefd == -1) ? NULL : fdopen(tmpfilefd, "wb");
+#endif
+            if(!tmpfile) {
+                fprintf(stderr, "qemu: couldn't create temporary diskimage\n");
+                exit(1);
+            }
+            fseek(tmpfile, 511, SEEK_SET);
+            fputc('0', tmpfile);
+            fclose(tmpfile);
+            bs_table[0] = bdrv_new("hda");
+            if (bdrv_open(bs_table[0], tmpfilename, 0) < 0) {
+                fprintf(stderr, "qemu: could not load temporary diskimage '%s'\n",
+                        tmpfilename);
+                exit(1);
+            }
+#ifndef WIN32
+            unlink(tmpfilename);
+#endif
+            boot_device = 'c';
         }
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
         ret = load_image(buf, bootsect);
#3 lore raw
In reply to Fabrice Bellard

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 7 lines · Fabrice Bellard

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

Makefile +1 -1
diff -u -p -r1.87 Makefile
@@ -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

Makefile.target +1 -1
diff -u -p -r1.69 Makefile.target
@@ -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

block.c +1 -0
diff -u -p -r1.22 block.c
@@ -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

vl.h +1 -0
diff -u -p -r1.73 vl.h
@@ -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

pc.c +8 -2
diff -u -p -r1.35 pc.c
@@ -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);
block-dummy.c new file +148 -0

148 lines not on this page · raw message