diff options
Diffstat (limited to 'sys/arch/powerpc')
-rw-r--r-- | sys/arch/powerpc/include/disklabel.h | 68 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/disksubr.c | 117 |
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; |