Пример #1
0
static int
read_minix_subp(struct biosdisk *d, struct disklabel* dflt_lbl,
			int this_ext, daddr_t sector)
{
	struct mbr_partition mbr[MBR_PART_COUNT];
	int i;
	int typ;
	struct partition *p;

	if (readsects(&d->ll, sector, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
		printf("Error reading MFS sector %"PRId64"\n", sector);
#endif
		return EIO;
	}
	if ((uint8_t)d->buf[510] != 0x55 || (uint8_t)d->buf[511] != 0xAA) {
		return -1;
	}
	memcpy(&mbr, MBR_PARTS(d->buf), sizeof(mbr));
	for (i = 0; i < MBR_PART_COUNT; i++) {
		typ = mbr[i].mbrp_type;
		if (typ == 0)
			continue;
		sector = this_ext + mbr[i].mbrp_start;
		if (dflt_lbl->d_npartitions >= MAXPARTITIONS)
			continue;
		p = &dflt_lbl->d_partitions[dflt_lbl->d_npartitions++];
		p->p_offset = sector;
		p->p_size = mbr[i].mbrp_size;
		p->p_fstype = xlat_mbr_fstype(typ);
	}
	return 0;
}
Пример #2
0
static int
look_netbsd_part(mbr_args_t *a, mbr_partition_t *dp, int slot, uint ext_base)
{
	struct partition *pp;
	int ptn_base = ext_base + le32toh(dp->mbrp_start);
	int rval;

	if (
#ifdef COMPAT_386BSD_MBRPART
	    dp->mbrp_type == MBR_PTYPE_386BSD ||
#endif
	    dp->mbrp_type == MBR_PTYPE_NETBSD) {
		rval = validate_label(a, ptn_base);

#if RAW_PART == 3
		/* Put actual location where we found the label into ptn 2 */
		if (rval == SCAN_FOUND || a->lp->d_partitions[2].p_size == 0) {
			a->lp->d_partitions[2].p_size = le32toh(dp->mbrp_size);
			a->lp->d_partitions[2].p_offset = ptn_base;
		}
#endif

		/* If we got a netbsd label look no further */
		if (rval == SCAN_FOUND)
			return rval;
	}

	/* Install main partitions into e..h and extended into i+ */
	if (ext_base == 0)
		slot += 4;
	else {
		slot = 4 + MBR_PART_COUNT;
		pp = &a->lp->d_partitions[slot];
		for (; slot < MAXPARTITIONS; pp++, slot++) {
			/* This gets called twice - avoid duplicates */
			if (pp->p_offset == ptn_base &&
			    pp->p_size == le32toh(dp->mbrp_size))
				break;
			if (pp->p_size == 0)
				break;
		}
	}

	if (slot < MAXPARTITIONS) {
		/* Stop 'a' being the entire disk */
		a->lp->d_partitions[0].p_size = 0;
		a->lp->d_partitions[0].p_fstype = 0;

		/* save partition info */
		pp = &a->lp->d_partitions[slot];
		pp->p_offset = ptn_base;
		pp->p_size = le32toh(dp->mbrp_size);
		pp->p_fstype = xlat_mbr_fstype(dp->mbrp_type);

		if (slot >= a->lp->d_npartitions)
			a->lp->d_npartitions = slot + 1;
	}

	return SCAN_CONTINUE;
}
Пример #3
0
static int
read_label(struct biosdisk *d)
{
	struct disklabel dflt_lbl;
	struct mbr_partition mbr[MBR_PART_COUNT];
	struct partition *p;
	uint32_t sector;
	int i;
	int error;
	int typ;
	uint32_t ext_base, this_ext, next_ext;
#ifdef COMPAT_386BSD_MBRPART
	int sector_386bsd = -1;
#endif

	memset(&dflt_lbl, 0, sizeof(dflt_lbl));
	dflt_lbl.d_npartitions = 8;

	d->boff = 0;

	if (d->ll.type != BIOSDISK_TYPE_HD)
		/* No label on floppy and CD */
		return -1;

	/*
	 * find NetBSD Partition in DOS partition table
	 * XXX check magic???
	 */
	ext_base = 0;
	next_ext = 0;
	for (;;) {
		this_ext = ext_base + next_ext;
		next_ext = 0;
		if (readsects(&d->ll, this_ext, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
			printf("error reading MBR sector %u\n", this_ext);
#endif
			return EIO;
		}
		memcpy(&mbr, MBR_PARTS(d->buf), sizeof(mbr));
		/* Look for NetBSD partition ID */
		for (i = 0; i < MBR_PART_COUNT; i++) {
			typ = mbr[i].mbrp_type;
			if (typ == 0)
				continue;
			sector = this_ext + mbr[i].mbrp_start;
#ifdef DISK_DEBUG
			printf("ptn type %d in sector %u\n", typ, sector);
#endif
                        if (typ == MBR_PTYPE_MINIX_14B) {
				if (!read_minix_subp(d, &dflt_lbl,
						   this_ext, sector)) {
					/* Don't add "container" partition */
					continue;
				}
			}
			if (typ == MBR_PTYPE_NETBSD) {
				error = check_label(d, sector);
				if (error >= 0)
					return error;
			}
			if (MBR_IS_EXTENDED(typ)) {
				next_ext = mbr[i].mbrp_start;
				continue;
			}
#ifdef COMPAT_386BSD_MBRPART
			if (this_ext == 0 && typ == MBR_PTYPE_386BSD)
				sector_386bsd = sector;
#endif
			if (this_ext != 0) {
				if (dflt_lbl.d_npartitions >= MAXPARTITIONS)
					continue;
				p = &dflt_lbl.d_partitions[dflt_lbl.d_npartitions++];
			} else
				p = &dflt_lbl.d_partitions[i];
			p->p_offset = sector;
			p->p_size = mbr[i].mbrp_size;
			p->p_fstype = xlat_mbr_fstype(typ);
		}
		if (next_ext == 0)
			break;
		if (ext_base == 0) {
			ext_base = next_ext;
			next_ext = 0;
		}
	}

	sector = 0;
#ifdef COMPAT_386BSD_MBRPART
	if (sector_386bsd != -1) {
		printf("old BSD partition ID!\n");
		sector = sector_386bsd;
	}
#endif

	/*
	 * One of two things:
	 * 	1. no MBR
	 *	2. no NetBSD partition in MBR
	 *
	 * We simply default to "start of disk" in this case and
	 * press on.
	 */
	error = check_label(d, sector);
	if (error >= 0)
		return error;

	/*
	 * Nothing at start of disk, return info from mbr partitions.
	 */
	/* XXX fill it to make checksum match kernel one */
	dflt_lbl.d_checksum = dkcksum(&dflt_lbl);
	ingest_label(d, &dflt_lbl);
	return 0;
}