diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2001-03-14 08:11:26 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2001-03-14 08:11:26 +0000 |
commit | 61295d6a90f797f6f37a0d86581537ee560e4f72 (patch) | |
tree | 3658971efe06eeb17d8fcf89ce0db23cea6951ee /sys | |
parent | 4996c6df5e2556471c44ab27ca1f295345c7865a (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')
-rw-r--r-- | sys/arch/powerpc/stand/ofdev.c | 78 |
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; } |