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 */ }
static void findbootdev(void) { device_t dv; int major, unit, controller; const char *name; booted_device = NULL; booted_partition = 0; /* Assume root is on partition a */ major = B_TYPE(bootdev); name = devsw_blk2name(major); if (name == NULL) return; unit = B_UNIT(bootdev); switch (major) { case 4: /* SCSI drive */ #if NSCSIBUS > 0 bootdev &= ~(B_UNITMASK << B_UNITSHIFT); /* XXX */ unit = target_to_unit(-1, unit, 0); bootdev |= (unit << B_UNITSHIFT); /* XXX */ #else /* NSCSIBUS > 0 */ panic("Boot device is on a SCSI drive but SCSI support " "is not present"); #endif /* NSCSIBUS > 0 */ break; case 22: /* IDE drive */ /* * controller(=channel=buses) uses only IDE drive. * Here, controller always is 0. */ controller = B_CONTROLLER(bootdev); unit = unit + (controller<<1); break; } if ((dv = device_find_by_driver_unit(name, unit)) != NULL) booted_device = dv; }
static void ida_cuckoo_wdc(void) { int cuckoo = IDA_CUCKOO_MODE; int steal = 0; char *mode; int major = B_TYPE(bootdev); if (cuckoo == IDA_CUCKOO_NEVER) { mode = "never"; } else if (cuckoo == IDA_CUCKOO_ROOTWD) { mode = "rootwd"; steal = (major == WD_BDMAJ); } else if (cuckoo == IDA_CUCKOO_ROOTNOTIDA) { mode = "notida"; /* check for magic value of 3 rather than ID_BDMAJ as boot code * pretends we are a wt device (not normally bootable) */ steal = (major != 3); } else { mode = "always"; steal = 1; } printf("ida: wdc vector stealing %s (mode = %s, boot major = %d)\n", (steal ? "on" : "off"), mode, major); if (!steal) return; /* OK - we have a controller, so steal wd driver's vectors */ wdcdriver = nodriver; bdevsw[WD_BDMAJ]->d_open = cdevsw[WD_CDMAJ]->d_open = idopen; bdevsw[WD_BDMAJ]->d_close = cdevsw[WD_CDMAJ]->d_close = idclose; bdevsw[WD_BDMAJ]->d_read = cdevsw[WD_CDMAJ]->d_read = idread; bdevsw[WD_BDMAJ]->d_write = cdevsw[WD_CDMAJ]->d_write = idwrite; bdevsw[WD_BDMAJ]->d_strategy = cdevsw[WD_CDMAJ]->d_strategy = idstrategy; bdevsw[WD_BDMAJ]->d_ioctl = cdevsw[WD_CDMAJ]->d_ioctl = idioctl; bdevsw[WD_BDMAJ]->d_dump = iddump; bdevsw[WD_BDMAJ]->d_psize = idsize; return; }
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(); }
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); }
/* * 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); }