void md_loadboot(void) { /* Load prototype boot blocks. */ if ((blkstore = loadproto(stage1, &blksize)) == NULL) exit(1); /* XXX - Paranoia: Make sure size is aligned! */ if (blksize & (DEV_BSIZE - 1)) errx(1, "proto %s bad size=%ld", stage1, blksize); if (blksize > SBSIZE - DEV_BSIZE) errx(1, "proto bootblocks too big"); }
/* * Read information about /boot's inode and filesystem parameters, then * put biosboot (partition boot record) on the target drive with these * parameters patched in. */ int main(int argc, char *argv[]) { int vol = -1, ndisks = 0, disk; int c; int devfd; struct disklabel dl; while ((c = getopt(argc, argv, "vn")) != -1) { switch (c) { case 'n': /* Do not actually write the bootblock to disk. */ nowrite = 1; break; case 'v': /* Give more information. */ verbose = 1; break; default: usage(); } } if (argc - optind < 3) usage(); boot = argv[optind]; proto = argv[optind + 1]; realdev = dev = argv[optind + 2]; /* Open raw disk device. */ if ((devfd = opendev(dev, (nowrite? O_RDONLY:O_RDWR), OPENDEV_PART, &realdev)) < 0) err(1, "open: %s", realdev); if (verbose) fprintf(stderr, "boot: %s proto: %s device: %s\n", boot, proto, realdev); /* Load proto blocks into core. */ if ((protostore = loadproto(proto, &protosize)) == NULL) exit(1); /* XXX - Paranoia: Make sure size is aligned! */ if (protosize & (DEV_BSIZE - 1)) errx(1, "proto %s bad size=%ld", proto, protosize); if (protosize > SBSIZE - DEV_BSIZE) errx(1, "proto bootblocks too big"); if (sr_volume(devfd, &vol, &ndisks)) { /* Install boot loader into softraid volume. */ sr_installboot(devfd); /* Install biosboot on each disk that is part of this volume. */ for (disk = 0; disk < ndisks; disk++) sr_installpbr(devfd, vol, disk); } else { /* Get and check disklabel. */ if (ioctl(devfd, DIOCGDINFO, &dl) != 0) err(1, "disklabel: %s", realdev); if (dl.d_magic != DISKMAGIC) err(1, "bad disklabel magic=0x%08x", dl.d_magic); /* Warn on unknown disklabel types. */ if (dl.d_type == 0) warnx("disklabel type unknown"); /* Get bootstrap parameters to patch into proto. */ if (getbootparams(boot, devfd, &dl) != 0) exit(1); /* Write boot blocks to device. */ write_bootblocks(devfd, &dl); } (void)close(devfd); return 0; }
/* * Read information about /boot's inode and filesystem parameters, then * put biosboot (partition boot record) on the target drive with these * parameters patched in. */ int main(int argc, char *argv[]) { int c; int devfd; char *protostore; long protosize; struct stat sb; struct disklabel dl; struct dos_mbr mbr; struct dos_partition *dp; off_t startoff = 0; while ((c = getopt(argc, argv, "vn")) != -1) { switch (c) { case 'n': /* Do not actually write the bootblock to disk. */ nowrite = 1; break; case 'v': /* Give more information. */ verbose = 1; break; default: usage(); } } if (argc - optind < 3) usage(); boot = argv[optind]; proto = argv[optind + 1]; realdev = dev = argv[optind + 2]; /* Open and check raw disk device. */ if ((devfd = opendev(dev, (nowrite? O_RDONLY:O_RDWR), OPENDEV_PART, &realdev)) < 0) err(1, "open: %s", realdev); if (verbose) { fprintf(stderr, "boot: %s\n", boot); fprintf(stderr, "proto: %s\n", proto); fprintf(stderr, "device: %s\n", realdev); } if (ioctl(devfd, DIOCGDINFO, &dl) != 0) err(1, "disklabel: %s", realdev); /* Check disklabel. */ if (dl.d_magic != DISKMAGIC) err(1, "bad disklabel magic=0x%08x", dl.d_magic); /* Warn on unknown disklabel types. */ if (dl.d_type == 0) warnx("disklabel type unknown"); /* Load proto blocks into core. */ if ((protostore = loadproto(proto, &protosize)) == NULL) exit(1); /* XXX - Paranoia: Make sure size is aligned! */ if (protosize & (DEV_BSIZE - 1)) errx(1, "proto %s bad size=%ld", proto, protosize); /* Write patched proto bootblock(s) into the superblock. */ if (protosize > SBSIZE - DEV_BSIZE) errx(1, "proto bootblocks too big"); if (fstat(devfd, &sb) < 0) err(1, "stat: %s", realdev); if (!S_ISCHR(sb.st_mode)) errx(1, "%s: not a character device", realdev); /* Get bootstrap parameters that are to be patched into proto. */ if (getbootparams(boot, devfd, &dl) != 0) exit(1); /* Patch the parameters into the proto bootstrap sector. */ pbr_set_symbols(proto, protostore, pbr_symbols); if (!nowrite) { /* Sync filesystems (to clean in-memory superblock?). */ sync(); sleep(1); } if (dl.d_type != 0 && dl.d_type != DTYPE_FLOPPY && dl.d_type != DTYPE_VND) { if (lseek(devfd, (off_t)DOSBBSECTOR, SEEK_SET) < 0 || read(devfd, &mbr, sizeof(mbr)) < sizeof(mbr)) err(4, "can't read master boot record"); if (mbr.dmbr_sign != DOSMBR_SIGNATURE) errx(1, "broken MBR"); /* Find OpenBSD partition. */ for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; dp++) { if (dp->dp_size && dp->dp_typ == DOSPTYP_OPENBSD) { startoff = (off_t)dp->dp_start * dl.d_secsize; fprintf(stderr, "using MBR partition %ld: " "type %d (0x%02x) offset %d (0x%x)\n", (long)(dp - mbr.dmbr_parts), dp->dp_typ, dp->dp_typ, dp->dp_start, dp->dp_start); break; } } /* Don't check for old part number, that is ;-p */ if (dp >= &mbr.dmbr_parts[NDOSPART]) errx(1, "no OpenBSD partition"); } if (!nowrite) { if (lseek(devfd, startoff, SEEK_SET) < 0 || write(devfd, protostore, protosize) != protosize) err(1, "write bootstrap"); } (void)close(devfd); return 0; }