static int ntfs_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; /* XXX */ int error; struct ntfs_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) { vrele(rootvp); return (error); } args.flag = 0; args.uid = 0; args.gid = 0; args.mode = 0777; if ((error = ntfs_mountfs(rootvp, mp, &args, l)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); (void)ntfs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
void live_entry(int index) { // Local variables char local_name[248]; char local_class[64]; char local_capabilities[64]; //Populate the local variables strcpy(local_name, dev_cache[index].name); strcpy(local_class, device_class(dev_cache[index].major_class, dev_cache[index].minor_class)); strcpy(local_capabilities, device_capability(dev_cache[index].flags)); // Let's format these a little nicer if (!strcmp(local_name, "VOID")) strcpy(local_name, "No Response"); if (!strcmp(local_class, "VOID")) strcpy(local_class, "Unclassified"); if (!strcmp(local_capabilities, "VOID")) strcpy(local_capabilities, "Not Reported"); // Write out log fprintf(outfile,"%s,", dev_cache[index].time); fprintf(outfile,"%s,", dev_cache[index].addr); fprintf(outfile,"%s,", local_name); fprintf(outfile,"%s,", local_class); // Last field is variable if (config.getmanufacturer) fprintf(outfile,"%s", mac_get_vendor(dev_cache[index].priv_addr)); else fprintf(outfile,"%s", local_capabilities); fprintf(outfile,"\n"); }
int ext2fs_mountroot(void) { extern struct vnode *rootvp; struct m_ext2fs *fs; struct mount *mp; struct ufsmount *ump; int error; if (device_class(root_device) != DV_DISK) return ENODEV; if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) { vrele(rootvp); return error; } if ((error = ext2fs_mountfs(rootvp, mp)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return error; } mountlist_append(mp); ump = VFSTOUFS(mp); fs = ump->um_e2fs; ext2fs_sb_setmountinfo(fs, mp); (void)ext2fs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); setrootfstime((time_t)fs->e2fs.e2fs_wtime); return 0; }
int cd9660_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; int error; struct iso_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_CD9660, "root_device", &mp)) != 0) { vrele(rootvp); return (error); } args.flags = ISOFSMNT_ROOT; if ((error = iso_mountfs(rootvp, mp, l, &args)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); (void)cd9660_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
input_code input_manager::poll_keyboard_switches() { // iterate over devices within each class input_class &keyboard_class = device_class(DEVICE_CLASS_KEYBOARD); for (int devnum = 0; devnum < keyboard_class.maxindex(); devnum++) { // fetch the device; ignore if nullptr input_device *device = keyboard_class.device(devnum); if (device == nullptr) continue; // iterate over items within each device for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid) { input_device_item *item = device->item(itemid); if (item != nullptr && item->itemclass() == ITEM_CLASS_SWITCH) { input_code code = item->code(); if (code_pressed_once(code)) return code; } } } // if nothing, return an invalid code return INPUT_CODE_INVALID; }
void device_register(device_t dev, void *aux) { if ((booted_device == NULL) && (netboot == 1)) if (device_class(dev) == DV_IFNET) booted_device = dev; }
static int is_valid_disk(device_t dv) { if (device_class(dv) != DV_DISK) return (0); return (device_is_a(dv, "dk") || device_is_a(dv, "sd") || device_is_a(dv, "wd") || device_is_a(dv, "ld") || device_is_a(dv, "ed")); }
/* * Choose root and swap devices. */ void cpu_rootconf(void) { struct prom_n2f *nf; const char *devname; findfunc_t find; char promname[4]; char partname[4]; const char *prompath; int prom_ctlr, prom_unit, prom_part; /* Get the PROM boot path and take it apart. */ prompath = prom_getbootpath(); if (prompath == NULL) prompath = "zz(0,0,0)"; promname[0] = *(prompath++); promname[1] = *(prompath++); promname[2] = '\0'; prom_ctlr = prom_unit = prom_part = 0; if (*prompath == '(' && *(prompath = str2hex(++prompath, &prom_ctlr)) == ',' && *(prompath = str2hex(++prompath, &prom_unit)) == ',') (void)str2hex(++prompath, &prom_part); /* Default to "unknown" */ booted_device = NULL; booted_partition = 0; devname = "<unknown>"; partname[0] = '\0'; find = NULL; /* Do we know anything about the PROM boot device? */ for (nf = prom_dev_table; nf->func; nf++) if (!strcmp(nf->name, promname)) { find = nf->func; break; } if (find) booted_device = (*find)(promname, prom_ctlr, prom_unit); if (booted_device) { devname = device_xname(booted_device); if (device_class(booted_device) == DV_DISK) { booted_partition = prom_part & 7; partname[0] = 'a' + booted_partition; partname[1] = '\0'; } } printf("boot device: %s%s\n", devname, partname); rootconf(); }
void device_register(struct device *dev, void *aux) { if (booted_device != NULL) return; if (netboot == 1) { /* check tlp0 on netboot */ if (device_class(dev) == DV_IFNET && device_is_a(dev, "tlp")) { struct pci_attach_args *pa = aux; if (pa->pa_bus == 0 && pa->pa_device == 7 && pa->pa_function == 0) booted_device = dev; } } else { /* check wd channel and drive */ if (device_class(dev) == DV_DISK && device_is_a(dev, "wd")) { struct ata_device *adev = aux; int unit; unit = adev->adev_channel * 2 + adev->adev_drv_data->drive; if (unit == bootunit) { booted_device = dev; } } /* * XXX Match up MBR boot specification with BSD disklabel * for root? */ booted_partition = 0; } }
device_t device_isa_register(device_t dev, void *aux) { /* * Handle network interfaces here, the attachment information is * not available driver-independently later. * * For disks, there is nothing useful available at attach time. */ if (device_class(dev) == DV_IFNET) { struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF); if (bin == NULL) return NULL; /* * We don't check the driver name against the device name * passed by the boot ROM. The ROM should stay usable if * the driver becomes obsolete. The physical attachment * information (checked below) must be sufficient to * identify the device. */ if (bin->bus == BI_BUS_ISA && device_is_a(device_parent(dev), "isa")) { struct isa_attach_args *iaa = aux; /* Compare IO base address */ /* XXXJRT What about multiple IO addrs? */ if (iaa->ia_nio > 0 && bin->addr.iobase == iaa->ia_io[0].ir_addr) return dev; } } #if NACPICA > 0 #if notyet if (device_is_a(dev, "isa") && acpi_active) { if (!(AcpiGbl_FADT.BootFlags & ACPI_FADT_LEGACY_DEVICES)) prop_dictionary_set_bool(device_properties(dev), "no-legacy-devices", true); } #endif #endif /* NACPICA > 0 */ return NULL; }
int msdosfs_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; /* XXX */ int error; struct msdosfs_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_MSDOS, "root_device", &mp))) { vrele(rootvp); return (error); } args.flags = MSDOSFSMNT_VERSIONED; args.uid = 0; args.gid = 0; args.mask = 0777; args.version = MSDOSFSMNT_VERSION; args.dirmask = 0777; if ((error = msdosfs_mountfs(rootvp, mp, l, &args)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } if ((error = update_mp(mp, &args)) != 0) { (void)msdosfs_unmount(mp, 0); vfs_unbusy(mp, false, NULL); vfs_destroy(mp); vrele(rootvp); return (error); } mountlist_append(mp); (void)msdosfs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
int ext2fs_mountroot(void) { // printf("ext2fs_mountroot\n"); extern struct vnode *rootvp; struct m_ext2fs *fs; struct mount *mp; struct ufsmount *ump; int error; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) { vrele(rootvp); return (error); } if ((error = ext2fs_mountfs(rootvp, mp)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); ump = VFSTOUFS(mp); fs = ump->um_e2fs; memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); (void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1, 0); if (fs->e2fs.e2fs_rev > E2FS_REV0) { memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); (void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt, sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0); } (void)ext2fs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); setrootfstime((time_t)fs->e2fs.e2fs_wtime); return (0); }
int #define struct ext2fs_mountroot(struct mount *mp) { struct vnode *rootvp; #undef struct struct m_ext2fs *fs; // struct mount *mp; int error; DEBUG ((EFI_D_INFO, "mountroot 1\n")); if (device_class(root_device) != DV_DISK) return (ENONDEV); DEBUG ((EFI_D_INFO, "mountroot 2\n")); if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) { vrele(rootvp); return (error); } DEBUG ((EFI_D_INFO, "mountroot 3\n")); if ((error = ext2fs_mountfs(rootvp, mp)) != 0) { vfs_unbusy(mp,false,NULL); vfs_destroy(mp); return (error); } DEBUG ((EFI_D_INFO, "mountroot 4\n")); fs = mp->fs; memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); (void) copystr(mp->f_mntonname, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1, 0); if (fs->e2fs.e2fs_rev > E2FS_REV0) { memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); (void) copystr(mp->f_mntonname, fs->e2fs.e2fs_fsmnt, sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0); } vfs_unbusy(mp, false, NULL); return (0);
static void findroot(void) { device_t dv; deviter_t di; if (booted_device) return; if ((booted_device == NULL) && netboot == 0) { for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (device_class(dv) == DV_DISK && device_is_a(dv, "wd")) booted_device = dv; } deviter_release(&di); } /* * XXX Match up MBR boot specification with BSD disklabel for root? */ booted_partition = 0; }
static void setbootdev(void) { struct dev_data *cdd, *dd; int type, ctlr; /* * Note our magic numbers for type: * * 0 == ct * 2 == rd * 4 == sd * 6 == le * * Allare bdevsw major numbers, except for le, which * is just special. * * We can't mount root on a tape, so we ignore those. */ /* * Start with a clean slate. */ bootdev = 0; /* * If the root device is network, we're done * early. */ if (device_class(root_device) == DV_IFNET) { bootdev = MAKEBOOTDEV(6, 0, 0, 0, 0); goto out; } /* * Determine device type. */ if (device_is_a(root_device, "rd")) type = 2; else if (device_is_a(root_device, "sd")) type = 4; else if (device_is_a(root_device, "md")) goto out; else { printf("WARNING: strange root device!\n"); goto out; } dd = dev_data_lookup(root_device); /* * Get parent's info. */ switch (type) { case 2: /* rd */ case 4: /* sd */ /* * "rd" -> "hpibbus" -> "fhpib" * "sd" -> "scsibus" -> "spc" */ for (cdd = LIST_FIRST(&dev_data_list_hpib), ctlr = 0; cdd != NULL; cdd = LIST_NEXT(cdd, dd_clist), ctlr++) { if (cdd->dd_dev == device_parent(device_parent(root_device))) { /* * Found it! */ bootdev = MAKEBOOTDEV(type, ctlr, dd->dd_slave, dd->dd_punit, DISKPART(rootdev)); break; } } break; } out: /* Don't need this anymore. */ for (dd = LIST_FIRST(&dev_data_list); dd != NULL; ) { cdd = dd; dd = LIST_NEXT(dd, dd_list); free(cdd, M_DEVBUF); } }
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; }
/* * Register a device. We're passed the device and the arguments * used to attach it. This is used to find the boot device. */ void device_register(struct device *dev, void *aux) { struct dev_data *dd; static int seen_netdevice = 0; /* * Allocate a dev_data structure and fill it in. * This means making some tests twice, but we don't * care; this doesn't really have to be fast. * * Note that we only really care about devices that * we can mount as root. */ dd = malloc(sizeof(struct dev_data), M_DEVBUF, M_NOWAIT | M_ZERO); if (dd == NULL) panic("device_register: can't allocate dev_data"); dd->dd_dev = dev; /* * BOOTROM and boot program can really only understand * using the lowest select code network interface, * so we ignore all but the first. */ if (device_class(dev) == DV_IFNET && seen_netdevice == 0) { struct dio_attach_args *da = aux; seen_netdevice = 1; dd->dd_scode = da->da_scode; goto linkup; } if (device_is_a(dev, "fhpib") || device_is_a(dev, "nhpib") || device_is_a(dev, "spc")) { struct dio_attach_args *da = aux; dd->dd_scode = da->da_scode; goto linkup; } if (device_is_a(dev, "rd")) { struct hpibbus_attach_args *ha = aux; dd->dd_slave = ha->ha_slave; dd->dd_punit = ha->ha_punit; goto linkup; } if (device_is_a(dev, "sd")) { struct scsipibus_attach_args *sa = aux; dd->dd_slave = sa->sa_periph->periph_target; dd->dd_punit = sa->sa_periph->periph_lun; goto linkup; } /* * Didn't need the dev_data. */ free(dd, M_DEVBUF); return; linkup: LIST_INSERT_HEAD(&dev_data_list, dd, dd_list); if (device_is_a(dev, "fhpib") || device_is_a(dev, "nhpib")) { dev_data_insert(dd, &dev_data_list_hpib); return; } if (device_is_a(dev, "spc")) { dev_data_insert(dd, &dev_data_list_scsi); return; } }
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 device_register(device_t dev, void *aux) { #if NPCI > 0 static bool found_console = false; struct pci_attach_args *paa = aux; #endif /* * Handle network interfaces here, the attachment information is * not available driver-independently later. * * For disks, there is nothing useful available at attach time. */ if (device_class(dev) == DV_IFNET) { struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF); if (bin == NULL) return; /* * We don't check the driver name against the device name * passed by the boot ROM. The ROM should stay usable if * the driver becomes obsolete. The physical attachment * information (checked below) must be sufficient to * idenfity the device. */ if (bin->bus == BI_BUS_ISA && device_is_a(device_parent(dev), "isa")) { struct isa_attach_args *iaa = aux; /* Compare IO base address */ /* XXXJRT What about multiple IO addrs? */ if (iaa->ia_nio > 0 && bin->addr.iobase == iaa->ia_io[0].ir_addr) goto found; } #if NPCI > 0 if (bin->bus == BI_BUS_PCI && device_is_a(device_parent(dev), "pci")) { int b, d, f; /* * Calculate BIOS representation of: * * <bus,device,function> * * and compare. */ pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f); if (bin->addr.tag == ((b << 8) | (d << 3) | f)) goto found; } #endif /* NPCI > 0 */ } #if NISA > 0 && NACPICA > 0 #if notyet if (device_is_a(dev, "isa") && acpi_active) { if (!(AcpiGbl_FADT.BootFlags & ACPI_FADT_LEGACY_DEVICES)) prop_dictionary_set_bool(device_properties(dev), "no-legacy-devices", true); } #endif #endif /* NISA > 0 && NACPICA > 0 */ #if NPCI > 0 if (device_parent(dev) && device_is_a(device_parent(dev), "pci") && found_console == false) { struct btinfo_framebuffer *fbinfo; struct pci_attach_args *pa = aux; prop_dictionary_t dict; #if NACPICA > 0 struct genfb_parameter_callback *gpc; int b, d, f; #endif if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY) { #if NWSDISPLAY > 0 && NGENFB > 0 extern struct vcons_screen x86_genfb_console_screen; struct rasops_info *ri; ri = &x86_genfb_console_screen.scr_ri; #endif fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER); dict = device_properties(dev); /* * framebuffer drivers other than genfb can work * without the address property */ if (fbinfo != NULL) { if (fbinfo->physaddr != 0) { prop_dictionary_set_uint32(dict, "width", fbinfo->width); prop_dictionary_set_uint32(dict, "height", fbinfo->height); prop_dictionary_set_uint8(dict, "depth", fbinfo->depth); prop_dictionary_set_uint16(dict, "linebytes", fbinfo->stride); prop_dictionary_set_uint64(dict, "address", fbinfo->physaddr); #if NWSDISPLAY > 0 && NGENFB > 0 if (ri->ri_bits != NULL) { prop_dictionary_set_uint64(dict, "virtual_address", (vaddr_t)ri->ri_bits); } #endif } #if notyet prop_dictionary_set_bool(dict, "splash", fbinfo->flags & BI_FB_SPLASH ? true : false); #endif if (fbinfo->depth == 8) { gfb_cb.gcc_cookie = NULL; gfb_cb.gcc_set_mapreg = x86_genfb_set_mapreg; prop_dictionary_set_uint64(dict, "cmap_callback", (uint64_t)(uintptr_t)&gfb_cb); } if (fbinfo->physaddr != 0) { mode_cb.gmc_setmode = x86_genfb_setmode; prop_dictionary_set_uint64(dict, "mode_callback", (uint64_t)(uintptr_t)&mode_cb); } #if NWSDISPLAY > 0 && NGENFB > 0 if (device_is_a(dev, "genfb")) { x86_genfb_set_console_dev(dev); #ifdef DDB db_trap_callback = x86_genfb_ddb_trap_callback; #endif } #endif } prop_dictionary_set_bool(dict, "is_console", true); prop_dictionary_set_bool(dict, "clear-screen", false); #if NWSDISPLAY > 0 && NGENFB > 0 prop_dictionary_set_uint16(dict, "cursor-row", x86_genfb_console_screen.scr_ri.ri_crow); #endif #if notyet prop_dictionary_set_bool(dict, "splash", fbinfo->flags & BI_FB_SPLASH ? true : false); #endif pmf_cb.gpc_suspend = x86_genfb_suspend; pmf_cb.gpc_resume = x86_genfb_resume; prop_dictionary_set_uint64(dict, "pmf_callback", (uint64_t)(uintptr_t)&pmf_cb); #if NACPICA > 0 pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f); gpc = acpidisp_md_out_find(b, d, f); if (gpc != NULL) prop_dictionary_set_uint64(dict, "brightness_callback", (uint64_t)(vaddr_t)gpc); #endif #ifdef VGA_POST vga_posth = vga_post_init(pa->pa_bus, pa->pa_device, pa->pa_function); #endif found_console = true; return; } } #endif return; found: if (booted_device) { /* XXX should be a panic() */ printf("WARNING: double match for boot device (%s, %s)\n", device_xname(booted_device), device_xname(dev)); return; } booted_device = dev; }
/* * 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. */ static void findroot(void) { struct btinfo_rootdevice *biv; struct btinfo_bootdisk *bid; struct btinfo_bootwedge *biw; struct btinfo_biosgeom *big; device_t dv; deviter_t di; if (booted_device) return; if (lookup_bootinfo(BTINFO_NETIF) != NULL) { /* * We got netboot interface information, but device_register() * failed to match it to a configured device. Boot disk * information cannot be present at the same time, so give * up. */ printf("%s: netboot interface not found.\n", __func__); return; } if ((biv = lookup_bootinfo(BTINFO_ROOTDEVICE)) != NULL) { for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { cfdata_t cd; size_t len; if (device_class(dv) != DV_DISK) continue; cd = device_cfdata(dv); len = strlen(cd->cf_name); if (strncmp(cd->cf_name, biv->devname, len) == 0 && biv->devname[len] - '0' == device_unit(dv)) { booted_device = dv; booted_partition = biv->devname[len + 1] - 'a'; booted_nblks = 0; break; } } DPRINTF(("%s: BTINFO_ROOTDEVICE %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); deviter_release(&di); if (dv != NULL) return; } bid = lookup_bootinfo(BTINFO_BOOTDISK); biw = lookup_bootinfo(BTINFO_BOOTWEDGE); if (biw != NULL) { /* * Scan all disk devices for ones that match the passed data. * Don't break if one is found, to get possible multiple * matches - for problem tracking. Use the first match anyway * because lower devices numbers are more likely to be the * boot device. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (is_valid_disk(dv)) { /* * Don't trust BIOS device numbers, try * to match the information passed by the * boot loader instead. */ if ((biw->biosdev & 0x80) == 0 || match_bootwedge(dv, biw) == 0) continue; goto bootwedge_found; } continue; bootwedge_found: if (booted_device) { dmatch(__func__, dv); continue; } booted_device = dv; booted_partition = bid != NULL ? bid->partition : 0; booted_nblks = biw->nblks; booted_startblk = biw->startblk; } deviter_release(&di); DPRINTF(("%s: BTINFO_BOOTWEDGE %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); if (booted_nblks) return; } if (bid != NULL) { /* * Scan all disk devices for ones that match the passed data. * Don't break if one is found, to get possible multiple * matches - for problem tracking. Use the first match anyway * because lower device numbers are more likely to be the * boot device. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (device_is_a(dv, "fd") && device_class(dv) == DV_DISK) { /* * Assume the configured unit number matches * the BIOS device number. (This is the old * behavior.) Needs some ideas how to handle * the BIOS's "swap floppy drive" options. */ /* XXX device_unit() abuse */ if ((bid->biosdev & 0x80) != 0 || device_unit(dv) != bid->biosdev) continue; goto bootdisk_found; } if (is_valid_disk(dv)) { /* * Don't trust BIOS device numbers, try * to match the information passed by the * boot loader instead. */ if ((bid->biosdev & 0x80) == 0 || match_bootdisk(dv, bid) == 0) continue; goto bootdisk_found; } continue; bootdisk_found: if (booted_device) { dmatch(__func__, dv); continue; } booted_device = dv; booted_partition = bid->partition; booted_nblks = 0; } deviter_release(&di); DPRINTF(("%s: BTINFO_BOOTDISK %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); if (booted_device) return; /* * No booted device found; check CD-ROM boot at last. * * Our bootloader assumes CD-ROM boot if biosdev is larger * or equal than the number of hard drives recognized by the * BIOS. The number of drives can be found in BTINFO_BIOSGEOM * here. For example, if we have wd0, wd1, and cd0: * * big->num = 2 (for wd0 and wd1) * bid->biosdev = 0x80 (wd0) * bid->biosdev = 0x81 (wd1) * bid->biosdev = 0x82 (cd0) * * See src/sys/arch/i386/stand/boot/devopen.c and * src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c . */ if ((big = lookup_bootinfo(BTINFO_BIOSGEOM)) != NULL && bid->biosdev >= 0x80 + big->num) { /* * XXX * There is no proper way to detect which unit is * recognized as a bootable CD-ROM drive by the BIOS. * Assume the first unit is the one. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (device_class(dv) == DV_DISK && device_is_a(dv, "cd")) { booted_device = dv; booted_partition = 0; booted_nblks = 0; break; } } deviter_release(&di); DPRINTF(("%s: BTINFO_BIOSGEOM %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); } } }
int main(int argc, char *argv[]) { // Handle signals signal(SIGINT,shut_down); signal(SIGHUP,shut_down); signal(SIGTERM,shut_down); signal(SIGQUIT,shut_down); // HCI device number, MAC struct int device = 0; bdaddr_t bdaddr; bacpy(&bdaddr, BDADDR_ANY); // Time to scan. Scan time is roughly 1.28 seconds * scan_window // Originally this was always 8, now we adjust based on device: #ifdef OPENWRT int scan_window = 8; #elif PWNPLUG int scan_window = 5; #else int scan_window = 3; #endif // Maximum number of devices per scan int max_results = 255; int num_results; // Device cache and index int cache_index = 0; // HCI cache setting int flags = IREQ_CACHE_FLUSH; // Strings to hold MAC and name char addr[19] = {0}; char addr_buff[19] = {0}; // String for time char cur_time[20]; // Process ID read from PID file int ext_pid; // Pointers to filenames char *infofilename = LIVE_INF; // Change default filename based on date char OUT_FILE[1000] = OUT_PATH; strncat(OUT_FILE, file_timestamp(),sizeof(OUT_FILE)-strlen(OUT_FILE)-1); char *outfilename = OUT_FILE; // Mode to open output file in char *filemode = "a+"; // Output buffer char outbuffer[500]; // Buffer for data from the second loop char exitbuffer[500]; // Misc Variables int i, ri, opt; // Record numbner of BlueZ errors int error_count = 0; // Current epoch time long long int epoch; // Kernel version info struct utsname sysinfo; uname(&sysinfo); while ((opt=getopt_long(argc,argv,"+o:i:r:a:w:vxctghldbfenksmq", main_options, NULL)) != EOF) { switch (opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) hci_devba(atoi(optarg + 3), &bdaddr); else str2ba(optarg, &bdaddr); break; case 'o': outfilename = strdup(optarg); break; case 'r': config.retry_count = atoi(optarg); break; case 'a': config.amnesia = atoi(optarg); break; case 'w': config.scan_window = round((atoi(optarg) / 1.28)); break; case 'c': config.showclass = 1; break; case 'e': config.encode = 1; break; case 'f': config.friendlyclass = 1; break; case 'v': config.verbose = 1; break; case 'g': config.status = 1; break; case 't': config.showtime = 1; break; case 's': config.syslogonly = 1; break; case 'x': config.obfuscate = 1; break; case 'q': config.quiet = 1; break; case 'l': if(!LIVEMODE) { printf("Live mode has been disabled in this build. See documentation.\n"); exit(0); } else config.bluelive = 1; break; case 'b': config.bluepropro = 1; break; case 'd': config.daemon = 1; break; case 'n': config.getname = 1; break; case 'm': if(!OUILOOKUP) { printf("Manufacturer lookups have been disabled in this build. See documentation.\n"); exit(0); } else config.getmanufacturer = 1; break; case 'h': help(); exit(0); case 'k': // Read PID from file into variable ext_pid = read_pid(); if (ext_pid != 0) { printf("Killing Bluelog process with PID %i...",ext_pid); if(kill(ext_pid,15) != 0) { printf("ERROR!\n"); printf("Unable to kill Bluelog process. Check permissions.\n"); exit(1); } else printf("OK.\n"); // Delete PID file unlink(PID_FILE); } else printf("No running Bluelog process found.\n"); exit(0); default: printf("Unknown option. Use -h for help, or see README.\n"); exit(1); } } // See if there is already a process running if (read_pid() != 0) { printf("Another instance of Bluelog is already running!\n"); printf("Use the -k option to kill a running Bluelog process.\n"); exit(1); } // Load config from file if no options given on command line if(cfg_exists() && argc == 1) { if (cfg_read() != 0) { printf("Error opening config file!\n"); exit(1); } // Put interface into BT struct hci_devba(config.hci_device, &bdaddr); } // Perform sanity checks on varibles cfg_check(); // Setup libmackerel mac_init(); // Boilerplate if (!config.quiet) { printf("%s (v%s%s) by MS3FGX\n", APPNAME, VERSION, VER_MOD); #if defined OPENWRT || PWNPLUG printf("----"); #endif printf("---------------------------\n"); } // Show notification we loaded config from file if(cfg_exists() && argc == 1 && !config.quiet) printf("Config loaded from: %s\n", CFG_FILE); // Init Hardware ba2str(&bdaddr, config.addr); if (!strcmp(config.addr, "00:00:00:00:00:00")) { if (!config.quiet) printf("Autodetecting device..."); device = hci_get_route(NULL); // Put autodetected device MAC into addr hci_devba(device, &bdaddr); ba2str(&bdaddr, config.addr); } else { if (!config.quiet) printf("Initializing device..."); device = hci_devid(config.addr); } // Open device and catch errors config.bt_socket = hci_open_dev(device); if (device < 0 || config.bt_socket < 0) { // Failed to open device, that can't be good printf("\n"); printf("Error initializing Bluetooth device!\n"); exit(1); } // If we get here the device should be online. if (!config.quiet) printf("OK\n"); // Status message for BPP if (!config.quiet) if (config.bluepropro) printf("Output formatted for BlueProPro.\n" "More Info: www.hackfromacave.com\n"); // Open socket if (config.udponly) open_udp_socket(); // Open output file, unless in networking mode if (!config.syslogonly && !config.udponly) { if (config.bluelive) { // Change location of output file outfilename = LIVE_OUT; filemode = "w"; if (!config.quiet) printf("Starting Bluelog Live...\n"); } if (!config.quiet) printf("Opening output file: %s...", outfilename); if ((outfile = fopen(outfilename, filemode)) == NULL) { printf("\n"); printf("Error opening output file!\n"); exit(1); } if (!config.quiet) printf("OK\n"); } else if (!config.quiet) printf("Network mode enabled, not creating log file.\n"); // Open status file if (config.bluelive) { if (!config.quiet) printf("Opening info file: %s...", infofilename); if ((infofile = fopen(infofilename,"w")) == NULL) { printf("\n"); printf("Error opening info file!\n"); exit(1); } if (!config.quiet) printf("OK\n"); } // Write PID file if (!config.daemon) write_pid(getpid()); // Get and print time to console and file strcpy(cur_time, get_localtime()); if (!config.daemon) printf("Scan started at [%s] on %s\n", cur_time, config.addr); if (config.showtime && (outfile != NULL)) { fprintf(outfile,"[%s] Scan started on %s\n", cur_time, config.addr); // Make sure this gets written out fflush(outfile); } // Write info file for Bluelog Live if (config.bluelive) { fprintf(infofile,"<div class=\"sideitem\">%s Version: %s%s</div>\n", APPNAME, VERSION, VER_MOD); fprintf(infofile,"<div class=\"sideitem\">Device: %s</div>\n", config.addr); fprintf(infofile,"<div class=\"sideitem\">Started: %s</div>\n", cur_time); // Think we are done with you now fclose(infofile); } // Log success to this point syslog(LOG_INFO,"Init OK!"); // Daemon switch if (config.daemon) daemonize(); else if (!config.quiet) #if defined PWNPAD printf("Close this window to end scan.\n"); #else printf("Hit Ctrl+C to end scan.\n"); #endif // Init result struct results = (inquiry_info*)malloc(max_results * sizeof(inquiry_info)); // Start scan, be careful with this infinite loop... for(;;) { // Flush results buffer memset(results, '\0', max_results * sizeof(inquiry_info)); // Scan and return number of results num_results = hci_inquiry(device, scan_window, max_results, NULL, &results, flags); // A negative number here means an error during scan if(num_results < 0) { // Increment error count error_count++; // Ignore occasional errors on Pwn Plug and OpenWRT #if !defined PWNPLUG || OPENWRT // All other platforms, print error and bail out syslog(LOG_ERR,"Received error from BlueZ!"); printf("Scan failed!\n"); // Check for kernel 3.0.x if (!strncmp("3.0.",sysinfo.release,4)) { printf("\n"); printf("-----------------------------------------------------\n"); printf("Device scanning failed, and you are running a 3.0.x\n"); printf("Linux kernel. This failure is probably due to the\n"); printf("following kernel bug:\n"); printf("\n"); printf("http://marc.info/?l=linux-kernel&m=131629118406044\n"); printf("\n"); printf("You will need to upgrade your kernel to at least the\n"); printf("the 3.1 series to continue.\n"); printf("-----------------------------------------------------\n"); } shut_down(1); #else // Exit on back to back errors if (error_count > 5) { printf("Scan failed!\n"); syslog(LOG_ERR,"BlueZ not responding, unrecoverable!"); shut_down(1); } // Otherwise, throttle back a bit, might help sleep(1); #endif } else { // Clear error counter error_count = 0; } // Check if we need to reset device cache if ((cache_index + num_results) >= MAX_DEV) { syslog(LOG_INFO,"Resetting device cache..."); memset(dev_cache, 0, sizeof(dev_cache)); cache_index = 0; } // Loop through results for (i = 0; i < num_results; i++) { // Return current MAC from struct ba2str(&(results+i)->bdaddr, addr); // Compare to device cache for (ri = 0; ri <= cache_index; ri++) { // Determine if device is already logged if (strcmp (addr, dev_cache[ri].priv_addr) == 0) { // This device has been seen before // Increment seen count, update printed time dev_cache[ri].seen++; strcpy(dev_cache[ri].time, get_localtime()); dev_cache[ri].missing_count = 0; // If we don't have a name, query again if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen > config.retry_count)) { syslog(LOG_INFO,"Unable to find name for %s!", addr); dev_cache[ri].print = 1; } else if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen < config.retry_count)) { // Query name strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr)); // Did we get one? if (strcmp (dev_cache[ri].name, "VOID") != 0) { syslog(LOG_INFO,"Name retry for %s successful!", addr); // Force print dev_cache[ri].print = 1; } else syslog(LOG_INFO,"Name retry %i for %s failed!",dev_cache[ri].seen, addr); } // Amnesia mode if (config.amnesia >= 0) { // Find current epoch time epoch = time(NULL); if ((epoch - dev_cache[ri].epoch) >= (config.amnesia * 60)) { // Update epoch time dev_cache[ri].epoch = epoch; // Set device to print dev_cache[ri].print = 1; } } // This device is seen before, but has been away if (strcmp (dev_cache[ri].status, "gone") == 0) { dev_cache[ri].print = 1; strcpy(dev_cache[ri].status, "returned"); } // Unless we need to get printed, move to next result if (dev_cache[ri].print != 1) break; } else if (strcmp (dev_cache[ri].addr, "") == 0) { // Write new device MAC (visible and internal use) strcpy(dev_cache[ri].addr, addr); strcpy(dev_cache[ri].priv_addr, addr); // Query for name if (config.getname) strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr)); else strcpy(dev_cache[ri].name, "IGNORED"); // Get time found strcpy(dev_cache[ri].time, get_localtime()); dev_cache[ri].epoch = time(NULL); // Class info dev_cache[ri].flags = (results+i)->dev_class[2]; dev_cache[ri].major_class = (results+i)->dev_class[1]; dev_cache[ri].minor_class = (results+i)->dev_class[0]; // Init misc variables dev_cache[ri].seen = 1; dev_cache[ri].missing_count = 0; strcpy(dev_cache[ri].status, "new"); // Increment index cache_index++; // If we have a device name, get printed if (strcmp (dev_cache[ri].name, "VOID") != 0) dev_cache[ri].print = 1; else { // Found with no name. // Print message to syslog, prevent printing, and move on syslog(LOG_INFO,"Device %s discovered with no name, will retry", dev_cache[ri].addr); dev_cache[ri].print = 3; break; } } // Ready to print? if (dev_cache[ri].print == 1) { // Encode MAC if (config.encode || config.obfuscate) { // Clear buffer memset(addr_buff, '\0', sizeof(addr_buff)); if (config.obfuscate) strcpy(addr_buff, mac_obfuscate(dev_cache[ri].priv_addr)); if (config.encode) strcpy(addr_buff, mac_encode(dev_cache[ri].priv_addr)); // Copy to cache strcpy(dev_cache[ri].addr, addr_buff); } // Print everything to console if verbose is on, optionally friendly class info if (config.verbose) { if (config.friendlyclass) { printf("[%s] %s,%s,%s,(%s) - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, device_class(dev_cache[ri].major_class,\ dev_cache[ri].minor_class), device_capability(dev_cache[ri].flags), dev_cache[ri].status); } else { printf("[%s] %s,%s,0x%02x%02x%02x - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class, dev_cache[ri].status); } } if (config.bluelive) { // Write result with live function live_entry(ri); } else if (config.bluepropro) { // Set output format for BlueProPro fprintf(outfile,"%s", dev_cache[ri].addr); fprintf(outfile,",0x%02x%02x%02x", dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class); fprintf(outfile,",%s\n", dev_cache[ri].name); } else { // Flush buffer memset(outbuffer, 0, sizeof(outbuffer)); // Print time first if enabled if (config.showtime) sprintf(outbuffer,"[%s],", dev_cache[ri].time); // Always output MAC sprintf(outbuffer+strlen(outbuffer),"%s", dev_cache[ri].addr); // Optionally output class if (config.showclass) sprintf(outbuffer+strlen(outbuffer),",0x%02x%02x%02x", dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class); // "Friendly" version of class info if (config.friendlyclass) sprintf(outbuffer+strlen(outbuffer),",%s,(%s)",\ device_class(dev_cache[ri].major_class, dev_cache[ri].minor_class),\ device_capability(dev_cache[ri].flags)); // Get manufacturer if (config.getmanufacturer) sprintf(outbuffer+strlen(outbuffer),",%s", mac_get_vendor(dev_cache[ri].priv_addr)); // Append the name if (config.getname) sprintf(outbuffer+strlen(outbuffer),",%s", dev_cache[ri].name); // Append the status if (config.status) sprintf(outbuffer+strlen(outbuffer)," - %s", dev_cache[ri].status); // Send buffer, else file. File needs newline if (config.syslogonly) syslog(LOG_INFO,"%s", outbuffer); else if (config.udponly) { // Append newline to socket, kind of hacky sprintf(outbuffer+strlen(outbuffer),"\n"); send_udp_msg(outbuffer); } else fprintf(outfile,"%s\n",outbuffer); } dev_cache[ri].print = 0; break; } // If we make it this far, it means we will check next stored device } // If there's a file open, write changes if (outfile != NULL) fflush(outfile); } // Now check if any devices are missing // Loop through the cache for (ri = 0; ri < cache_index; ri++) { for (i = 0; i <= num_results; i++) { // Return current MAC from struct ba2str(&(results+i)->bdaddr, addr); // Determine if device still present if (strcmp (addr, dev_cache[ri].priv_addr) == 0) { break; } // Device not found. if (i == num_results) { // The device is missing but not marked as gone -> it has just disappeared if (strcmp(dev_cache[ri].status, "gone") != 0) { // Devices aren't present every time. Wait a while before marking it gone if (dev_cache[ri].missing_count < 10) { dev_cache[ri].missing_count++; } else // It's really gone :( { strcpy(dev_cache[ri].status,"gone"); // Print to console if (config.verbose) { printf("[%s] %s,%s - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, dev_cache[ri].status); } // Flush buffer memset(exitbuffer, 0, sizeof(exitbuffer)); // Print time first if enabled if (config.showtime) sprintf(exitbuffer,"[%s],", dev_cache[ri].time); // Always output MAC sprintf(exitbuffer+strlen(exitbuffer),"%s", dev_cache[ri].addr); // Append the name if (config.getname) sprintf(exitbuffer+strlen(exitbuffer),",%s", dev_cache[ri].name); // Append the status if (config.status) sprintf(exitbuffer+strlen(exitbuffer)," - %s", dev_cache[ri].status); // Send buffer, else file. File needs newline if (config.syslogonly) syslog(LOG_INFO,"%s", exitbuffer); else if (config.udponly) { // Append newline to socket, kind of hacky sprintf(exitbuffer+strlen(exitbuffer),"\n"); send_udp_msg(exitbuffer); } else fprintf(outfile,"%s\n",exitbuffer); // If there's a file open, write changes if (outfile != NULL) fflush(outfile); } } } } } } // If we get here, shut down shut_down(0); // STFU return (1); }
/* * XXX Ugly bit of code. But, this is the only safe time that the * match between BIOS disks and native disks can be done. */ static void matchbiosdisks(void) { struct btinfo_biosgeom *big; struct bi_biosgeom_entry *be; device_t dv; deviter_t di; int i, ck, error, m, n; struct vnode *tv; char mbr[DEV_BSIZE]; int dklist_size; int numbig; big = lookup_bootinfo(BTINFO_BIOSGEOM); numbig = big ? big->num : 0; /* First, count all native disks. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (is_valid_disk(dv)) x86_ndisks++; } deviter_release(&di); dklist_size = sizeof(struct disklist) + (x86_ndisks - 1) * sizeof(struct nativedisk_info); /* XXX M_TEMP is wrong */ x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO); if (x86_alldisks == NULL) return; x86_alldisks->dl_nnativedisks = x86_ndisks; x86_alldisks->dl_nbiosdisks = numbig; for (i = 0; i < numbig; i++) { x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev; x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec; x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head; x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl; x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec; x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags; #ifdef GEOM_DEBUG #ifdef notyet printf("disk %x: flags %x, interface %x, device %llx\n", big->disk[i].dev, big->disk[i].flags, big->disk[i].interface_path, big->disk[i].device_path); #endif #endif } /* XXX Code duplication from findroot(). */ n = -1; for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (device_class(dv) != DV_DISK) continue; #ifdef GEOM_DEBUG printf("matchbiosdisks: trying to match (%s) %s\n", device_xname(dv), device_cfdata(dv)->cf_name); #endif if (is_valid_disk(dv)) { n++; snprintf(x86_alldisks->dl_nativedisks[n].ni_devname, sizeof(x86_alldisks->dl_nativedisks[n].ni_devname), "%s", device_xname(dv)); if ((tv = opendisk(dv)) == NULL) continue; error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0, UIO_SYSSPACE, 0, NOCRED, NULL, NULL); VOP_CLOSE(tv, FREAD, NOCRED); vput(tv); if (error) { #ifdef GEOM_DEBUG printf("matchbiosdisks: %s: MBR read failure\n", device_xname(dv)); #endif continue; } for (ck = i = 0; i < DEV_BSIZE; i++) ck += mbr[i]; for (m = i = 0; i < numbig; i++) { be = &big->disk[i]; #ifdef GEOM_DEBUG printf("match %s with %d " "dev ck %x bios ck %x\n", device_xname(dv), i, ck, be->cksum); #endif if (be->flags & BI_GEOM_INVALID) continue; if (be->cksum == ck && memcmp(&mbr[MBR_PART_OFFSET], be->mbrparts, MBR_PART_COUNT * sizeof(struct mbr_partition)) == 0) { #ifdef GEOM_DEBUG printf("matched BIOS disk %x with %s\n", be->dev, device_xname(dv)); #endif x86_alldisks->dl_nativedisks[n]. ni_biosmatches[m++] = i; } } x86_alldisks->dl_nativedisks[n].ni_nmatches = m; } } deviter_release(&di); }
/* * Mount a remote root fs via. NFS. It goes like this: * - Call nfs_boot_init() to fill in the nfs_diskless struct * - build the rootfs mount point and call mountnfs() to do the rest. */ int nfs_mountroot(void) { struct timespec ts; struct nfs_diskless *nd; struct vattr attr; struct mount *mp; struct vnode *vp; struct lwp *l; long n; int error; l = curlwp; /* XXX */ if (device_class(root_device) != DV_IFNET) return (ENODEV); /* * XXX time must be non-zero when we init the interface or else * the arp code will wedge. [Fixed now in if_ether.c] * However, the NFS attribute cache gives false "hits" when the * current time < nfs_attrtimeo(nmp, np) so keep this in for now. */ if (time_second < NFS_MAXATTRTIMO) { ts.tv_sec = NFS_MAXATTRTIMO; ts.tv_nsec = 0; tc_setclock(&ts); } /* * Call nfs_boot_init() to fill in the nfs_diskless struct. * Side effect: Finds and configures a network interface. */ nd = kmem_zalloc(sizeof(*nd), KM_SLEEP); error = nfs_boot_init(nd, l); if (error) { kmem_free(nd, sizeof(*nd)); return (error); } /* * Create the root mount point. */ error = nfs_mount_diskless(&nd->nd_root, "/", &mp, &vp, l); if (error) goto out; printf("root on %s\n", nd->nd_root.ndm_host); /* * Link it into the mount list. */ mountlist_append(mp); rootvp = vp; mp->mnt_vnodecovered = NULLVP; vfs_unbusy(mp, false, NULL); /* Get root attributes (for the time). */ vn_lock(vp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(vp, &attr, l->l_cred); VOP_UNLOCK(vp); if (error) panic("nfs_mountroot: getattr for root"); n = attr.va_atime.tv_sec; #ifdef DEBUG printf("root time: 0x%lx\n", n); #endif setrootfstime(n); out: if (error) nfs_boot_cleanup(nd, l); kmem_free(nd, sizeof(*nd)); return (error); }