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