summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2001-03-14 08:11:26 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2001-03-14 08:11:26 +0000
commit61295d6a90f797f6f37a0d86581537ee560e4f72 (patch)
tree3658971efe06eeb17d8fcf89ce0db23cea6951ee /sys/arch
parent4996c6df5e2556471c44ab27ca1f295345c7865a (diff)
Allow bootloader to read MacOS(DPME) partition tables, find OpenBSD
type table, load OpenBSD disklabel from there, and load a kernel out of the OpenBSD root partition. ofwboot must be located in the root of the first HFS(+) partition of the disk.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/powerpc/stand/ofdev.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/sys/arch/powerpc/stand/ofdev.c b/sys/arch/powerpc/stand/ofdev.c
index 675f8b72d54..38f160b2f7c 100644
--- a/sys/arch/powerpc/stand/ofdev.c
+++ b/sys/arch/powerpc/stand/ofdev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofdev.c,v 1.7 2001/02/09 05:22:05 drahn Exp $ */
+/* $OpenBSD: ofdev.c,v 1.8 2001/03/14 08:11:25 drahn Exp $ */
/* $NetBSD: ofdev.c,v 1.1 1997/04/16 20:29:20 thorpej Exp $ */
/*
@@ -182,6 +182,77 @@ get_long(p)
return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
}
+int
+read_mac_label(devp, buf, lp)
+ struct of_dev *devp;
+ char *buf;
+ struct disklabel *lp;
+{
+ struct part_map_entry *part;
+ struct buf *bp;
+ int err;
+ size_t read;
+ int part_cnt;
+ int i;
+ char *s;
+
+ if ((strategy(devp, F_READ, 1, DEV_BSIZE, buf, &read) != 0)
+ || (read != DEV_BSIZE))
+ {
+ return ERDLAB;
+ }
+ part = (struct part_map_entry *)buf;
+
+ /* if first partition is not valid, assume not HFS/DPME partitioned */
+ if (part->pmSig != PART_ENTRY_MAGIC) {
+ return ERDLAB;
+ }
+ part_cnt = part->pmMapBlkCnt;
+
+ /* first search for "OpenBSD" partition type
+ * standard bsd disklabel lives inside at offset 0
+ * otherwise, we should fake a bsd partition
+ * with first HFS partition starting at 'i'
+ * ? will this cause problems with booting bsd.rd from hfs
+ */
+ for (i = 0; i < part_cnt; i++) {
+ /* read the appropriate block */
+ if ((strategy(devp, F_READ, 1+i, DEV_BSIZE, buf, &read) != 0)
+ || (read != DEV_BSIZE))
+ {
+ return ERDLAB;
+ }
+ part = (struct part_map_entry *)buf;
+ /* toupper the string, in case caps are different... */
+ for (s = part->pmPartType; *s; s++)
+ if ((*s >= 'a') && (*s <= 'z'))
+ *s = (*s - 'a' + 'A');
+ if (0 == strcmp(part->pmPartType, PART_TYPE_OPENBSD)) {
+ /* FOUND OUR PARTITION!!! */
+ printf("found OpenBSD DPME partition\n");
+ if(strategy(devp, F_READ, part->pmPyPartStart,
+ DEV_BSIZE, buf, &read) == 0
+ && read == DEV_BSIZE)
+ {
+ if (!getdisklabel(buf, lp)) {
+ return 0;
+ }
+ /* If we have an OpenBSD region
+ * but no valid parition table,
+ * we cannot load a kernel from
+ * it, punt.
+ * should not have more than one
+ * OpenBSD of DPME type.
+ */
+ return ERDLAB;
+
+ }
+
+ }
+ }
+ return ERDLAB;
+
+}
/*
* Find a valid disklabel.
*/
@@ -309,7 +380,10 @@ devopen(of, name, file)
|| read != DEV_BSIZE
|| getdisklabel(buf, &label)) {
/* Else try MBR partitions */
- error = search_label(&ofdev, 0, buf, &label, 0);
+ error = read_mac_label(&ofdev, buf, &label);
+ if (error == ERDLAB) {
+ error = search_label(&ofdev, 0, buf, &label, 0);
+ }
if (error && error != ERDLAB)
goto bad;
}