All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Mayer" <l_indien@magic.fr>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] multiple boot devices
Date: Mon, 05 Nov 2007 14:04:40 +0100	[thread overview]
Message-ID: <1194267880.31210.87.camel@rapid> (raw)
In-Reply-To: <20071103011821.GA10975@networkno.de>

[-- Attachment #1: Type: text/plain, Size: 2370 bytes --]


On Sat, 2007-11-03 at 01:18 +0000, Thiemo Seufer wrote:
> J. Mayer wrote:
> [snip]
> > > > It restricts the letter to the ones historically allowed by Qemu, not to
> > > > anything specific to any architecture or hw platform. What I like in my
> > > > implementation, compared to the strchr..., is that it exactly tells the
> > > > user which given device is incorrect.
> > > 
> > > Well, here it makes no difference, strchr tells you exactly same as much.
> > 
> > Yes, you're right. Was thinking about the original strspn.
> > 
> > > Instead of the check, the code could also allow everything from 'a' to
> > > 'z' and then just AND the produced 32bit bitmap with a machine defined
> > > bitmap that would be part of QEMUMachine.
> > 
> > I guess we would better stop at 'n', because we can easily define a
> > semantic for devices 'c' to 'm' (ie hard disk drives in a hardware
> > platform specific order) but we have to define what means 'o' to 'z'.
> > But I agree we would better extend it now, instead of having to rework
> > it later...
> 
> To select the network device to boot from would probably become a
> 'n' 'o' 'p' 'q' series.
> 
> [snip]
> > > > Here's a second pass cleanup, adding the machine dependant checks for
> > > > the PC machine and the PowerPC ones. As one can see, the OpenHack'Ware
> > > > firmware is able to boot from devices 'e' and 'f'. For the PowerPC
> > > > machines, I choosed to try to boot from the first given usable device,
> > > > some may not agree with this choice. It can be noticed that the
> > > > available boot devices are not the same for PowerPC PreP, g3bw and mac99
> > > > machines.
> > > > As I don't know the features and requirements for the other
> > > > architectures, I prefered not to add any check for those ones.
> > > 
> > > Most other machines ignore -boot and those that don't, shouldn't break
> > > from the introduced change, so please commit it when you feel ok with
> > > it.
> > 
> > I'd like to know what are the feelings around about this patch and if
> > there are specific requirements and/or problems for some platforms to be
> > addressed before...
> 
> I think the proposed scheme (and the implementation) is flexible enough
> to accomodate all relevant platforms.

Here's an updated patch that address the remark about network boot
devices.

-- 
J. Mayer <l_indien@magic.fr>
Never organized

[-- Attachment #2: boot_devices.diff --]
[-- Type: text/x-patch, Size: 12365 bytes --]

Index: vl.c
===================================================================
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.353
diff -u -d -d -p -r1.353 vl.c
--- vl.c	31 Oct 2007 01:54:03 -0000	1.353
+++ vl.c	5 Nov 2007 12:07:05 -0000
@@ -162,12 +162,6 @@ static DisplayState display_state;
 int nographic;
 const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;
-#if defined(TARGET_I386)
-#define MAX_BOOT_DEVICES 3
-#else
-#define MAX_BOOT_DEVICES 1
-#endif
-static char boot_device[MAX_BOOT_DEVICES + 1];
 int ram_size;
 int pit_min_timer_count = 0;
 int nb_nics;
@@ -7556,14 +7552,16 @@ int main(int argc, char **argv)
     int use_gdbstub;
     const char *gdbstub_port;
 #endif
+    uint32_t boot_devices_bitmap = 0;
     int i, cdrom_index, pflash_index;
-    int snapshot, linux_boot;
+    int snapshot, linux_boot, net_boot;
     const char *initrd_filename;
     const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
     const char *pflash_filename[MAX_PFLASH];
     const char *sd_filename;
     const char *mtd_filename;
     const char *kernel_filename, *kernel_cmdline;
+    const char *boot_devices = "";
     DisplayState *ds = &display_state;
     int cyls, heads, secs, translation;
     char net_clients[MAX_NET_CLIENTS][256];
@@ -7815,20 +7813,34 @@ int main(int argc, char **argv)
                 }
                 break;
             case QEMU_OPTION_boot:
-                if (strlen(optarg) > MAX_BOOT_DEVICES) {
-                    fprintf(stderr, "qemu: too many boot devices\n");
-                    exit(1);
-                }
-                strncpy(boot_device, optarg, MAX_BOOT_DEVICES);
-#if defined(TARGET_SPARC) || defined(TARGET_I386)
-#define BOOTCHARS "acdn"
-#else
-#define BOOTCHARS "acd"
-#endif
-                if (strlen(boot_device) != strspn(boot_device, BOOTCHARS)) {
-                    fprintf(stderr, "qemu: invalid boot device "
-                                    "sequence '%s'\n", boot_device);
-                    exit(1);
+                boot_devices = optarg;
+                /* We just do some generic consistency checks */
+                {
+                    /* Could easily be extended to 64 devices if needed */
+                    const unsigned char *p;
+                    
+                    boot_devices_bitmap = 0;
+                    for (p = boot_devices; *p != '\0'; p++) {
+                        /* Allowed boot devices are:
+                         * a b     : floppy disk drives
+                         * c ... f : IDE disk drives
+                         * g ... m : machine implementation dependant drives
+                         * n ... p : network devices
+                         * It's up to each machine implementation to check
+                         * if the given boot devices match the actual hardware
+                         * implementation and firmware features.
+                         */
+                        if (*p < 'a' || *p > 'q') {
+                            fprintf(stderr, "Invalid boot device '%c'\n", *p);
+                            exit(1);
+                        }
+                        if (boot_devices_bitmap & (1 << (*p - 'a'))) {
+                            fprintf(stderr,
+                                    "Boot device '%c' was given twice\n",*p);
+                            exit(1);
+                        }
+                        boot_devices_bitmap |= 1 << (*p - 'a');
+                    }
                 }
                 break;
             case QEMU_OPTION_fda:
@@ -8176,23 +8188,23 @@ int main(int argc, char **argv)
         kqemu_allowed = 0;
 #endif
     linux_boot = (kernel_filename != NULL);
-
-    if (!linux_boot &&
-        (!strchr(boot_device, 'n')) &&
+    net_boot = (boot_devices_bitmap >> ('n' - 'a')) && 0xF;
+    
+    /* XXX: this should not be: some embedded targets just have flash */
+    if (!linux_boot && net_boot == 0 &&
         hd_filename[0] == '\0' &&
         (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
         fd_filename[0] == '\0')
         help(1);
 
     /* boot to floppy or the default cd if no hard disk defined yet */
-    if (!boot_device[0]) {
+    if (!boot_devices[0]) {
         if (hd_filename[0] != '\0')
-            boot_device[0] = 'c';
+            boot_devices = "c";
         else if (fd_filename[0] != '\0')
-            boot_device[0] = 'a';
+            boot_devices = "a";
         else
-            boot_device[0] = 'd';
-        boot_device[1] = 0;
+            boot_devices = "d";
     }
     setvbuf(stdout, NULL, _IOLBF, 0);
 
@@ -8232,20 +8244,28 @@ int main(int argc, char **argv)
     }
 
 #ifdef TARGET_I386
-    if (strchr(boot_device, 'n')) {
-	for (i = 0; i < nb_nics; i++) {
+    /* XXX: this should be moved in the PC machine instanciation code */
+    if (net_boot != 0) {
+        int netroms = 0;
+	for (i = 0; i < nb_nics && i < 4; i++) {
 	    const char *model = nd_table[i].model;
 	    char buf[1024];
-	    if (model == NULL)
-		model = "ne2k_pci";
-	    snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
-	    if (get_image_size(buf) > 0) {
-		option_rom[nb_option_roms] = strdup(buf);
-		nb_option_roms++;
-		break;
-	    }
+            if (net_boot & (1 << i)) {
+                if (model == NULL)
+                    model = "ne2k_pci";
+                snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
+                if (get_image_size(buf) > 0) {
+                    if (nb_option_roms >= MAX_OPTION_ROMS) {
+                        fprintf(stderr, "Too many option ROMs\n");
+                        exit(1);
+                    }
+                    option_rom[nb_option_roms] = strdup(buf);
+                    nb_option_roms++;
+                    netroms++;
+                }
+            }
 	}
-	if (i == nb_nics) {
+	if (netroms == 0) {
 	    fprintf(stderr, "No valid PXE rom found for network device\n");
 	    exit(1);
 	}
@@ -8425,7 +8445,7 @@ int main(int argc, char **argv)
         }
     }
 
-    machine->init(ram_size, vga_ram_size, boot_device,
+    machine->init(ram_size, vga_ram_size, boot_devices,
                   ds, fd_filename, snapshot,
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 
Index: hw/pc.c
===================================================================
RCS file: /sources/qemu/qemu/hw/pc.c,v
retrieving revision 1.88
diff -u -d -d -p -r1.88 pc.c
--- hw/pc.c	31 Oct 2007 01:54:04 -0000	1.88
+++ hw/pc.c	5 Nov 2007 12:07:06 -0000
@@ -173,6 +173,7 @@ static int boot_device2nibble(char boot_
 static void cmos_init(int ram_size, const char *boot_device, BlockDriverState **hd_table)
 {
     RTCState *s = rtc_state;
+    int nbds, bds[3] = { 0, };
     int val;
     int fd0, fd1, nb;
     int i;
@@ -202,11 +203,22 @@ static void cmos_init(int ram_size, cons
     rtc_set_memory(s, 0x35, val >> 8);
 
     /* set boot devices, and disable floppy signature check if requested */
-    rtc_set_memory(s, 0x3d,
-            boot_device2nibble(boot_device[1]) << 4 |
-            boot_device2nibble(boot_device[0]) );
-    rtc_set_memory(s, 0x38,
-            boot_device2nibble(boot_device[2]) << 4 | (fd_bootchk ?  0x0 : 0x1));
+#define PC_MAX_BOOT_DEVICES 3
+    nbds = strlen(boot_device);
+    if (nbds > PC_MAX_BOOT_DEVICES) {
+        fprintf(stderr, "Too many boot devices for PC\n");
+        exit(1);
+    }
+    for (i = 0; i < nbds; i++) {
+        bds[i] = boot_device2nibble(boot_device[i]);
+        if (bds[i] == 0) {
+            fprintf(stderr, "Invalid boot device for PC: '%c'\n",
+                    boot_device[i]);
+            exit(1);
+        }
+    }
+    rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
+    rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ?  0x0 : 0x1));
 
     /* floppy type */
 
Index: hw/ppc_chrp.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ppc_chrp.c,v
retrieving revision 1.48
diff -u -d -d -p -r1.48 ppc_chrp.c
--- hw/ppc_chrp.c	4 Nov 2007 01:16:04 -0000	1.48
+++ hw/ppc_chrp.c	5 Nov 2007 12:07:06 -0000
@@ -66,7 +66,7 @@ static void ppc_core99_init (int ram_siz
     qemu_irq *dummy_irq;
     int pic_mem_index, dbdma_mem_index, cuda_mem_index;
     int ide_mem_index[2];
-    int ppc_boot_device = boot_device[0];
+    int ppc_boot_device;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -178,6 +175,19 @@ static void ppc_core99_init (int ram_siz
         kernel_size = 0;
         initrd_base = 0;
         initrd_size = 0;
+        ppc_boot_device = '\0';
+        /* We consider that NewWorld PowerMac never have any floppy drive
+         * For now, OHW cannot boot from the network.
+         */
+        for (i = 0; i < boot_device[i] != '\0'; i++) {
+            ppc_boot_device = boot_device[i];
+            if (ppc_boot_device >= 'c' && ppc_boot_device <= 'f')
+                break;
+        }
+        if (ppc_boot_device == '\0') {
+            fprintf(stderr, "No valid boot device for Mac99 machine\n");
+            exit(1);
+        }
     }
 
     isa_mem_base = 0x80000000;
Index: hw/ppc_oldworld.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ppc_oldworld.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 ppc_oldworld.c
--- hw/ppc_oldworld.c	4 Nov 2007 01:16:04 -0000	1.4
+++ hw/ppc_oldworld.c	5 Nov 2007 12:07:06 -0000
@@ -114,7 +113,7 @@ static void ppc_heathrow_init (int ram_s
     int vga_bios_size, bios_size;
     qemu_irq *dummy_irq;
     int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
-    int ppc_boot_device = boot_device[0];
+    int ppc_boot_device;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -215,6 +214,25 @@ static void ppc_heathrow_init (int ram_s
         kernel_size = 0;
         initrd_base = 0;
         initrd_size = 0;
+        ppc_boot_device = '\0';
+        for (i = 0; i < boot_device[i] != '\0'; i++) {
+            ppc_boot_device = boot_device[i];
+            /* TOFIX: for now, the second IDE channel is not properly
+             *        emulated. The Mac floppy disk are not emulated.
+             *        For now, OHW cannot boot from the network.
+             */
+#if 0
+            if (ppc_boot_device >= 'a' && ppc_boot_device <= 'f')
+                break;
+#else
+            if (ppc_boot_device >= 'c' && ppc_boot_device <= 'd')
+                break;
+#endif
+        }
+        if (ppc_boot_device == '\0') {
+            fprintf(stderr, "No valid boot device for Mac99 machine\n");
+            exit(1);
+        }
     }
 
     isa_mem_base = 0x80000000;
Index: hw/ppc_prep.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ppc_prep.c,v
retrieving revision 1.51
diff -u -d -d -p -r1.51 ppc_prep.c
--- hw/ppc_prep.c	31 Oct 2007 01:54:04 -0000	1.51
+++ hw/ppc_prep.c	5 Nov 2007 12:07:06 -0000
@@ -521,7 +521,8 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = 
 #define NVRAM_SIZE        0x2000
 
 /* PowerPC PREP hardware initialisation */
-static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_device,
+static void ppc_prep_init (int ram_size, int vga_ram_size,
+                           const char *boot_device,
                            DisplayState *ds, const char **fd_filename,
                            int snapshot, const char *kernel_filename,
                            const char *kernel_cmdline,
@@ -539,7 +540,7 @@ static void ppc_prep_init (int ram_size,
     ppc_def_t *def;
     PCIBus *pci_bus;
     qemu_irq *i8259;
-    int ppc_boot_device = boot_device[0];
+    int ppc_boot_device;
 
     sysctrl = qemu_mallocz(sizeof(sysctrl_t));
     if (sysctrl == NULL)
@@ -614,6 +615,17 @@ static void ppc_prep_init (int ram_size,
         kernel_size = 0;
         initrd_base = 0;
         initrd_size = 0;
+        ppc_boot_device = '\0';
+        /* For now, OHW cannot boot from the network. */
+        for (i = 0; i < boot_device[i] != '\0'; i++) {
+            ppc_boot_device = boot_device[i];
+            if (ppc_boot_device >= 'a' && ppc_boot_device <= 'f')
+                break;
+        }
+        if (ppc_boot_device == '\0') {
+            fprintf(stderr, "No valid boot device for Mac99 machine\n");
+            exit(1);
+        }
     }
 
     isa_mem_base = 0xc0000000;

      parent reply	other threads:[~2007-11-05 13:04 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-31  1:54 [Qemu-devel] qemu vl.c vl.h hw/an5206.c hw/etraxfs.c hw/inte Andrzej Zaborowski
2007-10-31  2:21 ` J. Mayer
2007-10-31  2:35   ` andrzej zaborowski
2007-10-31  4:42     ` J. Mayer
2007-10-31 10:01       ` andrzej zaborowski
2007-10-31 10:22         ` J. Mayer
2007-10-31 22:49           ` J. Mayer
2007-11-01  0:01             ` andrzej zaborowski
2007-11-01 19:12               ` J. Mayer
2007-11-03  0:01                 ` andrzej zaborowski
2007-11-03  0:21                   ` J. Mayer
2007-11-03  1:18                     ` Thiemo Seufer
2007-11-03 12:40                       ` J. Mayer
2007-11-05 13:04                       ` J. Mayer [this message]

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=1194267880.31210.87.camel@rapid \
    --to=l_indien@magic.fr \
    --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.