Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/ofppc/stand/ofwboot When there is no NetBSD MBR par...
details: https://anonhg.NetBSD.org/src/rev/c7dbf390fee7
branches: trunk
changeset: 768580:c7dbf390fee7
user: phx <phx%NetBSD.org@localhost>
date: Sun Aug 21 13:08:57 2011 +0000
description:
When there is no NetBSD MBR partition with a valid disklabel, look for
the first FAT partition and construct a disklabel with an MSDOS filesystem
in partition 'a'.
diffstat:
sys/arch/ofppc/stand/ofwboot/mbr.c | 128 +++++++++++++++++++++++++-----------
1 files changed, 87 insertions(+), 41 deletions(-)
diffs (169 lines):
diff -r 4b4eb43e2aa7 -r c7dbf390fee7 sys/arch/ofppc/stand/ofwboot/mbr.c
--- a/sys/arch/ofppc/stand/ofwboot/mbr.c Sun Aug 21 11:04:21 2011 +0000
+++ b/sys/arch/ofppc/stand/ofwboot/mbr.c Sun Aug 21 13:08:57 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mbr.c,v 1.2 2011/08/18 09:03:28 phx Exp $ */
+/* $NetBSD: mbr.c,v 1.3 2011/08/21 13:08:57 phx Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -39,14 +39,9 @@
#include "mbr.h"
-
-static u_long
-get_long(const void *p)
-{
- const unsigned char *cp = p;
-
- return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
-}
+static int find_mbr_part(struct of_dev *, uint32_t, char *,
+ struct disklabel *, uint32_t, uint8_t, int);
+static void make_dos_label(struct disklabel *, uint32_t);
/*
* Find a valid MBR disklabel.
@@ -55,58 +50,109 @@
search_mbr_label(struct of_dev *devp, u_long off, char *buf,
struct disklabel *lp, u_long off0)
{
+ static uint8_t fat_types[] = {
+ MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S, MBR_PTYPE_FAT16B,
+ MBR_PTYPE_FAT32, MBR_PTYPE_FAT32L, MBR_PTYPE_FAT16L
+ };
+ size_t read;
+ uint32_t poff;
+ int i;
+
+ /* Find a disklabel in a NetBSD or 386BSD partition. */
+ poff = find_mbr_part(devp, off, buf, lp, 0, MBR_PTYPE_NETBSD, 0);
+#ifdef COMPAT_386BSD_MBRPART
+ if (poff == 0) {
+ poff = find_mbr_part(devp, off, buf, lp, 0,
+ MBR_PTYPE_386BSD, 0);
+ if (poff != 0)
+ printf("WARNING: old BSD partition ID!\n");
+ }
+#endif
+ if (poff != 0) {
+ if (strategy(devp, F_READ, poff + MBR_LABELSECTOR, DEV_BSIZE,
+ buf, &read) == 0 && read == DEV_BSIZE)
+ if (getdisklabel(buf, lp) == NULL)
+ return 0;
+ }
+
+ /*
+ * No BSD partition with a valid disklabel found, so try to
+ * construct a label from a DOS partition.
+ */
+ for (i = 0; i < sizeof(fat_types); i++) {
+ poff = find_mbr_part(devp, off, buf, lp, 0, fat_types[i], 0);
+ if (poff != 0) {
+ make_dos_label(lp, poff);
+ return 0;
+ }
+ }
+
+ return ERDLAB;
+}
+
+static int
+find_mbr_part(struct of_dev *devp, uint32_t off, char *buf,
+ struct disklabel *lp, uint32_t off0, uint8_t ptype, int recursion)
+{
size_t read;
struct mbr_partition *p;
int i;
- u_long poff;
- static int recursion;
+ uint32_t poff;
if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
|| read != DEV_BSIZE)
- return ERDLAB;
+ return 0;
- if (*(u_int16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC))
- return ERDLAB;
+ if (*(uint16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC))
+ return 0;
if (recursion++ <= 1)
off0 += off;
+
for (p = (struct mbr_partition *)(buf + MBR_PART_OFFSET), i = 0;
i < MBR_PART_COUNT; i++, 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 + MBR_LABELSECTOR,
- DEV_BSIZE, buf, &read) == 0
- && read == DEV_BSIZE) {
- if (getdisklabel(buf, lp) == NULL) {
- recursion--;
- return 0;
- }
+ if (p->mbrp_type == ptype) {
+ recursion--;
+ return sa_le32toh(p->mbrp_start) + off0;
+ }
+ else if (p->mbrp_type == MBR_PTYPE_EXT) {
+ poff = find_mbr_part(devp, sa_le32toh(p->mbrp_start),
+ buf, lp, off0, ptype, recursion);
+ if (poff != 0) {
+ recursion--;
+ return poff;
}
if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
|| read != DEV_BSIZE) {
recursion--;
- return ERDLAB;
- }
- } else if (p->mbrp_type == MBR_PTYPE_EXT) {
- poff = get_long(&p->mbrp_start);
- if (!search_mbr_label(devp, poff, buf, lp, off0)) {
- recursion--;
return 0;
}
- if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
- || read != DEV_BSIZE) {
- recursion--;
- return ERDLAB;
- }
}
}
recursion--;
- return ERDLAB;
+ return 0;
}
+
+static void
+make_dos_label(struct disklabel *lp, uint32_t poff)
+{
+ int i;
+
+ /* clear all partitions */
+ lp->d_npartitions = RAW_PART + 1;
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ lp->d_partitions[i].p_size = 0;
+ lp->d_partitions[i].p_offset = 0;
+ lp->d_partitions[i].p_fstype = 0;
+ }
+
+ /* set DOS partition as root partition */
+ lp->d_partitions[0].p_offset = poff;
+ lp->d_partitions[0].p_fstype = FS_MSDOS;
+
+ /* disklabel is valid */
+ lp->d_magic = lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+}
Home |
Main Index |
Thread Index |
Old Index