summaryrefslogtreecommitdiff
path: root/sys/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/powerpc')
-rw-r--r--sys/arch/powerpc/include/disklabel.h68
-rw-r--r--sys/arch/powerpc/powerpc/disksubr.c117
2 files changed, 176 insertions, 9 deletions
diff --git a/sys/arch/powerpc/include/disklabel.h b/sys/arch/powerpc/include/disklabel.h
index 1e76f9d9725..c1db665f39a 100644
--- a/sys/arch/powerpc/include/disklabel.h
+++ b/sys/arch/powerpc/include/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.13 1999/12/04 03:35:57 deraadt Exp $ */
+/* $OpenBSD: disklabel.h,v 1.14 2001/03/14 08:02:11 drahn Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -79,12 +79,6 @@ struct dos_partition {
#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
#include <sys/dkbad.h>
-struct cpu_disklabel {
- struct dos_partition dosparts[NDOSPART];
- struct dkbad bad;
-};
-
-#define DKBAD(x) ((x)->bad)
/* Isolate the relevant bits to get sector and cylinder. */
#define DPSECT(s) ((s) & 0x3f)
@@ -110,4 +104,64 @@ get_le(p)
return x;
}
+/* HFS/DPME */
+
+/* partition map structure from Inside Macintosh: Devices, SCSI Manager
+ * pp. 13-14. The partition map always begins on physical block 1.
+ *
+ * With the exception of block 0, all blocks on the disk must belong to
+ * exactly one partition. The partition map itself belongs to a partition
+ * of type `APPLE_PARTITION_MAP', and is not limited in size by anything
+ * other than available disk space. The partition map is not necessarily
+ * the first partition listed.
+ */
+struct part_map_entry {
+#define PART_ENTRY_MAGIC 0x504d
+ u_int16_t pmSig; /* partition signature */
+ u_int16_t pmSigPad; /* (reserved) */
+ u_int32_t pmMapBlkCnt; /* number of blocks in partition map */
+ u_int32_t pmPyPartStart; /* first physical block of partition */
+ u_int32_t pmPartBlkCnt; /* number of blocks in partition */
+ char pmPartName[32]; /* partition name */
+ char pmPartType[32]; /* partition type */
+ u_int32_t pmLgDataStart; /* first logical block of data area */
+ u_int32_t pmDataCnt; /* number of blocks in data area */
+ u_int32_t pmPartStatus; /* partition status information */
+ u_int32_t pmLgBootStart; /* first logical block of boot code */
+ u_int32_t pmBootSize; /* size of boot code, in bytes */
+ u_int32_t pmBootLoad; /* boot code load address */
+ u_int32_t pmBootLoad2; /* (reserved) */
+ u_int32_t pmBootEntry; /* boot code entry point */
+ u_int32_t pmBootEntry2; /* (reserved) */
+ u_int32_t pmBootCksum; /* boot code checksum */
+ char pmProcessor[16]; /* processor type (e.g. "68020") */
+ u_int8_t pmBootArgs[128]; /* A/UX boot arguments */
+ /* we do not index the disk image as an array,
+ * leave out the on disk padding
+ */
+#if 0
+ u_int8_t pad[248]; /* pad to end of block */
+#endif
+};
+
+#define PART_TYPE_DRIVER "APPLE_DRIVER"
+#define PART_TYPE_DRIVER43 "APPLE_DRIVER43"
+#define PART_TYPE_DRIVERATA "APPLE_DRIVER_ATA"
+#define PART_TYPE_DRIVERIOKIT "APPLE_DRIVER_IOKIT"
+#define PART_TYPE_FWDRIVER "APPLE_FWDRIVER"
+#define PART_TYPE_FWB_COMPONENT "FWB DRIVER COMPONENTS"
+#define PART_TYPE_FREE "APPLE_FREE"
+#define PART_TYPE_MAC "APPLE_HFS"
+#define PART_TYPE_OPENBSD "OPENBSD"
+
+
+struct cpu_disklabel {
+ struct dos_partition dosparts[NDOSPART];
+ /* only store first entry and openbsd partition */
+ struct part_map_entry macparts[2];
+ struct dkbad bad;
+};
+
+#define DKBAD(x) ((x)->bad)
+
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/powerpc/powerpc/disksubr.c b/sys/arch/powerpc/powerpc/disksubr.c
index 5e22ec62e18..8bb0ea29813 100644
--- a/sys/arch/powerpc/powerpc/disksubr.c
+++ b/sys/arch/powerpc/powerpc/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.14 2000/10/18 21:00:39 mickey Exp $ */
+/* $OpenBSD: disksubr.c,v 1.15 2001/03/14 08:02:12 drahn Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -89,7 +89,12 @@ readdisklabel(dev, strat, lp, osdep, spoofonly)
struct buf *bp;
struct disklabel *dlp;
char *msg = NULL, *cp;
+ char *s;
int dospartoff, cyl, i, ourpart = -1;
+ /* HFS variables */
+ int part_cnt, n, hfspartoff;
+ struct part_map_entry *part;
+
/* minimal requirements for archtypal disk label */
if (lp->d_secsize == 0)
@@ -109,13 +114,97 @@ readdisklabel(dev, strat, lp, osdep, spoofonly)
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
+ /* DPME (HFS) disklabel */
+
+ bp->b_blkno = 1;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = 1 / lp->d_secpercyl;
+ (*strat)(bp);
+
+ /* if successful, wander through DPME partition table */
+ if (biowait(bp)) {
+ msg = "DPME partition I/O error";
+ goto hfs_done;
+ }
+
+ part = (struct part_map_entry *)bp->b_data;
+ /* if first partition is not valid, assume not HFS/DPME partitioned */
+ if (part->pmSig != PART_ENTRY_MAGIC) {
+ msg = "DPME partition invalid";
+ osdep->macparts[0].pmSig = 0; /* make invalid */
+ goto hfs_done;
+ }
+ osdep->macparts[0] = *part;
+ part_cnt = part->pmMapBlkCnt;
+ n = 0;
+ for (i = 0; i < part_cnt; i++) {
+ struct partition *pp = &lp->d_partitions[8+n];
+
+ bp->b_blkno = 1+i;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = 1+i / lp->d_secpercyl;
+ (*strat)(bp);
+
+ if (biowait(bp)) {
+ msg = "DPME partition I/O error";
+ goto hfs_done;
+ }
+ part = (struct part_map_entry *)bp->b_data;
+ /* toupper the string, in case caps are different... */
+ for (s = part->pmPartType; *s; s++)
+ if ((*s >= 'a') && (*s <= 'z'))
+ *s = (*s - 'a' + 'A');
+
+ if (0 == strcmp(part->pmPartType, PART_TYPE_OPENBSD)) {
+ hfspartoff = part->pmPyPartStart;
+ osdep->macparts[1] = *part;
+ }
+ /* currently we ignore all but HFS partitions */
+ if (0 == strcmp(part->pmPartType, PART_TYPE_MAC)) {
+ pp->p_offset = part->pmPyPartStart;
+ pp->p_size = part->pmPartBlkCnt;
+ pp->p_fstype = FS_HFS;
+ n++;
+#if 0
+ printf("found DPME HFS partition [%s], adding to fake\n",
+ part->pmPartName);
+#endif
+ }
+ }
+ lp->d_npartitions = MAXPARTITIONS;
+
+ /* don't read the on-disk label if we are in spoofed-only mode */
+ if (spoofonly)
+ goto done;
+
+ /* next, dig out disk label */
+ bp->b_blkno = hfspartoff;
+ bp->b_cylin = hfspartoff/lp->d_secpercyl; /* XXX */
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ if (biowait(bp)) {
+ /* XXX we return the faked label built so far */
+ msg = "disk label I/O error";
+ goto done;
+ }
+ goto found_disklabel;
+
+
+hfs_done:
+ /* MBR type disklabel */
/* do dos partitions in the process of getting disklabel? */
dospartoff = 0;
cyl = LABELSECTOR / lp->d_secpercyl;
if (dp) {
daddr_t part_blkno = DOSBBSECTOR;
unsigned long extoff = 0;
- int wander = 1, n = 0, loop = 0;
+ int wander = 1, loop = 0;
+ n = 0;
/*
* Read dos partition table, follow extended partitions.
@@ -262,6 +351,8 @@ donot:
msg = "disk label I/O error";
goto done;
}
+
+found_disklabel:
for (dlp = (struct disklabel *)bp->b_data;
dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
@@ -405,6 +496,28 @@ writedisklabel(dev, strat, lp, osdep)
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
+ /* try DPME partition */
+ if (osdep->macparts[0].pmSig == PART_ENTRY_MAGIC) {
+
+ /* only write if a valid "OpenBSD" partition type exists */
+ if (osdep->macparts[1].pmSig == PART_ENTRY_MAGIC) {
+ bp->b_blkno = osdep->macparts[1].pmPyPartStart;
+ bp->b_cylin = bp->b_blkno/lp->d_secpercyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_WRITE;
+ *(struct disklabel *)bp->b_data = *lp;
+ (*strat)(bp);
+ error = biowait(bp);
+ goto done;
+ }
+
+ /* SHOULD FAIL TO WRITE LABEL IF VALID HFS partition exists
+ * and no OpenBSD partition exists
+ */
+ error = 1; /* EPERM? */
+ goto done;
+ }
+
/* do dos partitions in the process of getting disklabel? */
dospartoff = 0;
cyl = LABELSECTOR / lp->d_secpercyl;