Пример #1
0
/*
 * 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;
}
Пример #2
0
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));
}