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