1 /* $NetBSD: disksubr_mbr.c,v 1.1 2001/03/04 05:06:51 matt Exp $ */ 2 3 /* 4 * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Christopher G. Demetriou 17 * for the NetBSD Project. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by the University of 48 * California, Berkeley and its contributors. 49 * 4. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 66 */ 67 68 /* 69 * From i386 disklabel.c rev 1.29, with cleanups and modifications to 70 * make it easier to use on the arm32 and to use as MI code (not quite 71 * clean enough, yet). 72 */ 73 74 #include <sys/param.h> 75 #include <sys/systm.h> 76 #include <sys/buf.h> 77 #include <sys/disklabel.h> 78 79 #include "opt_mbr.h" 80 81 #define MBRSIGOFS 0x1fe 82 static char mbrsig[2] = {0x55, 0xaa}; 83 84 int fat_types[] = { 85 MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S, 86 MBR_PTYPE_FAT16B, MBR_PTYPE_FAT32, 87 MBR_PTYPE_FAT32L, MBR_PTYPE_FAT16L, 88 -1 89 }; 90 91 int 92 mbr_label_read(dev, strat, lp, osdep, msgp, cylp, netbsd_label_offp) 93 dev_t dev; 94 void (*strat) __P((struct buf *)); 95 struct disklabel *lp; 96 struct cpu_disklabel *osdep; 97 char **msgp; 98 int *cylp, *netbsd_label_offp; 99 { 100 struct mbr_partition *mbrp; 101 struct partition *pp; 102 int cyl, mbrpartoff, i, *ip; 103 struct buf *bp; 104 int rv = 1; 105 106 /* get a buffer and initialize it */ 107 bp = geteblk((int)lp->d_secsize); 108 bp->b_dev = dev; 109 110 /* In case nothing sets them */ 111 mbrpartoff = 0; 112 cyl = LABELSECTOR / lp->d_secpercyl; 113 114 mbrp = osdep->mbrparts; 115 116 /* read master boot record */ 117 bp->b_blkno = MBR_BBSECTOR; 118 bp->b_bcount = lp->d_secsize; 119 bp->b_flags |= B_READ; 120 bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl; 121 (*strat)(bp); 122 123 /* if successful, wander through dos partition table */ 124 if (biowait(bp)) { 125 *msgp = "dos partition I/O error"; 126 goto out; 127 } else { 128 struct mbr_partition *ourmbrp = NULL; 129 130 /* XXX "there has to be a better check than this." */ 131 if (bcmp(bp->b_data + MBRSIGOFS, mbrsig, sizeof(mbrsig))) { 132 rv = 0; 133 goto out; 134 } 135 136 /* XXX how do we check veracity/bounds of this? */ 137 bcopy(bp->b_data + MBR_PARTOFF, mbrp, 138 NMBRPART * sizeof(*mbrp)); 139 140 /* look for NetBSD partition */ 141 ourmbrp = NULL; 142 for (i = 0; !ourmbrp && i < NMBRPART; i++) { 143 if (mbrp[i].mbrp_typ == MBR_PTYPE_NETBSD) 144 ourmbrp = &mbrp[i]; 145 } 146 #ifdef COMPAT_386BSD_MBRPART 147 /* didn't find it -- look for 386BSD partition */ 148 for (i = 0; !ourmbrp && i < NMBRPART; i++) { 149 if (mbrp[i].mbrp_typ == MBR_PTYPE_386BSD) { 150 printf("WARNING: old BSD partition ID!\n"); 151 ourmbrp = &mbrp[i]; 152 break; 153 } 154 } 155 #endif 156 for (i = 0; i < NMBRPART; i++, mbrp++) { 157 158 strncpy(lp->d_packname, "fictitious-MBR", 159 sizeof lp->d_packname); 160 161 /* Install in partition e, f, g, or h. */ 162 pp = &lp->d_partitions['e' - 'a' + i]; 163 pp->p_offset = mbrp->mbrp_start; 164 pp->p_size = mbrp->mbrp_size; 165 for (ip = fat_types; *ip != -1; ip++) { 166 if (mbrp->mbrp_typ == *ip) 167 pp->p_fstype = FS_MSDOS; 168 } 169 if (mbrp->mbrp_typ == MBR_PTYPE_LNXEXT2) 170 pp->p_fstype = FS_EX2FS; 171 172 /* is this ours? */ 173 if (mbrp == ourmbrp) { 174 /* need sector address for SCSI/IDE, 175 cylinder for ESDI/ST506/RLL */ 176 mbrpartoff = mbrp->mbrp_start; 177 cyl = MBR_PCYL(mbrp->mbrp_scyl, mbrp->mbrp_ssect); 178 179 #ifdef __i386__ /* XXX? */ 180 /* update disklabel with details */ 181 lp->d_partitions[2].p_size = 182 mbrp->mbrp_size; 183 lp->d_partitions[2].p_offset = 184 mbrp->mbrp_start; 185 lp->d_ntracks = mbrp->mbrp_ehd + 1; 186 lp->d_nsectors = MBR_PSECT(mbrp->mbrp_esect); 187 lp->d_secpercyl = 188 lp->d_ntracks * lp->d_nsectors; 189 #endif 190 } 191 } 192 lp->d_npartitions = 'e' - 'a' + i; 193 } 194 195 *cylp = cyl; 196 *netbsd_label_offp = mbrpartoff; 197 *msgp = NULL; 198 out: 199 brelse(bp); 200 return (rv); 201 } 202 203 int 204 mbr_label_locate(dev, strat, lp, osdep, cylp, netbsd_label_offp) 205 dev_t dev; 206 void (*strat) __P((struct buf *)); 207 struct disklabel *lp; 208 struct cpu_disklabel *osdep; 209 int *cylp, *netbsd_label_offp; 210 { 211 struct mbr_partition *mbrp; 212 int cyl, mbrpartoff, i; 213 struct mbr_partition *ourmbrp = NULL; 214 struct buf *bp; 215 int rv = 1; 216 217 /* get a buffer and initialize it */ 218 bp = geteblk((int)lp->d_secsize); 219 bp->b_dev = dev; 220 221 /* do MBR partitions in the process of getting disklabel? */ 222 mbrpartoff = 0; 223 cyl = LABELSECTOR / lp->d_secpercyl; 224 225 mbrp = osdep->mbrparts; 226 227 /* read master boot record */ 228 bp->b_blkno = MBR_BBSECTOR; 229 bp->b_bcount = lp->d_secsize; 230 bp->b_flags |= B_READ; 231 bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl; 232 (*strat)(bp); 233 234 if ((rv = biowait(bp)) != 0) { 235 rv = -rv; 236 goto out; 237 } 238 239 if (bcmp(bp->b_data + MBRSIGOFS, mbrsig, sizeof(mbrsig))) { 240 rv = 0; 241 goto out; 242 } 243 244 /* XXX how do we check veracity/bounds of this? */ 245 bcopy(bp->b_data + MBR_PARTOFF, mbrp, NMBRPART * sizeof(*mbrp)); 246 247 /* look for NetBSD partition */ 248 ourmbrp = NULL; 249 for (i = 0; !ourmbrp && i < NMBRPART; i++) { 250 if (mbrp[i].mbrp_typ == MBR_PTYPE_NETBSD) 251 ourmbrp = &mbrp[i]; 252 } 253 #ifdef COMPAT_386BSD_MBRPART 254 /* didn't find it -- look for 386BSD partition */ 255 for (i = 0; !ourmbrp && i < NMBRPART; i++) { 256 if (mbrp[i].mbrp_typ == MBR_PTYPE_386BSD) { 257 printf("WARNING: old BSD partition ID!\n"); 258 ourmbrp = &mbrp[i]; 259 } 260 } 261 #endif 262 if (!ourmbrp) { 263 rv = 0; /* XXX allow easy clobber? */ 264 goto out; 265 } 266 267 /* need sector address for SCSI/IDE, cylinder for ESDI/ST506/RLL */ 268 mbrpartoff = ourmbrp->mbrp_start; 269 cyl = MBR_PCYL(ourmbrp->mbrp_scyl, ourmbrp->mbrp_ssect); 270 271 *cylp = cyl; 272 *netbsd_label_offp = mbrpartoff; 273 out: 274 brelse(bp); 275 return (rv); 276 } 277