Example #1
0
static int
machdep_bootdev(u_long value)
{
	int majdev, unit, slice, part;
	struct _foo *p;

	if ((value & B_MAGICMASK) != B_DEVMAGIC) {
		printf("invalid (0x%08lx)", value);
		return 0;
	}
	majdev = B_TYPE(value);
	unit = B_UNIT(value);
	slice = B_SLICE(value);
	part = B_PARTITION(value);
	if (majdev == 2) {	/* floppy, as known to the boot block... */
		printf("/dev/fd%d", unit);
		return 0;
	}
	for (p = maj2name; p->name != NULL && p->majdev != majdev ; p++) ;
	if (p->name != NULL) {	/* found */
		if (slice == WHOLE_DISK_SLICE)
			printf("/dev/%s%d%c", p->name, unit, part);
		else
			printf("/dev/%s%ds%d%c",
			    p->name, unit, slice - BASE_SLICE + 1, part + 'a');
	} else
		printf("unknown (major %d unit %d slice %d part %d)",
			majdev, unit, slice, part);
	return 0;
}
Example #2
0
int
main()
{
	int currname = 0;

	printf("\n>> OpenBSD [%dKB] UNIFIED BOOT %s HP 9000/%s CPU\n",
	       (__LDPGSZ / 1024), version, getmachineid());
	printf(">> Enter \"reset\" to reset system.\n");

	bdev   = B_TYPE(bootdev);
	badapt = B_ADAPTOR(bootdev);
	bctlr  = B_CONTROLLER(bootdev);
	bunit  = B_UNIT(bootdev);
	bpart  = B_PARTITION(bootdev);

	for (;;) {
		name = names[currname++];
		if (currname == NUMNAMES)
			currname = 0;

		if (!noconsole) {
			howto = 0;
			getbootdev(&howto);
		} else
			printf(": %s\n", name);

		exec(name, lowram, howto);
		printf("boot: %s\n", strerror(errno));
	}
	return (0);
}
Example #3
0
/*
 * Attempt to find the device from which we were booted.
 * If we can do so, and not instructed not to do so,
 * change rootdev to correspond to the load device.
 */
void
findroot(void)
{
	int i, majdev, unit, part;
	struct device *dv;
	char buf[32];

#if 0
	printf("howto %x bootdev %x ", boothowto, bootdev);
#endif

	if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
		return;

	majdev = B_TYPE(bootdev);
	for (i = 0; dev_name2blk[i].d_name != NULL; i++)
		if (majdev == dev_name2blk[i].d_maj)
			break;
	if (dev_name2blk[i].d_name == NULL)
		return;

	part = B_PARTITION(bootdev);
	unit = B_UNIT(bootdev);

	sprintf(buf, "%s%d", dev_name2blk[i].d_name, unit);
	for (dv = alldevs.tqh_first; dv != NULL;
	    dv = dv->dv_list.tqe_next) {
		if (strcmp(buf, dv->dv_xname) == 0) {
			booted_device = dv;
			booted_partition = part;
			return;
		}
	}
}
Example #4
0
/*
 * Now that we are fully operational, we can checksum the
 * disks, and using some heuristics, hopefully are able to
 * always determine the correct root disk.
 */
void
diskconf(void)
{
	int majdev, unit, part = 0;
	struct device *bootdv = NULL;
	dev_t tmpdev;
	char buf[128];
	extern bios_bootmac_t *bios_bootmac;

	dkcsumattach();

	if ((bootdev & B_MAGICMASK) == (u_int)B_DEVMAGIC) {
		majdev = B_TYPE(bootdev);
		unit = B_UNIT(bootdev);
		part = B_PARTITION(bootdev);
		snprintf(buf, sizeof buf, "%s%d%c", findblkname(majdev),
		    unit, part + 'a');
		bootdv = parsedisk(buf, strlen(buf), part, &tmpdev);
	}

	if (bios_bootmac) {
		struct ifnet *ifp;

		for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
		    ifp = TAILQ_NEXT(ifp, if_list)) {
			if (ifp->if_type == IFT_ETHER &&
			    bcmp(bios_bootmac->mac,
			    ((struct arpcom *)ifp)->ac_enaddr,
			    ETHER_ADDR_LEN) == 0)
				break;
		}
		if (ifp) {
#if defined(NFSCLIENT)
			printf("PXE boot MAC address %s, interface %s\n",
			    ether_sprintf(bios_bootmac->mac), ifp->if_xname);
			bootdv = parsedisk(ifp->if_xname, strlen(ifp->if_xname),
			    0, &tmpdev);
			part = 0;
#endif
		} else
			printf("PXE boot MAC address %s, interface %s\n",
			    ether_sprintf(bios_bootmac->mac), "unknown");
	}

	setroot(bootdv, part, RB_USERREQ);
	dumpconf();

#ifdef HIBERNATE
	hibernate_resume();
#endif /* HIBERNATE */
}
Example #5
0
int
dkopen(struct open_file *f, ...)
{
	struct disklabel *lp;
	struct hppa_dev *dp = f->f_devdata;
	const char *st;

#ifdef	DEBUG
	if (debug)
		printf("dkopen(%p)\n", f);
#endif

	if (!(dp->pz_dev = pdc_findev(-1, PCL_RANDOM)))
		return ENXIO;

	lp = dp->label;
	st = NULL;

#ifdef DEBUG
	if (debug)
		printf ("disklabel\n");
#endif

	if ((st = dk_disklabel(dp, lp)) != NULL) {
#ifdef DEBUG
		if (debug)
			printf ("dkopen: %s\n", st);
#endif
		/* we do not know if it's a disk or net, but do not fail */
	} else {
		u_int i;

		i = B_PARTITION(dp->bootdev);
		if (i >= lp->d_npartitions || !lp->d_partitions[i].p_size)
			return (EPART);

		dp->fsoff = lp->d_partitions[i].p_offset;
	}

#ifdef DEBUGBUG
	if (debug)
		printf ("dkopen() ret\n");
#endif
	return (0);
}
Example #6
0
File: dk.c Project: MarginC/kame
int
dkopen(struct open_file *f, ...)
{
	struct disklabel *lp;
	struct hppa_dev *dp = f->f_devdata;
	const char *st;
	u_int i;

#ifdef	DEBUG
	if (debug)
		printf("dkopen(%p)\n", f);
#endif

	if (!(dp->pz_dev = pdc_findev(-1, PCL_RANDOM)))
		return ENXIO;

	lp = dp->label;
	st = NULL;
#ifdef DEBUG
	if (debug)
		printf ("disklabel\n");
#endif
	if ((st = dk_disklabel(dp, lp)) != NULL) {
#ifdef DEBUG
		if (debug)
			printf ("dkopen: %s\n", st);
#endif
		return ERDLAB;
	} else {
		i = B_PARTITION(dp->bootdev);
#ifdef DEBUG
		if (debug)
			printf("bootdev 0x%x, partition %u\n", dp->bootdev, i);
#endif
		if (i >= lp->d_npartitions || !lp->d_partitions[i].p_size) {
			return (EPART);
		}
	}
#ifdef DEBUGBUG
	if (debug)
		printf ("dkopen() ret\n");
#endif
	return (0);
}
Example #7
0
static void
findbootdev(void)
{
	int type, ctlr, slave, punit, part;
	int scsiboot, hpibboot, netboot;
	struct dev_data *dd;

	booted_device = NULL;
	booted_partition = 0;

	if ((bootdev & B_MAGICMASK) != B_DEVMAGIC)
		return;

	type  = B_TYPE(bootdev);
	ctlr  = B_ADAPTOR(bootdev);
	slave = B_CONTROLLER(bootdev);
	punit = B_UNIT(bootdev);
	part  = B_PARTITION(bootdev);

	scsiboot = (type == 4);			/* sd major */
	hpibboot = (type == 0 || type == 2);	/* ct/rd major */
	netboot  = (type == 6);			/* le - special */

	/*
	 * Check for network boot first, since it's a little
	 * different.  The BOOTROM/boot program can only boot
	 * off of the first (lowest select code) ethernet
	 * device.  device_register() knows this and only
	 * registers one DV_IFNET.  This is a safe assumption
	 * since the code that finds devices on the DIO bus
	 * always starts at scode 0 and works its way up.
	 */
	if (netboot) {
		for (dd = LIST_FIRST(&dev_data_list); dd != NULL;
		    dd = LIST_NEXT(dd, dd_list)) {
			if (device_class(dd->dd_dev) == DV_IFNET) {
				/*
				 * Found it!
				 */
				booted_device = dd->dd_dev;
				break;
			}
		}
		return;
	}

	/*
	 * Check for HP-IB boots next.
	 */
	if (hpibboot) {
		findbootdev_slave(&dev_data_list_hpib, ctlr,
		    slave, punit);
		if (booted_device == NULL)
			return;

		/*
		 * Sanity check.
		 */
		if ((type == 0 && !device_is_a(booted_device, "ct")) ||
		    (type == 2 && !device_is_a(booted_device, "rd"))) {
			printf("WARNING: boot device/type mismatch!\n");
			printf("device = %s, type = %d\n",
			    booted_device->dv_xname, type);
			booted_device = NULL;
		}
		goto out;
	}

	/*
	 * Check for SCSI boots last.
	 */
	if (scsiboot) {
		findbootdev_slave(&dev_data_list_scsi, ctlr,
		     slave, punit);
		if (booted_device == NULL)
			return;

		/*
		 * Sanity check.
		 */
		if ((type == 4 && !device_is_a(booted_device, "sd"))) {
			printf("WARNING: boot device/type mismatch!\n");
			printf("device = %s, type = %d\n",
			    booted_device->dv_xname, type);
			booted_device = NULL;
		}
		goto out;
	}

	/* Oof! */
	printf("WARNING: UNKNOWN BOOT DEVICE TYPE = %d\n", type);

 out:
	if (booted_device != NULL)
		booted_partition = part;
}
Example #8
0
void
cpu_rootconf(void)
{
	struct dev_data *dd;
	struct device *dv;
	struct vfsops *vops;

	/*
	 * Find boot device.
	 */
	if ((bootdev & B_MAGICMASK) != B_DEVMAGIC) {
		printf("WARNING: boot program didn't supply boot device.\n");
		printf("Please update your boot program.\n");
	} else {
		findbootdev();
		if (booted_device == NULL) {
			printf("WARNING: can't find match for bootdev:\n");
			printf(
		    "type = %d, ctlr = %d, slave = %d, punit = %d, part = %d\n",
			    B_TYPE(bootdev), B_ADAPTOR(bootdev),
			    B_CONTROLLER(bootdev), B_UNIT(bootdev),
			    B_PARTITION(bootdev));
			bootdev = 0;		/* invalidate bootdev */
		} else {
			printf("boot device: %s\n", booted_device->dv_xname);
		}
	}

	dv = booted_device;

	/*
	 * If wild carded root device and wired down NFS root file system,
	 * pick the network interface device to use.
	 */
	if (rootspec == NULL) {
		vops = vfs_getopsbyname("nfs");
		if (vops != NULL && vops->vfs_mountroot == mountroot) {
			for (dd = LIST_FIRST(&dev_data_list);
			    dd != NULL; dd = LIST_NEXT(dd, dd_list)) {
				if (device_class(dd->dd_dev) == DV_IFNET) {
					/* Got it! */
					dv = dd->dd_dev;
					break;
				}
			}
			if (dd == NULL) {
				printf("no network interface for NFS root");
				dv = NULL;
			}
		}
	}

	/*
	 * If bootdev is bogus, ask the user anyhow.
	 */
	if (bootdev == 0)
		boothowto |= RB_ASKNAME;

	/*
	 * If we booted from tape, ask the user.
	 */
	if (booted_device != NULL && device_class(booted_device) == DV_TAPE)
		boothowto |= RB_ASKNAME;

	setroot(dv, booted_partition);

	/*
	 * Set bootdev based on what we found as the root.
	 * This is given to the boot program when we reboot.
	 */
	setbootdev();

}
Example #9
0
void
dkcsumattach(void)
{
	struct device *dv;
	struct buf *bp;
	struct bdevsw *bdsw;
	dev_t dev;
	int error;
	u_int32_t csum;
	bios_diskinfo_t *bdi, *hit;

	/* do nothing if no diskinfo passed from /boot, or a bad length */
	if (bios_diskinfo == NULL || bios_cksumlen * DEV_BSIZE > MAXBSIZE)
		return;

	/*
	 * XXX Whatif DEV_BSIZE is changed to something else than the BIOS
	 * blocksize?  Today, /boot doesn't cover that case so neither need
	 * I care here.
	 */
	bp = geteblk(bios_cksumlen * DEV_BSIZE);	/* XXX error check?  */

	for (dv = alldevs.tqh_first; dv; dv = dv->dv_list.tqe_next) {

		if (dv->dv_class != DV_DISK)
			continue;
		bp->b_dev = dev = dev_rawpart(dv);
		if (dev == NODEV)
			continue;
		bdsw = &bdevsw[major(dev)];

		/*
		 * This open operation guarantees a proper initialization
		 * of the device, for future strategy calls.
		 */
		error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc);
		if (error) {
			/* XXX What to do here? */
			if (error != EIO)
				printf("dkcsum: open of %s failed (%d)\n",
				    dv->dv_xname, error);
			continue;
		}

		/* Read blocks to cksum.  XXX maybe a d_read should be used. */
		bp->b_blkno = 0;
		bp->b_bcount = bios_cksumlen * DEV_BSIZE;
		bp->b_flags = B_BUSY | B_READ;
		bp->b_cylin = 0;
		(*bdsw->d_strategy)(bp);
		if (biowait(bp)) {
			/* XXX What to do here? */
			printf("dkcsum: read of %s failed (%d)\n",
			    dv->dv_xname, error);
			error = (*bdsw->d_close)(dev, 0, S_IFCHR, curproc);
			if (error)
				printf("dkcsum: close of %s failed (%d)\n",
				    dv->dv_xname, error);
			continue;
		}
		error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc);
		if (error) {
			/* XXX What to do here? */
			printf("dkcsum: close of %s failed (%d)\n",
			    dv->dv_xname, error);
			continue;
		}

		csum = adler32(0, bp->b_data, bios_cksumlen * DEV_BSIZE);
#ifdef DEBUG
		printf("dkcsum: checksum of %s is %x\n", dv->dv_xname, csum);
#endif

		/* Find the BIOS device */
		hit = 0;
		for (bdi = bios_diskinfo; bdi->bios_number != -1; bdi++) {
			/* Skip non-harddrives */
			if (!(bdi->bios_number & 0x80))
				continue;
#ifdef DEBUG
			printf("dkcsum: "
			    "attempting to match with BIOS drive %x csum %x\n",
			    bdi->bios_number, bdi->checksum);
#endif
			if (bdi->checksum == csum) {
				if (!hit && !(bdi->flags & BDI_PICKED))
					hit = bdi;
				else {
					/* XXX add other heuristics here.  */
					printf("dkcsum: warning: "
					    "dup BSD->BIOS disk mapping\n");
				}
			}
		}

		/*
		 * If we have no hit, that's OK, we can see a lot more devices
		 * than the BIOS can, so this case is pretty normal.
		 */
		if (hit) {
#ifdef DIAGNOSTIC
			printf("dkcsum: %s matched BIOS disk %x\n",
			    dv->dv_xname, hit->bios_number);
#endif
		} else {
#ifdef DIAGNOSTIC
			printf("dkcsum: %s had no matching BIOS disk\n",
			    dv->dv_xname);
#endif
			continue;
		}

		/* Fixup bootdev if units match.  This means that all of
		 * hd*, sd*, wd*, will be interpreted the same.  Not 100%
		 * backwards compatible, but sd* and wd* should be phased-
		 * out in the bootblocks.
		 */
		if (B_UNIT(bootdev) == (hit->bios_number & 0x7F)) {
			int type, ctrl, adap, part, unit;

			/* Translate to MAKEBOOTDEV() style */
			type = major(bp->b_dev);
			adap = B_ADAPTOR(bootdev);
			ctrl = B_CONTROLLER(bootdev);
			unit = DISKUNIT(bp->b_dev);
			part = B_PARTITION(bootdev);

			bootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part);
		}

		/* This will overwrite /boot's guess, just so you remember */
		hit->bsd_dev = MAKEBOOTDEV(major(bp->b_dev), 0, 0,
		    DISKUNIT(bp->b_dev), RAW_PART);
		hit->flags |= BDI_PICKED;
	}
	bp->b_flags |= B_INVAL;
	brelse(bp);
}
Example #10
0
int
devopen(struct open_file *f, const char *fname, char **file)
{
	int error;
	int dev, adapt, ctlr, unit, part;
	struct devsw *dp = &devsw[0];

	dev   = B_TYPE(bootdev);
	adapt = B_ADAPTOR(bootdev);
	ctlr  = B_CONTROLLER(bootdev);
	unit  = B_UNIT(bootdev);
	part  = B_PARTITION(bootdev);

	if ((error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)))
	    return(error);

	/*
	 * Set up filesystem type based on what device we're opening.
	 */
	switch (dev) {
	case 0:		/* ct */
		bcopy(file_system_rawfs, file_system, sizeof(struct fs_ops));
		break;

	case 2:		/* hd */
		bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
		break;

	case 4:		/* sd */
		bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
		bcopy(file_system_cd9660, &file_system[1],
		    sizeof(struct fs_ops));
		nfsys = 2;
		break;

	case 6:		/* le */
		bcopy(file_system_nfs, file_system, sizeof(struct fs_ops));
		break;

	default:
		/* XXX what else should we do here? */
		printf("WARNING: BOGUS BOOT DEV TYPE 0x%x!\n", dev);
		return (EIO);
	}

	dp = &devsw[dev];

	if (!dp->dv_open)
		return(ENODEV);

	f->f_dev = dp;

	if ((error = (*dp->dv_open)(f, adapt, ctlr, part)) == 0) {
		if ((error =
		    (*punitsw[dev].p_punit)(adapt, ctlr, &unit)) != 0) {
			goto bad;
		}
		opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part);
		return(0);
	}

 bad:
	printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name,
	    adapt, ctlr, unit, part, strerror(error));

	return(error);
}
Example #11
0
int
dkopen(struct open_file *f, ...)
{
	struct disklabel dkl;
	struct hppa_dev *dp = f->f_devdata;
	const char *st;
	u_int i;

#ifdef	DEBUG
	if (debug)
		printf("dkopen(%p)\n", f);
#endif

	if (!(dp->pz_dev = pdc_findev(-1, PCL_RANDOM)))
		return ENXIO;

	dp->part_off = 0;
	st = NULL;
#ifdef DEBUG
	if (debug)
		printf ("disklabel\n");
#endif
	if ((st = dk_disklabel(dp, &dkl)) != NULL) {
#ifdef DEBUG
		if (debug)
			printf ("dkopen: %s\n", st);
#endif
	/*
	 * Ignore disklabel errors for this two reasons:
	 * 1. It is possible to dd(1) a LIF image containing the bootloader
	 * and a kernel with attached RAM disk to disk and boot it. That way
	 * the netboot installation LIF image is also usable as disk boot 
	 * image.
	 * 2. Some old 700 machines report a wrong device class in 
	 * PAGE0->mem_boot.pz_class when net booting. (PCL_RANDOM instead 
	 * PCL_NET_MASK|PCL_SEQU) So the bootloader thinks it is booting 
	 * from disk when it is actually net booting. The net boot LIF image 
	 * contains no disklabel so the test for the disklabel will fail. 
	 * If the device open fails if there is no disklabel we are not able
	 * to netboot those machines. 
	 * Therefore the error is ignored. The bootloader will fall back to 
	 * LIF later when there is no disklabel / FFS partition.
	 * At the moment it doesn't matter that the wrong device type ("dk"
	 * instead "lf") is used, as all I/O is abstracted by the firmware.
	 * To get the correct device type it would be necessary to add a 
	 * quirk table to the switch() in dev_hppa.c:devboot().
	 */
	} else {
		i = B_PARTITION(dp->bootdev);
#ifdef DEBUG
		if (debug)
			printf("bootdev 0x%x, partition %u\n", dp->bootdev, i);
#endif
		if (i >= dkl.d_npartitions || !dkl.d_partitions[i].p_size) {
			return (EPART);
		}
		dp->part_off = dkl.d_partitions[i].p_offset * dkl.d_secsize;
	}
#ifdef DEBUGBUG
	if (debug)
		printf ("dkopen() ret\n");
#endif
	return (0);
}
Example #12
0
/*
 * Set the 'current device' by (if possible) recovering the boot device as
 * supplied by the initial bootstrap.
 *
 * XXX should be extended for netbooting.
 */
static void
extract_currdev(void)
{
    struct i386_devdesc	new_currdev;
    int			biosdev = -1;

    /* Assume we are booting from a BIOS disk by default */
    new_currdev.d_dev = &biosdisk;

    /* new-style boot loaders such as pxeldr and cdldr */
    if (kargs->bootinfo == 0) {
        if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
	    /* we are booting from a CD with cdboot */
	    new_currdev.d_dev = &bioscd;
	    new_currdev.d_unit = bc_bios2unit(initial_bootdev);
	} else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
	    /* we are booting from pxeldr */
	    new_currdev.d_dev = &pxedisk;
	    new_currdev.d_unit = 0;
	} else {
	    /* we don't know what our boot device is */
	    new_currdev.d_kind.biosdisk.slice = -1;
	    new_currdev.d_kind.biosdisk.partition = 0;
	    biosdev = -1;
	}
    } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
	/* The passed-in boot device is bad */
	new_currdev.d_kind.biosdisk.slice = -1;
	new_currdev.d_kind.biosdisk.partition = 0;
	biosdev = -1;
    } else {
	new_currdev.d_kind.biosdisk.slice = B_SLICE(initial_bootdev) - 1;
	new_currdev.d_kind.biosdisk.partition = B_PARTITION(initial_bootdev);
	biosdev = initial_bootinfo->bi_bios_dev;

	/*
	 * If we are booted by an old bootstrap, we have to guess at the BIOS
	 * unit number.  We will lose if there is more than one disk type
	 * and we are not booting from the lowest-numbered disk type
	 * (ie. SCSI when IDE also exists).
	 */
	if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2))	/* biosdev doesn't match major */
	    biosdev = 0x80 + B_UNIT(initial_bootdev);		/* assume harddisk */
    }
    new_currdev.d_type = new_currdev.d_dev->dv_type;

    /*
     * If we are booting off of a BIOS disk and we didn't succeed in determining
     * which one we booted off of, just use disk0: as a reasonable default.
     */
    if ((new_currdev.d_type == biosdisk.dv_type) &&
	((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) {
	printf("Can't work out which disk we are booting from.\n"
	       "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
	new_currdev.d_unit = 0;
    }

    env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
	       i386_setcurrdev, env_nounset);
    env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
	       env_nounset);
}