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>