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