summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2001-03-14 08:02:13 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2001-03-14 08:02:13 +0000
commit1b02ad742026c364f306e51bf6c0569a1eb9aa20 (patch)
tree62f6d1d92f4dd934fc2dd42060d9ec9e6a6ec5f0 /sys
parent4f84f4d31232004b002699c4918bd5dfede599f9 (diff)
Support shared disks with MacOS. This is only one of the pieces of
the task. The kernel now support a BSD disklabel located inside a HFS(DPME) partition of type "OpenBSD". It will use this disklabel for OpenBSD. If no OpenBSD DPME partition exists it will fake HFS partitions for apple HFS partitions of the disk. The tool to change the DPME partition type to OpenBSD and booting support in ofwboot are not yet ready.
Diffstat (limited to 'sys')
-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;