Home | History | Annotate | Line # | Download | only in ofwboot
mbr.c revision 1.2
      1  1.2  phx /*	$NetBSD: mbr.c,v 1.2 2011/08/18 09:03:28 phx Exp $	*/
      2  1.1  phx 
      3  1.1  phx /*
      4  1.1  phx  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
      5  1.1  phx  * Copyright (C) 1995, 1996 TooLs GmbH.
      6  1.1  phx  * All rights reserved.
      7  1.1  phx  *
      8  1.1  phx  * Redistribution and use in source and binary forms, with or without
      9  1.1  phx  * modification, are permitted provided that the following conditions
     10  1.1  phx  * are met:
     11  1.1  phx  * 1. Redistributions of source code must retain the above copyright
     12  1.1  phx  *    notice, this list of conditions and the following disclaimer.
     13  1.1  phx  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  phx  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  phx  *    documentation and/or other materials provided with the distribution.
     16  1.1  phx  * 3. All advertising materials mentioning features or use of this software
     17  1.1  phx  *    must display the following acknowledgement:
     18  1.1  phx  *	This product includes software developed by TooLs GmbH.
     19  1.1  phx  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     20  1.1  phx  *    derived from this software without specific prior written permission.
     21  1.1  phx  *
     22  1.1  phx  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     23  1.1  phx  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  1.1  phx  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  1.1  phx  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  1.1  phx  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27  1.1  phx  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     28  1.1  phx  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     29  1.1  phx  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     30  1.1  phx  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     31  1.1  phx  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  1.1  phx  */
     33  1.1  phx 
     34  1.1  phx #include <sys/param.h>
     35  1.1  phx #include <sys/bootblock.h>
     36  1.1  phx 
     37  1.1  phx #include <lib/libsa/byteorder.h>
     38  1.1  phx #include <lib/libsa/stand.h>
     39  1.1  phx 
     40  1.1  phx #include "mbr.h"
     41  1.1  phx 
     42  1.1  phx 
     43  1.1  phx static u_long
     44  1.1  phx get_long(const void *p)
     45  1.1  phx {
     46  1.1  phx 	const unsigned char *cp = p;
     47  1.1  phx 
     48  1.1  phx 	return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
     49  1.1  phx }
     50  1.1  phx 
     51  1.1  phx /*
     52  1.1  phx  * Find a valid MBR disklabel.
     53  1.1  phx  */
     54  1.1  phx int
     55  1.1  phx search_mbr_label(struct of_dev *devp, u_long off, char *buf,
     56  1.1  phx     struct disklabel *lp, u_long off0)
     57  1.1  phx {
     58  1.1  phx 	size_t read;
     59  1.1  phx 	struct mbr_partition *p;
     60  1.1  phx 	int i;
     61  1.1  phx 	u_long poff;
     62  1.1  phx 	static int recursion;
     63  1.1  phx 
     64  1.1  phx 	if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
     65  1.1  phx 	    || read != DEV_BSIZE)
     66  1.1  phx 		return ERDLAB;
     67  1.1  phx 
     68  1.1  phx 	if (*(u_int16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC))
     69  1.1  phx 		return ERDLAB;
     70  1.1  phx 
     71  1.1  phx 	if (recursion++ <= 1)
     72  1.1  phx 		off0 += off;
     73  1.1  phx 	for (p = (struct mbr_partition *)(buf + MBR_PART_OFFSET), i = 0;
     74  1.1  phx 	     i < MBR_PART_COUNT; i++, p++) {
     75  1.1  phx 		if (p->mbrp_type == MBR_PTYPE_NETBSD
     76  1.1  phx #ifdef COMPAT_386BSD_MBRPART
     77  1.1  phx 		    || (p->mbrp_type == MBR_PTYPE_386BSD &&
     78  1.1  phx 			(printf("WARNING: old BSD partition ID!\n"), 1)
     79  1.1  phx 			/* XXX XXX - libsa printf() is void */ )
     80  1.1  phx #endif
     81  1.1  phx 		    ) {
     82  1.1  phx 			poff = get_long(&p->mbrp_start) + off0;
     83  1.2  phx 			if (strategy(devp, F_READ, poff + MBR_LABELSECTOR,
     84  1.1  phx 				     DEV_BSIZE, buf, &read) == 0
     85  1.1  phx 			    && read == DEV_BSIZE) {
     86  1.2  phx 				if (getdisklabel(buf, lp) == NULL) {
     87  1.1  phx 					recursion--;
     88  1.1  phx 					return 0;
     89  1.1  phx 				}
     90  1.1  phx 			}
     91  1.1  phx 			if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
     92  1.1  phx 			    || read != DEV_BSIZE) {
     93  1.1  phx 				recursion--;
     94  1.1  phx 				return ERDLAB;
     95  1.1  phx 			}
     96  1.1  phx 		} else if (p->mbrp_type == MBR_PTYPE_EXT) {
     97  1.1  phx 			poff = get_long(&p->mbrp_start);
     98  1.1  phx 			if (!search_mbr_label(devp, poff, buf, lp, off0)) {
     99  1.1  phx 				recursion--;
    100  1.1  phx 				return 0;
    101  1.1  phx 			}
    102  1.1  phx 			if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
    103  1.1  phx 			    || read != DEV_BSIZE) {
    104  1.1  phx 				recursion--;
    105  1.1  phx 				return ERDLAB;
    106  1.1  phx 			}
    107  1.1  phx 		}
    108  1.1  phx 	}
    109  1.1  phx 
    110  1.1  phx 	recursion--;
    111  1.1  phx 	return ERDLAB;
    112  1.1  phx }
    113