Port-sgimips archive

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

Re: two questions wrt sgimips boot



tnn%NetBSD.org@localhost wrote:

> > > 2) Is netboot of -current kernels broken?
> > >    Netboot of current kernel makes it silently reboot at the
> > >    root device prompt, but it can boot successfully from disk.
> > >    4.0 kernel netboots OK.
> > 
> > Netboot directly via ARCBIOS prompt?
> > Hmm, I think it worked last time I tried, but I'll check it again later.
> 
> Yes. I was quite surprised to see ARCBIOS grok the kernel without a 2nd
> stage netboot loader.

What command did you type on ARCBIOS prompt for netboot at that time?

- The ARCBIOS seems to put a booted filename (including device path)
  into argv[0] and rest args into folloing argv[1-n] (at least on IP32).

- On 4.0, kernel checks argv[1] first, then check an "OSLoadPartition"
  environment variable on ARCBIOS to get bootpath.
  (see comments in machdep.c)

- On -current, kernel was changed (by rumble@ for IP12 support)
  to check "OSLoadPartition" first, then check argv[1].
  (no changes on my bootinfo support addition)

If you don't specify any args except bootfile with -f option,
I don't think you can mount nfsroot even on booting 4.0 kernel.

On the other hand, cngetc() might have some problem
(at least on IP32 serial console).
RB_ASKNAME prompt asking root device after mountroot() failure
(caued by a wrong partition number in the environment variable etc.)
seems to cause a silent reboot.


Anyway, I'd like to fix bootloader and kernel as following:
(diff attached)

- Make a bootloader pass bootpath which includes device via BOOTPATH
  (currently bootloader passes only a path in the boot filesystem.
   (like '/netbsd') but current kernel doesn't use it)

- Make a kernel use BOOTPATH in bootinfo to see boot device first,
  then check argv[0] if there is no valid bootinfo.
  If both are invalid, check OSLoadPartition variables
  in the ARCBIOS environment and whole argv[] arguments.
  (old bootloader doesn't set device path into BOOTPATH but
   kernel will use the OSLoadPartitions environment as before
   in that case)

- While here initialize mach_type before it's referred

I just wonder if argv[0] is valid on IP12 or not. Comments?
---
Izumi Tsutsui


Index: sgimips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/machdep.c,v
retrieving revision 1.118
diff -u -r1.118 machdep.c
--- sgimips/machdep.c   26 Jan 2008 14:35:24 -0000      1.118
+++ sgimips/machdep.c   9 Mar 2008 15:26:36 -0000
@@ -231,6 +231,7 @@
 
 uint8_t *bootinfo;                     /* pointer to bootinfo structure */
 static uint8_t bi_buf[BOOTINFO_SIZE];  /* buffer to store bootinfo data */
+static char *bootpath;                 /* bootpath passed from bootinfo */
 static const char *bootinfo_msg = NULL;
 
 #if defined(_LP64)
@@ -286,15 +287,19 @@
        /* set up bootinfo structures */
        if (magic == BOOTINFO_MAGIC && bip != NULL) {
                struct btinfo_magic *bi_magic;
+               struct btinfo_bootpath *bi_path;
 
                memcpy(bi_buf, bip, BOOTINFO_SIZE);
                bootinfo = bi_buf;
                bi_magic = lookup_bootinfo(BTINFO_MAGIC);
-               if (bi_magic == NULL || bi_magic->magic != BOOTINFO_MAGIC)
+               if (bi_magic != NULL && bi_magic->magic == BOOTINFO_MAGIC) {
+                       bootinfo_msg = "bootinfo found.\n";
+                       bi_path = lookup_bootinfo(BTINFO_BOOTPATH);
+                       if (bi_path != NULL)
+                               bootpath = bi_path->bootpath;
+               } else
                        bootinfo_msg =
                            "invalid magic number in bootinfo structure.\n";
-               else
-                       bootinfo_msg = "bootinfo found.\n";
        } else
                bootinfo_msg = "no bootinfo found. (old bootblocks?)\n";
 
@@ -331,31 +336,80 @@
        curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000;
 
        /*
-        * Try to get the boot device information from ARCBIOS. If we fail,
-        * attempt to use the environment variables passed as follows:
-        *
-        * argv[0] can be either the bootloader loaded by the PROM, or a
-        * kernel loaded directly by the PROM.
-        *
-        * If argv[0] is the bootloader, then argv[1] might be the kernel
-        * that was loaded.  How to tell which one to use?
+        * Check machine (IPn) type.
         *
-        * If argv[1] isn't an environment string, try to use it to set the
-        * boot device.
+        * Note even on IP12 (which doesn't have ARCBIOS),
+        * arcbios_system_identifiler[] has been initilialized
+        * in arcemu_ip12_init().
+        */
+       for (i = 0; arcbios_system_identifier[i] != '\0'; i++) {
+               if (arcbios_system_identifier[i] >= '0' &&
+                   arcbios_system_identifier[i] <= '9') {
+                       mach_type = strtoul(&arcbios_system_identifier[i],
+                           NULL, 10);
+                       break;
+               }
+       }
+       if (mach_type <= 0)
+               panic("invalid architecture");
+
+       /*
+        * Get boot device infomation.
+        */
+
+       /* Try to get the boot device information from bootinfo first. */
+       if (bootpath != NULL)
+               makebootdev(bootpath);
+       else {
+               /*
+                * If we are loaded directly by ARCBIOS, argv[0] is the path
+                * of the loaded kernel or old bootloader.
+                */
+               if (argc > 0 && argv[0] != NULL)
+                       makebootdev(argv[0]);
+       }
+
+       /*
+        * Also try to get the default bootpath from ARCBIOS envronment
+        * bacause argv[0] might be invalid.
         */
        osload = ARCBIOS->GetEnvironmentVariable("OSLoadPartition");
        if (osload != NULL)
                makebootdev(osload);
-       else if (argc > 1 && strchr(argv[1], '=') != 0)
-               makebootdev(argv[1]);
 
-       boothowto = RB_SINGLE;
+       /*
+        * The case where the kernel has been loaded by a
+        * boot loader will usually have been catched by
+        * the first makebootdev() case earlier on, but
+        * we still use OSLoadPartition to get the preferred
+        * root filesystem location, even if it's not
+        * actually the location of the loaded kernel.
+        */
+       for (i = 0; i < argc; i++) {
+               if (strncmp(argv[i], "OSLoadPartition=", 15) == 0)
+                       makebootdev(argv[i] + 16);
+       }
+
+       /*
+        * When the kernel is loaded directly by the firmware, and
+        * no explicit OSLoadPartition is set, we fall back on
+        * SystemPartition for the boot device.
+        */
+       for (i = 0; i < argc; i++) {
+               if (strncmp(argv[i], "SystemPartition", 15) == 0)
+                       makebootdev(argv[i] + 16);
+       }
+
 
        /*
         * Single- or multi-user ('auto' in SGI terms).
         *
         * Query ARCBIOS first, then default to environment variables.
         */
+
+       /* Set default to single user. */
+       boothowto = RB_SINGLE;
+
        osload = ARCBIOS->GetEnvironmentVariable("OSLoadOptions");
        if (osload != NULL && strcmp(osload, "auto") == 0)
                boothowto &= ~RB_SINGLE;
@@ -363,17 +417,6 @@
        for (i = 0; i < argc; i++) {
                if (strcmp(argv[i], "OSLoadOptions=auto") == 0)
                        boothowto &= ~RB_SINGLE;
-
-               /*
-                * The case where the kernel has been loaded by a
-                * boot loader will usually have been catched by
-                * the first makebootdev() case earlier on, but
-                * we still use OSLoadPartition to get the preferred
-                * root filesystem location, even if it's not
-                * actually the location of the loaded kernel.
-                */
-               if (strncmp(argv[i], "OSLoadPartition=", 15) == 0)
-                       makebootdev(argv[i] + 16);
        }
 
        /*
@@ -422,30 +465,9 @@
 #ifdef DEBUG
        boothowto |= AB_DEBUG;
 #endif
-
-       /*
-        * When the kernel is loaded directly by the firmware, and
-        * no explicit OSLoadPartition is set, we fall back on
-        * SystemPartition for the boot device.
-        */
-       for (i = 0; i < argc; i++) {
-               if (strncmp(argv[i], "SystemPartition", 15) == 0)
-                       makebootdev(argv[i] + 16);
-
-               aprint_debug("argv[%d]: %s\n", i, argv[i]);
-       }
-
-       for (i = 0; arcbios_system_identifier[i] != '\0'; i++) {
-               if (arcbios_system_identifier[i] >= '0' &&
-                   arcbios_system_identifier[i] <= '9') {
-                       mach_type = strtoul(&arcbios_system_identifier[i],
-                           NULL, 10);
-                       break;
-               }
-       }
-
-       if (mach_type <= 0)
-               panic("invalid architecture");
+       aprint_debug("argc = %d\n", argc);
+       for (i = 0; i < argc; i++)
+               aprint_debug("argv[%d] = %s\n", i, argv[i]);
 
 #if NKSYMS || defined(DDB) || defined(LKM)
        /* init symbols if present */
Index: stand/common/boot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/stand/common/boot.c,v
retrieving revision 1.15
diff -u -r1.15 boot.c
--- stand/common/boot.c 23 Feb 2008 06:51:28 -0000      1.15
+++ stand/common/boot.c 9 Mar 2008 15:26:36 -0000
@@ -238,7 +238,7 @@
        }
 
 finish:
-       strlcpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN);
+       strlcpy(bi_bpath.bootpath, bootfile, BTINFO_BOOTPATH_LEN);
        bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));
 
        bi_syms.nsym = marks[MARK_NSYM];


Home | Main Index | Thread Index | Old Index