Subject: Boot loader changes for RAID boot
To: NetBSD port-sparc mailing list <port-sparc@netbsd.org>
From: Julian Coleman <jdc@coris.org.uk>
List: port-sparc
Date: 06/17/2006 11:34:30
--f2QGlHpHGjS2mn6Y
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
I've made some changse to the boot loader code to enable booting from RAID 1.
The code looks at the disklabel and checks if the boot partition is of type
RAID. If so, it offsets the reads from the disk, so that it can read the
kernel image.
I've tested this on a SPARCstation 20, a SPARCstation 2 and a 4/330. The
only caveat is that the 4/330 will only boot from RAID if the RAID partition
is the first one on the disk, because I can't see any easy way of reading the
disklabel for machines without OBP (the `ok' prompt).
Patches are attached. Can anyone see any problem with them?
Thanks,
J
--
My other computer also runs NetBSD / Sailing at Newbiggin
http://www.netbsd.org/ / http://www.newbigginsailingclub.org/
--f2QGlHpHGjS2mn6Y
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="common.diffs"
diff -ur /usr/src/sys/arch/sparc/stand/common/promdev.c common/promdev.c
--- /usr/src/sys/arch/sparc/stand/common/promdev.c 2005-05-01 09:08:39.000000000 +0100
+++ common/promdev.c 2006-06-17 10:51:46.000000000 +0100
@@ -48,6 +48,12 @@
#include <lib/libkern/libkern.h>
#include <sparc/stand/common/promdev.h>
+#ifndef BOOTXX
+#include <sys/disklabel.h>
+#include <dev/sun/disklabel.h>
+#include <dev/raidframe/raidframevar.h>
+#endif
+
/* OBP V0-3 PROM vector */
#define obpvec ((struct promvec *)romp)
@@ -94,6 +100,10 @@
char prom_bootdevice[MAX_PROM_PATH];
static int saveecho;
+#ifndef BOOTXX
+static daddr_t doffset = 0;
+#endif
+
void
putchar(c)
@@ -119,6 +129,15 @@
{
int error = 0, fd = 0;
struct promdata *pd;
+#ifndef BOOTXX
+ char *partition;
+ int part = 0;
+ char rawpart[MAX_PROM_PATH];
+ struct promdata *disk_pd;
+ char buf[DEV_BSIZE];
+ struct disklabel *dlp;
+ size_t read;
+#endif
pd = (struct promdata *)alloc(sizeof *pd);
f->f_devdata = (void *)pd;
@@ -188,8 +207,78 @@
prom_bootdevice);
return (error);
}
- } else
+ } else {
bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
+
+#ifdef NOTDEF_DEBUG
+ printf("devopen: Checking disklabel for RAID partition\n");
+#endif
+
+ /*
+ * We need to read from the raw partition (i.e. the
+ * beginning of the disk in order to check the NetBSD
+ * disklabel to see if the boot partition is type RAID.
+ *
+ * For machines with prom_version() == PROM_OLDMON, we
+ * only handle boot from RAID for the first disk partition.
+ */
+ disk_pd = (struct promdata *)alloc(sizeof *disk_pd);
+ memcpy(disk_pd, pd, sizeof(struct promdata));
+ if (prom_version() != PROM_OLDMON) {
+ strcpy(rawpart, prom_bootdevice);
+ if ((partition = strchr(rawpart, ':')) != '\0' &&
+ *++partition >= 'a' &&
+ *partition <= 'a' + MAXPARTITIONS) {
+ part = *partition - 'a';
+ *partition = RAW_PART + 'a';
+ } else
+ strcat(rawpart, ":c");
+ if ((disk_pd->fd = prom_open(rawpart)) == 0)
+ return 0;
+ }
+ error = f->f_dev->dv_strategy(disk_pd, F_READ, LABELSECTOR,
+ DEV_BSIZE, &buf, &read);
+ if (prom_version() != PROM_OLDMON)
+ prom_close(disk_pd->fd);
+ if (error || (read != DEV_BSIZE))
+ return 0;
+#ifdef NOTDEF_DEBUG
+ {
+ int x = 0;
+ char *p = (char *) buf;
+
+ printf(" Sector %d:\n", LABELSECTOR);
+ printf("00000000 ");
+ while (x < DEV_BSIZE) {
+ if (*p >= 0x00 && *p < 0x10)
+ printf("0%x ", *p & 0xff);
+ else
+ printf("%x ", *p & 0xff);
+ x++;
+ if (x && !(x % 8))
+ printf(" ");
+ if (x && !(x % 16)) {
+ if(x < 0x100)
+ printf("\n000000%x ", x);
+ else
+ printf("\n00000%x ", x);
+ }
+ p++;
+ }
+ printf("\n");
+ }
+#endif
+ /* Check for NetBSD disk label. */
+ dlp = (struct disklabel *) (buf + LABELOFFSET);
+ if (dlp->d_magic == DISKMAGIC && !dkcksum(dlp) &&
+ dlp->d_partitions[part].p_fstype == FS_RAID) {
+#ifdef NOTDEF_DEBUG
+ printf("devopen: found RAID partition, "
+ "adjusting offset to %d\n", RF_PROTECTED_SECTORS);
+#endif
+ doffset = RF_PROTECTED_SECTORS;
+ }
+ }
#endif /* BOOTXX */
return (0);
}
@@ -208,6 +297,9 @@
struct promdata *pd = (struct promdata *)devdata;
int fd = pd->fd;
+#ifndef BOOTXX
+ dblk += doffset;
+#endif
#ifdef DEBUG_PROM
printf("promstrategy: size=%d dblk=%d\n", size, dblk);
#endif
@@ -249,6 +341,9 @@
struct promdata *pd = (struct promdata *)devdata;
int fd = pd->fd;
+#ifndef BOOTXX
+ dblk += doffset;
+#endif
#ifdef DEBUG_PROM
printf("promstrategy: size=%d dblk=%d\n", size, dblk);
#endif
@@ -290,6 +385,9 @@
si = pd->si;
ops = si->si_boottab;
+#ifndef BOOTXX
+ dblk += doffset;
+#endif
#ifdef DEBUG_PROM
printf("prom_strategy: size=%d dblk=%d\n", size, dblk);
#endif
Only in common: promdev.c.dist
--f2QGlHpHGjS2mn6Y--