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:
wrstuden 1999-09-27 17:02:43 +00:00
parent 4b8ee1f7d2
commit 25faa820de
2 changed files with 596 additions and 144 deletions

View File

@ -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));

View File

@ -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);
}
/*