Add support for reading MacOS-partitioned disks. Stolen from the mac68k
port, but modified in that macppc searches for netbsd-partitioned disks before MacOS partitioned disks, since installboot generates a fake MacOS partition table which isn't the one we want to use.
This commit is contained in:
parent
4b8ee1f7d2
commit
25faa820de
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: disklabel.h,v 1.3 1999/01/27 21:30:08 thorpej Exp $ */
|
||||
/* $NetBSD: disklabel.h,v 1.4 1999/09/27 17:02:43 wrstuden Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
|
||||
@ -30,6 +30,68 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1994 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Christopher G. Demetriou.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
* Michael L. Finch, Bradley A. Grantham, and
|
||||
* Lawrence A. Kesteloot
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Alice Group.
|
||||
* 4. The names of the Alice Group or any of its members may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_DISKLABEL_H_
|
||||
#define _MACHINE_DISKLABEL_H_
|
||||
@ -43,6 +105,103 @@ struct cpu_disklabel {
|
||||
int cd_start; /* Offset to NetBSD partition in blocks */
|
||||
};
|
||||
|
||||
/*
|
||||
* Driver Descriptor Map, from Inside Macintosh: Devices, SCSI Manager
|
||||
* pp 12-13. The driver descriptor map always resides on physical block 0.
|
||||
*/
|
||||
struct drvr_descriptor {
|
||||
u_int32_t descBlock; /* first block of driver */
|
||||
u_int16_t descSize; /* driver size in blocks */
|
||||
u_int16_t descType; /* system type */
|
||||
};
|
||||
|
||||
/* system types; Apple reserves 0-15 */
|
||||
#define DRVR_TYPE_MACINTOSH 1
|
||||
|
||||
struct drvr_map {
|
||||
#define DRIVER_MAP_MAGIC 0x4552
|
||||
u_int16_t sbSig; /* map signature */
|
||||
u_int16_t sbBlockSize; /* block size of device */
|
||||
u_int32_t sbBlkCount; /* number of blocks on device */
|
||||
u_int16_t sbDevType; /* (used internally by ROM) */
|
||||
u_int16_t sbDevID; /* (used internally by ROM) */
|
||||
u_int32_t sbData; /* (used internally by ROM) */
|
||||
u_int16_t sbDrvrCount; /* number of driver descriptors */
|
||||
#define DRVR_MAX_DESCRIPTORS 61
|
||||
struct drvr_descriptor sb_dd[DRVR_MAX_DESCRIPTORS];
|
||||
u_int16_t pad[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ddBlock(N) sb_dd[(N)].descBlock
|
||||
#define ddSize(N) sb_dd[(N)].descSize
|
||||
#define ddType(N) sb_dd[(N)].descType
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
u_int8_t pad[248]; /* pad to end of block */
|
||||
};
|
||||
|
||||
#define PART_TYPE_DRIVER "APPLE_DRIVER"
|
||||
#define PART_TYPE_DRIVER43 "APPLE_DRIVER43"
|
||||
#define PART_TYPE_DRIVERATA "APPLE_DRIVER_ATA"
|
||||
#define PART_TYPE_FWB_COMPONENT "FWB DRIVER COMPONENTS"
|
||||
#define PART_TYPE_MAC "APPLE_HFS"
|
||||
#define PART_TYPE_NETBSD "NETBSD"
|
||||
#define PART_TYPE_PARTMAP "APPLE_PARTITION_MAP"
|
||||
#define PART_TYPE_SCRATCH "APPLE_SCRATCH"
|
||||
#define PART_TYPE_UNIX "APPLE_UNIX_SVR2"
|
||||
|
||||
/*
|
||||
* "pmBootArgs" for APPLE_UNIX_SVR2 partition.
|
||||
* NetBSD/mac68k only uses Magic, Cluster, Type, and Flags.
|
||||
*/
|
||||
struct blockzeroblock {
|
||||
u_int32_t bzbMagic;
|
||||
u_int8_t bzbCluster;
|
||||
u_int8_t bzbType;
|
||||
u_int16_t bzbBadBlockInode;
|
||||
u_int16_t bzbFlags;
|
||||
u_int16_t bzbReserved;
|
||||
u_int32_t bzbCreationTime;
|
||||
u_int32_t bzbMountTime;
|
||||
u_int32_t bzbUMountTime;
|
||||
};
|
||||
|
||||
#define BZB_MAGIC 0xABADBABE
|
||||
#define BZB_TYPEFS 1
|
||||
#define BZB_TYPESWAP 3
|
||||
#define BZB_ROOTFS 0x8000
|
||||
#define BZB_USRFS 0x4000
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct disklabel;
|
||||
int bounds_check_with_label __P((struct buf *bp, struct disklabel *lp, int wlabel));
|
||||
|
@ -1,5 +1,72 @@
|
||||
/* $NetBSD: disksubr.c,v 1.4 1999/01/31 13:54:24 tsubai Exp $ */
|
||||
/* $NetBSD: disksubr.c,v 1.5 1999/09/27 17:02:44 wrstuden Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
||||
*/
|
||||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
* Michael L. Finch, Bradley A. Grantham, and
|
||||
* Lawrence A. Kesteloot
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Alice Group.
|
||||
* 4. The names of the Alice Group or any of its members may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 1996 Wolfgang Solfrank.
|
||||
* Copyright (C) 1996 TooLs GmbH.
|
||||
@ -30,47 +97,345 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* rewritten, 2-5-93 MLF */
|
||||
/* its alot cleaner now, and adding support for new partition types
|
||||
* isn't a bitch anymore
|
||||
* known bugs:
|
||||
* 1) when only an HFS_PART part exists on a drive it gets assigned to "B"
|
||||
* this is because of line 623 of sd.c, I think this line should go.
|
||||
* 2) /sbin/disklabel expects the whole disk to be in "D", we put it in
|
||||
* "C" (I think) and we don't set that position in the disklabel structure
|
||||
* as used. Again, not my fault.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/disklabel_mbr.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
static inline unsigned short get_short __P((void *p));
|
||||
static inline unsigned long get_long __P((void *p));
|
||||
#include <machine/bswap.h>
|
||||
|
||||
#define b_cylin b_resid
|
||||
|
||||
#define NUM_PARTS 32
|
||||
|
||||
#define ROOT_PART 1
|
||||
#define UFS_PART 2
|
||||
#define SWAP_PART 3
|
||||
#define HFS_PART 4
|
||||
#define SCRATCH_PART 5
|
||||
|
||||
int fat_types[] = { MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S,
|
||||
MBR_PTYPE_FAT16B, MBR_PTYPE_FAT32,
|
||||
MBR_PTYPE_FAT32L, MBR_PTYPE_FAT16L,
|
||||
-1 };
|
||||
|
||||
static int getFreeLabelEntry __P((struct disklabel *));
|
||||
static int whichType __P((struct part_map_entry *));
|
||||
static void setpartition __P((struct part_map_entry *,
|
||||
struct partition *, int));
|
||||
static int getNamedType __P((struct part_map_entry *, int,
|
||||
struct disklabel *, int, int, int *));
|
||||
static char *read_mac_label __P((dev_t, void (*)(struct buf *),
|
||||
struct disklabel *, struct cpu_disklabel *));
|
||||
static char *read_dos_label __P((dev_t, void (*)(struct buf *),
|
||||
struct disklabel *, struct cpu_disklabel *));
|
||||
static int get_netbsd_label __P((dev_t dev, void (*strat)(struct buf *),
|
||||
struct disklabel *lp, daddr_t bno));
|
||||
static int mbr_to_label __P((dev_t dev, void (*strat)(struct buf *),
|
||||
daddr_t bno, struct disklabel *lp,
|
||||
unsigned short *pnpart,
|
||||
struct cpu_disklabel *osdep, daddr_t off));
|
||||
struct disklabel *lp, daddr_t bno));
|
||||
|
||||
/*
|
||||
* Little endian access routines
|
||||
* Find an entry in the disk label that is unused and return it
|
||||
* or -1 if no entry
|
||||
*/
|
||||
static inline unsigned short
|
||||
get_short(p)
|
||||
void *p;
|
||||
static int
|
||||
getFreeLabelEntry(lp)
|
||||
struct disklabel *lp;
|
||||
{
|
||||
unsigned char *cp = p;
|
||||
int i = 0;
|
||||
|
||||
return cp[0] | (cp[1] << 8);
|
||||
for (i = 0; i < MAXPARTITIONS; i++) {
|
||||
if ((i != RAW_PART)
|
||||
&& (lp->d_partitions[i].p_fstype == FS_UNUSED))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
get_long(p)
|
||||
void *p;
|
||||
/*
|
||||
* figure out what the type of the given part is and return it
|
||||
*/
|
||||
static int
|
||||
whichType(part)
|
||||
struct part_map_entry *part;
|
||||
{
|
||||
unsigned char *cp = p;
|
||||
struct blockzeroblock *bzb;
|
||||
char typestr[32], *s;
|
||||
int type;
|
||||
|
||||
return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
|
||||
if (part->pmSig != PART_ENTRY_MAGIC || part->pmPartType[0] == '\0')
|
||||
return 0;
|
||||
|
||||
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_DRIVER, typestr) == 0 ||
|
||||
strcmp(PART_TYPE_DRIVER43, typestr) == 0 ||
|
||||
strcmp(PART_TYPE_DRIVERATA, typestr) == 0 ||
|
||||
strcmp(PART_TYPE_FWB_COMPONENT, typestr) == 0 ||
|
||||
strcmp(PART_TYPE_PARTMAP, typestr) == 0)
|
||||
type = 0;
|
||||
else if (strcmp(PART_TYPE_UNIX, typestr) == 0) {
|
||||
/* unix part, swap, root, usr */
|
||||
bzb = (struct blockzeroblock *)(&part->pmBootArgs);
|
||||
if (bzb->bzbMagic != BZB_MAGIC)
|
||||
type = 0;
|
||||
else if (bzb->bzbFlags & BZB_ROOTFS)
|
||||
type = ROOT_PART;
|
||||
else if (bzb->bzbFlags & BZB_USRFS)
|
||||
type = UFS_PART;
|
||||
else if (bzb->bzbType == BZB_TYPESWAP)
|
||||
type = SWAP_PART;
|
||||
else
|
||||
type = SCRATCH_PART;
|
||||
} else if (strcmp(PART_TYPE_MAC, typestr) == 0)
|
||||
type = HFS_PART;
|
||||
else
|
||||
type = SCRATCH_PART; /* no known type */
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
setpartition(part, pp, fstype)
|
||||
struct part_map_entry *part;
|
||||
struct partition *pp;
|
||||
{
|
||||
pp->p_size = part->pmPartBlkCnt;
|
||||
pp->p_offset = part->pmPyPartStart;
|
||||
pp->p_fstype = fstype;
|
||||
|
||||
part->pmPartType[0] = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
getNamedType(part, num_parts, lp, type, alt, maxslot)
|
||||
struct part_map_entry *part;
|
||||
int num_parts;
|
||||
struct disklabel *lp;
|
||||
int type, alt;
|
||||
int *maxslot;
|
||||
{
|
||||
struct blockzeroblock *bzb;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < num_parts; i++) {
|
||||
if (whichType(part + i) != type)
|
||||
continue;
|
||||
|
||||
if (type == ROOT_PART) {
|
||||
bzb = (struct blockzeroblock *)
|
||||
(&(part + i)->pmBootArgs);
|
||||
if (alt >= 0 && alt != bzb->bzbCluster)
|
||||
continue;
|
||||
setpartition(part + i, &lp->d_partitions[0], FS_BSDFFS);
|
||||
} else if (type == UFS_PART) {
|
||||
bzb = (struct blockzeroblock *)
|
||||
(&(part + i)->pmBootArgs);
|
||||
if (alt >= 0 && alt != bzb->bzbCluster)
|
||||
continue;
|
||||
setpartition(part + i, &lp->d_partitions[6], FS_BSDFFS);
|
||||
if (*maxslot < 6)
|
||||
*maxslot = 6;
|
||||
} else if (type == SWAP_PART) {
|
||||
setpartition(part + i, &lp->d_partitions[1], FS_SWAP);
|
||||
if (*maxslot < 1)
|
||||
*maxslot = 1;
|
||||
} else
|
||||
printf("disksubr.c: can't do type %d\n", type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* MF --
|
||||
* here's what i'm gonna do:
|
||||
* read in the entire diskpartition table, it may be bigger or smaller
|
||||
* than NUM_PARTS but read that many entries. Each entry has a magic
|
||||
* number so we'll know if an entry is crap.
|
||||
* next fill in the disklabel with info like this
|
||||
* next fill in the root, usr, and swap parts.
|
||||
* then look for anything else and fit it in.
|
||||
* A: root
|
||||
* B: Swap
|
||||
* C: Whole disk
|
||||
* G: Usr
|
||||
*
|
||||
*
|
||||
* I'm not entirely sure what netbsd386 wants in c & d
|
||||
* 386bsd wants other stuff, so i'll leave them alone
|
||||
*
|
||||
* AKB -- I added to Mike's original algorithm by searching for a bzbCluster
|
||||
* of zero for root, first. This allows A/UX to live on cluster 1 and
|
||||
* NetBSD to live on cluster 0--regardless of the actual order on the
|
||||
* disk. This whole algorithm should probably be changed in the future.
|
||||
*/
|
||||
static char *
|
||||
read_mac_label(dev, strat, lp, osdep)
|
||||
dev_t dev;
|
||||
void (*strat)(struct buf *);
|
||||
struct disklabel *lp;
|
||||
struct cpu_disklabel *osdep;
|
||||
{
|
||||
struct part_map_entry *part;
|
||||
struct partition *pp;
|
||||
struct buf *bp;
|
||||
char *msg = NULL;
|
||||
int i, slot, maxslot = 0;
|
||||
|
||||
/* get buffer and initialize it */
|
||||
bp = geteblk((int)lp->d_secsize * NUM_PARTS);
|
||||
bp->b_dev = dev;
|
||||
|
||||
/* read partition map */
|
||||
bp->b_blkno = 1; /* partition map starts at blk 1 */
|
||||
bp->b_bcount = lp->d_secsize * NUM_PARTS;
|
||||
bp->b_flags = B_BUSY | B_READ;
|
||||
bp->b_cylin = 1 / lp->d_secpercyl;
|
||||
(*strat)(bp);
|
||||
|
||||
if (biowait(bp)) {
|
||||
msg = "Macintosh partition map I/O error";
|
||||
goto done;
|
||||
}
|
||||
|
||||
part = (struct part_map_entry *)bp->b_data;
|
||||
|
||||
/* Fill in standard partitions */
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
if (getNamedType(part, NUM_PARTS, lp, ROOT_PART, 0, &maxslot))
|
||||
getNamedType(part, NUM_PARTS, lp, ROOT_PART, -1, &maxslot);
|
||||
if (getNamedType(part, NUM_PARTS, lp, UFS_PART, 0, &maxslot))
|
||||
getNamedType(part, NUM_PARTS, lp, UFS_PART, -1, &maxslot);
|
||||
getNamedType(part, NUM_PARTS, lp, SWAP_PART, -1, &maxslot);
|
||||
|
||||
/* Now get as many of the rest of the partitions as we can */
|
||||
for (i = 0; i < NUM_PARTS; i++) {
|
||||
slot = getFreeLabelEntry(lp);
|
||||
if (slot < 0)
|
||||
break;
|
||||
|
||||
pp = &lp->d_partitions[slot];
|
||||
|
||||
switch (whichType(part + i)) {
|
||||
case ROOT_PART:
|
||||
/*
|
||||
* another root part will turn into a plain old
|
||||
* UFS_PART partition, live with it.
|
||||
*/
|
||||
case UFS_PART:
|
||||
setpartition(part + i, pp, FS_BSDFFS);
|
||||
break;
|
||||
case SWAP_PART:
|
||||
setpartition(part + i, pp, FS_SWAP);
|
||||
break;
|
||||
case HFS_PART:
|
||||
setpartition(part + i, pp, FS_HFS);
|
||||
break;
|
||||
case SCRATCH_PART:
|
||||
setpartition(part + i, pp, FS_OTHER);
|
||||
break;
|
||||
default:
|
||||
slot = 0;
|
||||
break;
|
||||
}
|
||||
if (slot > maxslot)
|
||||
maxslot = slot;
|
||||
}
|
||||
lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
|
||||
|
||||
done:
|
||||
bp->b_flags |= B_INVAL;
|
||||
brelse(bp);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* Read MS-DOS partition table.
|
||||
*
|
||||
* XXX -
|
||||
* Since FFS is endian sensitive, we pay no effort in attempting to
|
||||
* dig up *BSD/i386 disk labels that may be present on the disk.
|
||||
* Hence anything but DOS partitions is treated as unknown FS type, but
|
||||
* this should suffice to mount_msdos Zip and other removable media.
|
||||
*/
|
||||
static char *
|
||||
read_dos_label(dev, strat, lp, osdep)
|
||||
dev_t dev;
|
||||
void (*strat)(struct buf *);
|
||||
struct disklabel *lp;
|
||||
struct cpu_disklabel *osdep;
|
||||
{
|
||||
struct mbr_partition *dp;
|
||||
struct partition *pp;
|
||||
struct buf *bp;
|
||||
char *msg = NULL;
|
||||
int i, *ip, slot, maxslot = 0;
|
||||
|
||||
/* get a buffer and initialize it */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dev;
|
||||
|
||||
/* read master boot record */
|
||||
bp->b_blkno = MBR_BBSECTOR;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_flags = B_BUSY | B_READ;
|
||||
bp->b_cylin = MBR_BBSECTOR / lp->d_secpercyl;
|
||||
(*strat)(bp);
|
||||
|
||||
/* if successful, wander through dos partition table */
|
||||
if (biowait(bp)) {
|
||||
msg = "dos partition I/O error";
|
||||
goto done;
|
||||
} else {
|
||||
/* XXX */
|
||||
dp = (struct mbr_partition *)(bp->b_data + MBR_PARTOFF);
|
||||
for (i = 0; i < NMBRPART; i++, dp++) {
|
||||
if (dp->mbrp_typ != 0) {
|
||||
slot = getFreeLabelEntry(lp);
|
||||
if (slot > maxslot)
|
||||
maxslot = slot;
|
||||
|
||||
pp = &lp->d_partitions[slot];
|
||||
pp->p_fstype = FS_OTHER;
|
||||
pp->p_offset = bswap32(dp->mbrp_start);
|
||||
pp->p_size = bswap32(dp->mbrp_size);
|
||||
|
||||
for (ip = fat_types; *ip != -1; ip++) {
|
||||
if (dp->mbrp_typ == *ip) {
|
||||
pp->p_fstype = FS_MSDOS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
|
||||
|
||||
done:
|
||||
bp->b_flags |= B_INVAL;
|
||||
brelse(bp);
|
||||
return (msg);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -119,141 +484,69 @@ done:
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct disklabel entries from partition entries.
|
||||
*/
|
||||
static int
|
||||
mbr_to_label(dev, strat, bno, lp, pnpart, osdep, off)
|
||||
dev_t dev;
|
||||
void (*strat)();
|
||||
daddr_t bno;
|
||||
struct disklabel *lp;
|
||||
unsigned short *pnpart;
|
||||
struct cpu_disklabel *osdep;
|
||||
daddr_t off;
|
||||
{
|
||||
static int recursion = 0;
|
||||
struct mbr_partition *mp;
|
||||
struct partition *pp;
|
||||
struct buf *bp;
|
||||
int i, found = 0;
|
||||
|
||||
/* Check for recursion overflow. */
|
||||
if (recursion > MAXPARTITIONS)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Extended partitions seem to be relative to their first occurence?
|
||||
*/
|
||||
if (recursion++ == 1)
|
||||
off = bno;
|
||||
|
||||
/* get a buffer and initialize it */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dev;
|
||||
|
||||
/* Now get the MBR */
|
||||
bp->b_blkno = bno;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_flags = B_BUSY | B_READ;
|
||||
bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
|
||||
(*strat)(bp);
|
||||
|
||||
if (biowait(bp))
|
||||
goto done;
|
||||
|
||||
if (get_short(bp->b_data + MBR_MAGICOFF) != MBR_MAGIC)
|
||||
goto done;
|
||||
|
||||
/* Extract info from MBR partition table */
|
||||
mp = (struct mbr_partition *)(bp->b_data + MBR_PARTOFF);
|
||||
for (i = 0; i < NMBRPART; i++, mp++) {
|
||||
if (get_long(&mp->mbrp_size)) {
|
||||
switch (mp->mbrp_typ) {
|
||||
case MBR_PTYPE_EXT:
|
||||
if (*pnpart < MAXPARTITIONS) {
|
||||
pp = lp->d_partitions + *pnpart;
|
||||
bzero(pp, sizeof *pp);
|
||||
pp->p_size = get_long(&mp->mbrp_size);
|
||||
pp->p_offset = off + get_long(&mp->mbrp_start);
|
||||
++*pnpart;
|
||||
}
|
||||
if (found = mbr_to_label(dev, strat,
|
||||
off + get_long(&mp->mbrp_start),
|
||||
lp, pnpart, osdep, off))
|
||||
goto done;
|
||||
break;
|
||||
case MBR_PTYPE_NETBSD:
|
||||
/* Found the real NetBSD partition, use it */
|
||||
osdep->cd_start = off + get_long(&mp->mbrp_start);
|
||||
if (found = get_netbsd_label(dev, strat, lp, osdep->cd_start))
|
||||
goto done;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (*pnpart < MAXPARTITIONS) {
|
||||
pp = lp->d_partitions + *pnpart;
|
||||
bzero(pp, sizeof *pp);
|
||||
pp->p_size = get_long(&mp->mbrp_size);
|
||||
pp->p_offset = off + get_long(&mp->mbrp_start);
|
||||
++*pnpart;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
recursion--;
|
||||
bp->b_flags |= B_INVAL;
|
||||
brelse(bp);
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to read a disk label from a device
|
||||
* using the indicated strategy routine.
|
||||
* Attempt to read a disk label from a device using the indicated stategy
|
||||
* routine. The label must be partly set up before this: secpercyl and
|
||||
* anything required in the strategy routine (e.g., sector size) must be
|
||||
* filled in before calling us. Returns null on success and an error
|
||||
* string on failure.
|
||||
*
|
||||
* If we can't find a NetBSD label, we attempt to fake one
|
||||
* based on the MBR (and extended partition) information
|
||||
* This will read sector zero. If this contains what looks like a valid
|
||||
* Macintosh boot sector, we attempt to fill in the disklabel structure.
|
||||
* If the first longword of the disk is a NetBSD disk label magic number,
|
||||
* then we assume that it's a real disklabel and return it.
|
||||
*/
|
||||
char *
|
||||
readdisklabel(dev, strat, lp, osdep)
|
||||
dev_t dev;
|
||||
void (*strat)();
|
||||
void (*strat)(struct buf *);
|
||||
struct disklabel *lp;
|
||||
struct cpu_disklabel *osdep;
|
||||
{
|
||||
struct mbr_partition *mp;
|
||||
struct buf *bp;
|
||||
char *msg = 0;
|
||||
int i;
|
||||
char *msg = NULL;
|
||||
struct disklabel *dlp;
|
||||
|
||||
/* Initialize disk label with some defaults */
|
||||
if (lp->d_secsize == 0)
|
||||
lp->d_secsize = DEV_BSIZE;
|
||||
if (lp->d_secpercyl == 0)
|
||||
lp->d_secpercyl = 1;
|
||||
if (lp->d_secperunit == 0)
|
||||
lp->d_secperunit = 0x7fffffff;
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
for (i = 0; i < MAXPARTITIONS; i++) {
|
||||
if (i != RAW_PART) {
|
||||
lp->d_partitions[i].p_size = 0;
|
||||
lp->d_partitions[i].p_offset = 0;
|
||||
}
|
||||
}
|
||||
if (lp->d_partitions[RAW_PART].p_size == 0) {
|
||||
lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
|
||||
lp->d_partitions[RAW_PART].p_offset = 0;
|
||||
lp->d_secperunit = 0x1fffffff;
|
||||
|
||||
if (lp->d_secpercyl == 0) {
|
||||
return msg = "Zero secpercyl";
|
||||
}
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
|
||||
bp->b_dev = dev;
|
||||
bp->b_blkno = 0;
|
||||
bp->b_resid = 0;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_flags = B_BUSY | B_READ;
|
||||
bp->b_cylin = 1 / lp->d_secpercyl;
|
||||
(*strat)(bp);
|
||||
|
||||
osdep->cd_start = -1;
|
||||
|
||||
if (get_netbsd_label(dev, strat, lp, 0)) {
|
||||
if (biowait(bp)) {
|
||||
msg = "I/O error reading block zero";
|
||||
} if (get_netbsd_label(dev, strat, lp, 0)) {
|
||||
osdep->cd_start = 0;
|
||||
}
|
||||
osdep->cd_start = 0; /* XXX for now */
|
||||
msg = "NetBSD disklabel";
|
||||
} else {
|
||||
u_int16_t *sbSigp;
|
||||
|
||||
/*mbr_to_label(dev, strat, MBR_BBSECTOR, lp, &lp->d_npartitions, osdep, 0);*/
|
||||
return 0;
|
||||
sbSigp = (u_int16_t *)bp->b_un.b_addr;
|
||||
if (*sbSigp == 0x4552) {
|
||||
msg = read_mac_label(dev, strat, lp, osdep);
|
||||
} else if (bswap16(*(u_int16_t *)(bp->b_data + MBR_MAGICOFF))
|
||||
== MBR_MAGIC) {
|
||||
msg = read_dos_label(dev, strat, lp, osdep);
|
||||
} else {
|
||||
msg = "no disk label -- NetBSD or Macintosh";
|
||||
osdep->cd_start = 0; /* XXX for now */
|
||||
}
|
||||
}
|
||||
|
||||
bp->b_flags |= B_INVAL;
|
||||
brelse(bp);
|
||||
return (msg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user