/* * Find a valid disklabel. */ static int search_label(struct of_dev *devp, u_long off, u_char *buf, struct disklabel *lp, u_long off0) { size_t nread; struct mbr_partition *p; int i; u_long poff; static int recursion; if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &nread) || nread != DEV_BSIZE) return ERDLAB; if (*(u_int16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC)) return ERDLAB; if (recursion++ <= 1) off0 += off; for (p = (struct mbr_partition *)(buf + MBR_PART_OFFSET), i = 4; --i >= 0; p++) { if (p->mbrp_type == MBR_PTYPE_NETBSD #ifdef COMPAT_386BSD_MBRPART || (p->mbrp_type == MBR_PTYPE_386BSD && (printf("WARNING: old BSD partition ID!\n"), 1) /* XXX XXX - libsa printf() is void */ ) #endif ) { poff = get_long(&p->mbrp_start) + off0; if (strategy(devp, F_READ, poff + 1, DEV_BSIZE, buf, &nread) == 0 && nread == DEV_BSIZE) { if (!getdisklabel(buf, lp)) { recursion--; return 0; } } if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &nread) || nread != DEV_BSIZE) { recursion--; return ERDLAB; } } else if (p->mbrp_type == MBR_PTYPE_EXT) { poff = get_long(&p->mbrp_start); if (!search_label(devp, poff, buf, lp, off0)) { recursion--; return 0; } if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &nread) || nread != DEV_BSIZE) { recursion--; return ERDLAB; } } } recursion--; return ERDLAB; }
static void prep_check_mbr(int prep_fd, char *rawdev) { int raw_fd; unsigned long entry, length; struct mbr_partition *mbrp; struct stat raw_stat; /* If we are building a standalone image, do not write an MBR, just * set entry point and boot image size skipping over elf header */ if (saloneflag) { entry = sa_htole32(0x400); length = sa_htole32(elf_stat.st_size - sizeof(hdr) + 0x400); lseek(prep_fd, sizeof(mbr), SEEK_SET); write(prep_fd, &entry, sizeof(entry)); write(prep_fd, &length, sizeof(length)); return; } /* * if we have a raw device, we need to check to see if it already * has a partition table, and if so, read it in and check for * suitability. */ if (rawdev != NULL) { raw_fd = open(rawdev, O_RDONLY, 0); if (raw_fd == -1) errx(3, "couldn't open raw device %s: %s", rawdev, strerror(errno)); fstat(raw_fd, &raw_stat); if (!S_ISCHR(raw_stat.st_mode)) errx(3, "%s is not a raw device", rawdev); if (read(raw_fd, mbr, 512) != 512) errx(3, "MBR Read Failed: %s", strerror(errno)); mbrp = (struct mbr_partition *)&mbr[MBR_PART_OFFSET]; if (mbrp->mbrp_type != MBR_PTYPE_PREP) errx(3, "First partition is not of type 0x%x.", MBR_PTYPE_PREP); if (mbrp->mbrp_start != 0) errx(3, "Use of the raw device is intended for" " upgrading of legacy installations. Your" " install does not have a PReP boot partition" " starting at sector 0. Use the -s option" " to build an image instead."); /* if we got this far, we are fine, write back the partition * and write the entry points and get outta here */ /* Set entry point and boot image size skipping over elf header */ lseek(prep_fd, 0, SEEK_SET); entry = sa_htole32(0x400); length = sa_htole32(elf_stat.st_size - sizeof(hdr) + 0x400); write(prep_fd, mbr, sizeof(mbr)); write(prep_fd, &entry, sizeof(entry)); write(prep_fd, &length, sizeof(length)); close(raw_fd); return; } /* if we get to here, we want to build a standard floppy or netboot * image to file, so just build it */ memset(mbr, 0, sizeof(mbr)); mbrp = (struct mbr_partition *)&mbr[MBR_PART_OFFSET]; /* Set entry point and boot image size skipping over elf header */ entry = sa_htole32(0x400); length = sa_htole32(elf_stat.st_size - sizeof(hdr) + 0x400); /* * Set magic number for msdos partition */ *(unsigned short *)&mbr[MBR_MAGIC_OFFSET] = sa_htole16(MBR_MAGIC); /* * Build a "PReP" partition table entry in the boot record * - "PReP" may only look at the system_indicator */ mbrp->mbrp_flag = MBR_PFLAG_ACTIVE; mbrp->mbrp_type = MBR_PTYPE_PREP; /* * The first block of the diskette is used by this "boot record" which * actually contains the partition table. (The first block of the * partition contains the boot image, but I digress...) We'll set up * one partition on the diskette and it shall contain the rest of the * diskette. */ mbrp->mbrp_shd = 0; /* zero-based */ mbrp->mbrp_ssect = 2; /* one-based */ mbrp->mbrp_scyl = 0; /* zero-based */ mbrp->mbrp_ehd = 1; /* assumes two heads */ if (lfloppyflag) mbrp->mbrp_esect = 36; /* 2.88MB floppy */ else mbrp->mbrp_esect = 18; /* assumes 18 sectors/track */ mbrp->mbrp_ecyl = 79; /* assumes 80 cylinders/diskette */ /* * The "PReP" software ignores the above fields and just looks at * the next two. * - size of the diskette is (assumed to be) * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) * - unlike the above sector numbers, * the beginning sector is zero-based! */ /* This has to be 0 on the PowerStack? */ mbrp->mbrp_start = sa_htole32(0); mbrp->mbrp_size = sa_htole32(2 * 18 * 80 - 1); write(prep_fd, mbr, sizeof(mbr)); write(prep_fd, &entry, sizeof(entry)); write(prep_fd, &length, sizeof(length)); }