Port-macppc archive

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

Native BSD disklabel access



All,

a few days ago, I had the need to access a sparc disk from a Macintosh G3.
Same endianness, so no problem, I thought.

The macppc kernel only gave me a generic, empty disklabel where I expected
my partitions. 'disklabel -r' gave me the expected list, but unlike
mbrlabel(8), disklabel(8) has no way of feeding a label to the kernel.

Looking at macppc/macppc/disksubr.c, I found that the support for reading
native disklabels I added to the mac68k port twelve years ago had never
made it across. Prying a disklabel out of an mbr partition, yes (what for?
It'll be LE, most likely), but no native BSD label.

In the wake of netbsd-6, I didn't want to be too intrusive (although
disksubr.c could use some tough love), just plopped in an adapted version
of the mac68k routine, and was able to access the sparc disk.

Comments? Okay to commit?

        hauke


<snip>
Index: macppc/macppc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/macppc/disksubr.c,v
retrieving revision 1.47
diff -u -u -r1.47 disksubr.c
--- macppc/macppc/disksubr.c    16 Mar 2009 23:11:12 -0000      1.47
+++ macppc/macppc/disksubr.c    20 Jan 2012 16:38:44 -0000
@@ -137,6 +137,8 @@
                struct disklabel *, struct cpu_disklabel *);
 static const char *read_dos_label(dev_t, void (*)(struct buf *),
                struct disklabel *, struct cpu_disklabel *);
+static const char *read_bsd_label(dev_t, void (*)(struct buf *),
+               struct disklabel *, struct cpu_disklabel *);
 static int get_netbsd_label(dev_t, void (*)(struct buf *),
                struct disklabel *, struct cpu_disklabel *);

@@ -387,6 +389,78 @@
        return msg;
 }

+/*
+ * Scan the disk buffer in four byte strides for a native BSD
+ * disklabel (different ports have variably-sized bootcode before
+ * the label)
+ */
+static const char *
+read_bsd_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
+    struct cpu_disklabel *osdep)
+{
+       struct disklabel *dlp;
+       struct buf *bp;
+       const char *msg;
+       struct disklabel *blk_start, *blk_end;
+       int size, match;
+
+       msg = NULL;
+
+       /*
+        * Read in the first #(NUM_PARTS + 1) blocks of the disk.
+        * The native Macintosh partition table starts at
+        * sector #1, but we want #0 too for the BSD label.
+        */
+       size = roundup((NUM_PARTS + 1) << DEV_BSHIFT, lp->d_secsize);
+       bp = geteblk(size);
+
+       bp->b_dev = dev;
+       bp->b_blkno = 0;
+       bp->b_resid = 0;
+       bp->b_bcount = size;
+       bp->b_flags |= B_READ;
+       bp->b_cylinder = 1 / lp->d_secpercyl;
+       (*strat)(bp);
+
+       match = 0;
+
+       if (biowait(bp)) {
+               msg = "I/O error reading BSD disklabel";
+       } else {
+               /*
+                * Hunt the label, starting at the beginning of the disk.
+                * When we find an inconsistent label, report and continue.
+                */
+               blk_start = (struct disklabel *)bp->b_data;
+               blk_end = (struct disklabel *)((char *)bp->b_data +
+                   (NUM_PARTS << DEV_BSHIFT) - sizeof(struct disklabel));
+
+               for (dlp = blk_start; dlp <= blk_end;
+                    dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+                       if (dlp->d_magic == DISKMAGIC &&
+                           dlp->d_magic2 == DISKMAGIC) {
+                               /* Sanity check */
+                               if (dlp->d_npartitions <= MAXPARTITIONS &&
+                                   dkcksum(dlp) == 0) {
+                                       *lp = *dlp;
+                                       match = -1;
+                                       break;
+#ifdef DIAGNOSTIC
+                               } else {
+                                       printf("read_bsd_label() found "
+                                           "damaged disklabel starting at "
+                                           "0x0%p, ignore\n", dlp);
+#endif /* DIAGNOSTIC */
+                               }
+                       }
+               }
+               if (!match)
+                       msg = "BSD disklabel not found";
+       }
+       brelse(bp, 0);
+       return msg;
+}
+
 /* Read MS-DOS partition table.
  *
  * XXX -
@@ -597,8 +671,9 @@
                        if (!msg)
                                osdep->cd_start = 0;
                } else {
-                       msg = "no disk label -- NetBSD or Macintosh";
-                       osdep->cd_start = 0;    /* XXX for now */
+                       msg = read_bsd_label(dev, strat, lp, osdep);
+                       if (!msg)
+                               osdep->cd_start = 0;    /* XXX for now */
                }
        }

</snip>


-- 
Hauke Fath                        <hauke%Espresso.Rhein-Neckar.DE@localhost>
Friedrich-Ebert-Straße 70
64347 Griesheim
Germany


Home | Main Index | Thread Index | Old Index