Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 May 2012 05:04:49 +0000 (UTC)
From:      Tim Kientzle <kientzle@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234860 - head/sys/boot/uboot/lib
Message-ID:  <201205010504.q4154niY002886@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kientzle
Date: Tue May  1 05:04:49 2012
New Revision: 234860
URL: http://svn.freebsd.org/changeset/base/234860

Log:
  Teach ubldr(8) about simple MBR partitioning.

Modified:
  head/sys/boot/uboot/lib/devicename.c
  head/sys/boot/uboot/lib/disk.c
  head/sys/boot/uboot/lib/libuboot.h

Modified: head/sys/boot/uboot/lib/devicename.c
==============================================================================
--- head/sys/boot/uboot/lib/devicename.c	Tue May  1 04:35:53 2012	(r234859)
+++ head/sys/boot/uboot/lib/devicename.c	Tue May  1 05:04:49 2012	(r234860)
@@ -131,6 +131,10 @@ uboot_parsedev(struct uboot_devdesc **de
 				    *(cp + 1) != ':') {
 					pnum = strtol(cp + 1, &cp, 10);
 					ptype = PTYPE_GPT;
+				} else if (*cp == 's' && *(cp + 1) &&
+				    *(cp + 1) != ':') {
+					pnum = strtol(cp + 1, &cp, 10);
+					ptype = PTYPE_MBR;
 				} else {
 					pnum = *cp - 'a';
 					ptype = PTYPE_BSDLABEL;
@@ -218,6 +222,9 @@ uboot_fmtdev(void *vdev)
 			else if (dev->d_kind.disk.ptype == PTYPE_GPT)
 				cp += sprintf(cp, "p%i",
 				    dev->d_kind.disk.pnum);
+			else if (dev->d_kind.disk.ptype == PTYPE_MBR)
+				cp += sprintf(cp, "s%i",
+				    dev->d_kind.disk.pnum);
 		}
 
 		strcat(cp, ":");

Modified: head/sys/boot/uboot/lib/disk.c
==============================================================================
--- head/sys/boot/uboot/lib/disk.c	Tue May  1 04:35:53 2012	(r234859)
+++ head/sys/boot/uboot/lib/disk.c	Tue May  1 05:04:49 2012	(r234860)
@@ -398,6 +398,94 @@ out:
 }
 
 static int
+stor_open_mbr(struct open_dev *od, struct uboot_devdesc *dev)
+{
+	char *buf = NULL;
+	struct dos_partition *dp;
+	int err, i, part;
+
+	od->od_nparts = 0;
+	od->od_partitions = NULL;
+
+	/* Block size must be at least 512 bytes. */
+	if (od->od_bsize < 512)
+		return (ENXIO);
+
+	/* Read MBR */
+	buf = malloc(od->od_bsize);
+	if (!buf) {
+		stor_printf("could not allocate memory for MBR\n");
+		return (ENOMEM);
+	}
+	err = stor_readdev(dev, 0, 1, buf);
+	if (err) {
+		stor_printf("MBR read error=%d\n", err);
+		err = EIO;
+		goto out;
+	}
+
+	/* Check the slice table magic. */
+	if (le16toh(*((uint16_t *)(buf + DOSMAGICOFFSET))) != DOSMAGIC) {
+		err = ENXIO;
+		goto out;
+	}
+
+	/* Save information about partitions. */
+	dp = (struct dos_partition *)(buf + DOSPARTOFF);
+	od->od_partitions = calloc(NDOSPART, sizeof(struct gpt_part));
+	if (!od->od_partitions) {
+		stor_printf("could not allocate memory for MBR partitions\n");
+		err = ENOMEM;
+		goto out;
+	}
+
+	part = 0;
+	for (i = 0; i < NDOSPART; i++) {
+		u_int32_t start = le32dec(&dp[i].dp_start);
+		u_int32_t size = le32dec(&dp[i].dp_size);
+		uuid_t *u = NULL;
+
+		/* Map MBR partition types to GPT partition types. */
+		switch (dp[i].dp_typ) {
+		case DOSPTYP_386BSD:
+			u = &freebsd_ufs;
+			break;
+		/* XXX Other types XXX */
+		}
+
+		if (u) {
+			od->od_partitions[part].gp_type = *u;
+			od->od_partitions[part].gp_index = i + 1;
+			od->od_partitions[part].gp_start = start;
+			od->od_partitions[part].gp_end = start + size;
+			part += 1;
+		}
+	}
+	od->od_nparts = part;
+
+	if (od->od_nparts == 0) {
+		err = EINVAL;
+		goto out;
+	}
+
+	dev->d_disk.ptype = PTYPE_MBR;
+
+	/* XXX Be smarter here? XXX */
+	if (dev->d_disk.pnum == 0)
+		dev->d_disk.pnum = od->od_partitions[0].gp_index;
+
+	for (i = 0; i < od->od_nparts; i++)
+		if (od->od_partitions[i].gp_index == dev->d_disk.pnum)
+			od->od_bstart = od->od_partitions[i].gp_start;
+
+out:
+	if (err && od->od_partitions)
+		free(od->od_partitions);
+	free(buf);
+	return (err);
+}
+
+static int
 stor_open_bsdlabel(struct open_dev *od, struct uboot_devdesc *dev)
 {
 	char *buf;
@@ -443,7 +531,7 @@ stor_readdev(struct uboot_devdesc *dev, 
 	lbasize_t real_size;
 	int err, handle;
 
-	debugf("reading size=%d @ 0x%08x\n", size, (uint32_t)buf);
+	debugf("reading blk=%d size=%d @ 0x%08x\n", (int)blk, size, (uint32_t)buf);
 
 	handle = stor_info[dev->d_unit];
 	err = ub_dev_read(handle, buf, size, blk, &real_size);
@@ -495,7 +583,10 @@ stor_opendev(struct open_dev **odp, stru
 	od->od_bsize = di->di_stor.block_size;
 	od->od_bstart = 0;
 
-	if ((err = stor_open_gpt(od, dev)) != 0)
+	err = stor_open_gpt(od, dev);
+	if (err != 0)
+		err = stor_open_mbr(od, dev);
+	if (err != 0)
 		err = stor_open_bsdlabel(od, dev);
 
 	if (err != 0)
@@ -517,6 +608,8 @@ stor_closedev(struct uboot_devdesc *dev)
 	od = (struct open_dev *)dev->d_disk.data;
 	if (dev->d_disk.ptype == PTYPE_GPT && od->od_nparts != 0)
 		free(od->od_partitions);
+	if (dev->d_disk.ptype == PTYPE_MBR && od->od_nparts != 0)
+		free(od->od_partitions);
 
 	free(od);
 	dev->d_disk.data = NULL;

Modified: head/sys/boot/uboot/lib/libuboot.h
==============================================================================
--- head/sys/boot/uboot/lib/libuboot.h	Tue May  1 04:35:53 2012	(r234859)
+++ head/sys/boot/uboot/lib/libuboot.h	Tue May  1 05:04:49 2012	(r234860)
@@ -45,6 +45,7 @@ struct uboot_devdesc
 
 #define PTYPE_BSDLABEL	1
 #define PTYPE_GPT	2
+#define PTYPE_MBR	3
 
 /*
  * Default network packet alignment in memory



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205010504.q4154niY002886>