Port-macppc archive

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

ofwboot enhancement



Hi,

the following patch will make ofwboot automatically find a NetBSD root
partition, when no device name is specified in the boot file name.

For example a simple "boot hd:,ofwboot.xcf" will now always find the root
partition and load the netbsd kernel from it.

When there are no objections or comments I will commit it shortly.

Index: ofdev.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/stand/ofwboot/ofdev.c,v
retrieving revision 1.20.8.1
diff -u -r1.20.8.1 ofdev.c
--- ofdev.c 2 Feb 2009 22:19:09 -0000   1.20.8.1
+++ ofdev.c 12 Oct 2010 16:01:27 -0000
@@ -132,6 +132,88 @@
 
 char opened_name[MAXBOOTPATHLEN];
 
+/*
+ * Check if this APM partition is a suitable root partition and return
+ * its file system type or zero.
+ */
+static u_int8_t
+check_apm_root(struct part_map_entry *part, int *clust)
+{
+   struct blockzeroblock *bzb;
+   char typestr[32], *s;
+   u_int8_t fstype;
+
+   *clust = 0;  /* may become 1 for A/UX partitions */
+   fstype = 0;
+   bzb = (struct blockzeroblock *)(&part->pmBootArgs);
+
+   /* convert partition type name to upper case */
+   strncpy(typestr, (char *)part->pmPartType, sizeof(typestr));
+   typestr[sizeof(typestr) - 1] = '\0';
+   for (s = typestr; *s; s++)
+       if ((*s >= 'a') && (*s <= 'z'))
+           *s = (*s - 'a' + 'A');
+
+   if (strcmp(PART_TYPE_NBSD_PPCBOOT, typestr) == 0) {
+       if ((bzb->bzbMagic == BZB_MAGIC) &&
+           (bzb->bzbType < FSMAXTYPES))
+           fstype = bzb->bzbType;
+       else
+           fstype = FS_BSDFFS;
+   } else if (strcmp(PART_TYPE_UNIX, typestr) == 0 &&
+       bzb->bzbMagic == BZB_MAGIC && (bzb->bzbFlags & BZB_ROOTFS)) {
+       *clust = bzb->bzbCluster;
+       fstype = FS_BSDFFS;
+   }
+
+   return fstype;
+}
+
+/*
+ * Build a disklabel from APM partitions.
+ * We will just look for a suitable root partition and insert it into
+ * the 'a' slot. Should be sufficient to boot a kernel from it.
+ */
+static int
+search_mac_label(struct of_dev *devp, char *buf, struct disklabel *lp)
+{
+   struct part_map_entry *pme;
+   struct partition *a_part;
+   size_t nread;
+   int blkno, clust, lastblk, lastclust;
+   u_int8_t fstype;
+
+   pme = (struct part_map_entry *)buf;
+   a_part = &lp->d_partitions[0];      /* disklabel 'a' partition */
+   lastclust = -1;
+
+   for (blkno = lastblk = 1; blkno <= lastblk; blkno++) {
+       if (strategy(devp, F_READ, blkno, DEV_BSIZE, pme, &nread)
+           || nread != DEV_BSIZE)
+           return ERDLAB;
+       if (pme->pmSig != PART_ENTRY_MAGIC ||
+           pme->pmPartType[0] == '\0')
+           break;
+       lastblk = pme->pmMapBlkCnt;
+
+       fstype = check_apm_root(pme, &clust);
+
+       if (fstype && (lastclust == -1 || clust < lastclust)) {
+           a_part->p_size = pme->pmPartBlkCnt;
+           a_part->p_offset = pme->pmPyPartStart;
+           a_part->p_fstype = fstype;
+           if ((lastclust = clust) == 0)
+               break;  /* we won't find a better match */
+       }
+   }
+   if (lastclust < 0)
+       return ERDLAB;      /* no root partition found */
+
+   /* pretend we only have partitions 'a', 'b' and 'c' */
+   lp->d_npartitions = RAW_PART + 1;
+   return 0;
+}
+
 static u_long
 get_long(const void *p)
 {
@@ -141,11 +223,11 @@
 }
 
 /*
- * Find a valid disklabel.
+ * Find a valid disklabel from MBR partitions.
  */
 static int
-search_label(struct of_dev *devp, u_long off, u_char *buf, struct disklabel
*lp,
-        u_long off0)
+search_dos_label(struct of_dev *devp, u_long off, char *buf,
+    struct disklabel *lp, u_long off0)
 {
    size_t nread;
    struct mbr_partition *p;
@@ -187,7 +269,7 @@
            }
        } else if (p->mbrp_type == MBR_PTYPE_EXT) {
            poff = get_long(&p->mbrp_start);
-           if (!search_label(devp, poff, buf, lp, off0)) {
+           if (!search_dos_label(devp, poff, buf, lp, off0)) {
                recursion--;
                return 0;
            }
@@ -202,7 +284,6 @@
    return ERDLAB;
 }
 
-
 bool
 parsefilepath(const char *path, char *devname, char *fname, char *ppart)
 {
@@ -340,14 +421,9 @@
        return ENOENT;
    if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
        return ENXIO;
-#if 0
-   if (!strcmp(buf, "block"))
-       /*
-        * For block devices, indicate raw partition
-        * (:0 in OpenFirmware)
-        */
+   if (!strcmp(buf, "block") && strrchr(devname, ':') == NULL)
+       /* indicate raw partition, when missing */
        strlcat(devname, ":0", sizeof(devname));
-#endif
    if ((handle = OF_open(devname)) == -1)
        return ENXIO;
    memset(&ofdev, 0, sizeof ofdev);
@@ -362,8 +438,12 @@
                 LABELSECTOR, DEV_BSIZE, buf, &nread) != 0
            || nread != DEV_BSIZE
            || getdisklabel(buf, &label)) {
-           /* Else try MBR partitions */
-           error = search_label(&ofdev, 0, buf, &label, 0);
+           /* Else try APM or MBR partitions */
+           if (((struct drvr_map *)buf)->sbSig == DRIVER_MAP_MAGIC)
+               error = search_mac_label(&ofdev, buf, &label);
+           else
+               error = search_dos_label(&ofdev, 0, buf,
+                   &label, 0);
            if (error && error != ERDLAB)
                goto bad;
        }
@@ -375,7 +455,7 @@
                 * but there is none
                 */
                goto bad;
-           /* No, label, just use complete disk */
+           /* No label, just use complete disk */
            ofdev.partoff = 0;
        } else {
            part = partition ? partition - 'a' : 0;


-- 
Frank Wille



Home | Main Index | Thread Index | Old Index