summaryrefslogtreecommitdiffstats
path: root/sys/boot/arm
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2008-10-07 17:44:04 +0000
committerimp <imp@FreeBSD.org>2008-10-07 17:44:04 +0000
commit95c9e7cdf318405d7f5627ba68c71d4285009614 (patch)
treeffec1c5bc0ad2b22e4d71dc0ea0d144dc2eef51e /sys/boot/arm
parentde3502c94653a61f09be8b8db9619c0b03d1964c (diff)
downloadFreeBSD-src-95c9e7cdf318405d7f5627ba68c71d4285009614.zip
FreeBSD-src-95c9e7cdf318405d7f5627ba68c71d4285009614.tar.gz
More diff reductions against ixp425/boot2/boot2.c. This time, we
bring in FIXUP_BOOT_DRV functionality as an #ifdef. This is not enabled at this time, and the md5 remains constant with this change. Apart from the 'accept any partitioning scheme on the device' changes, this was the biggest delta... # and yes, we'll merge these into one source file if we can do that in a # way that makes sense. Obtained from: sys/boot/arm/ixp425/boot2/boot2.c
Diffstat (limited to 'sys/boot/arm')
-rw-r--r--sys/boot/arm/at91/boot2/boot2.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/sys/boot/arm/at91/boot2/boot2.c b/sys/boot/arm/at91/boot2/boot2.c
index f5f04e4..9730888 100644
--- a/sys/boot/arm/at91/boot2/boot2.c
+++ b/sys/boot/arm/at91/boot2/boot2.c
@@ -95,6 +95,9 @@ static void load(void);
static int parse(void);
static int xfsread(ino_t, void *, size_t);
static int dskread(void *, unsigned, unsigned);
+#ifdef FIXUP_BOOT_DRV
+static void fixup_boot_drv(caddr_t, int, int, int);
+#endif
#define UFS_SMALL_CGBASE
#include "ufsread.c"
@@ -196,7 +199,13 @@ load(void)
ino_t ino;
uint32_t addr;
int i, j;
+#ifdef FIXUP_BOOT_DRV
+ caddr_t staddr;
+ int klen;
+ staddr = (caddr_t)0xffffffff;
+ klen = 0;
+#endif
if (!(ino = lookup(kname))) {
if (!ls)
printf("No %s\n", kname);
@@ -218,10 +227,18 @@ load(void)
for (i = 0; i < 2; i++) {
p = (caddr_t)ep[i].p_paddr;
fs_off = ep[i].p_offset;
+#ifdef FIXUP_BOOT_DRV
+ if (staddr == (caddr_t)0xffffffff)
+ staddr = p;
+ klen += ep[i].p_filesz;
+#endif
if (xfsread(ino, p, ep[i].p_filesz))
return;
}
addr = eh.e_entry;
+#ifdef FIXUP_BOOT_DRV
+ fixup_boot_drv(staddr, klen, bootslice, bootpart);
+#endif
((void(*)(int))addr)(opts & RBX_MASK);
}
@@ -304,3 +321,73 @@ dskread(void *buf, unsigned lba, unsigned nblk)
}
return drvread(buf, dsk_start + lba, nblk);
}
+
+#ifdef FIXUP_BOOT_DRV
+/*
+ * fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel
+ * and change it to what was specified on the comandline or /boot.conf
+ * file or to what was encountered on the disk. It will try to handle 3
+ * different disk layouts, raw (dangerously dedicated), slice only and
+ * slice + partition. It will look for the following strings in the
+ * kernel, but if it is one of the first three, the string in the kernel
+ * must use the correct form to match the actual disk layout:
+ * - ufs:ad0a
+ * - ufs:ad0s1
+ * - ufs:ad0s1a
+ * - ufs:ROOTDEVNAME
+ * In the case of the first three strings, only the "a" at the end and
+ * the "1" after the "s" will be modified, if they exist. The string
+ * length will not be changed. In the case of the last string, the
+ * whole string will be built up and nul, '\0' terminated.
+ */
+static void
+fixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
+{
+ const u_int8_t op[] = "ufs:ROOTDEVNAME";
+ const u_int8_t op2[] = "ufs:ad0";
+ u_int8_t *p, *ps;
+
+ DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
+ (int)addr, klen, bs, bp);
+ if (bs > 4)
+ return;
+ if (bp > 7)
+ return;
+ ps = memmem(addr, klen, op, sizeof(op));
+ if (ps != NULL) {
+ p = ps + 4; /* past ufs: */
+ DPRINTF("Found it at 0x%x\n", (int)ps);
+ p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */
+ p += 3;
+ if (bs > 0) {
+ /* append slice */
+ *p++ = 's';
+ *p++ = bs + '0';
+ }
+ if (disk_layout != DL_SLICE) {
+ /* append partition */
+ *p++ = bp + 'a';
+ }
+ *p = '\0';
+ } else {
+ ps = memmem(addr, klen, op2, sizeof(op2) - 1);
+ if (ps != NULL) {
+ p = ps + sizeof(op2) - 1;
+ DPRINTF("Found it at 0x%x\n", (int)ps);
+ if (*p == 's') {
+ /* fix slice */
+ p++;
+ *p++ = bs + '0';
+ }
+ if (*p == 'a')
+ *p = bp + 'a';
+ }
+ }
+ if (ps == NULL) {
+ printf("Could not locate \"%s\" to fix kernel boot device, "
+ "check ROOTDEVNAME is set\n", op);
+ return;
+ }
+ DPRINTF("Changed boot device to %s\n", ps);
+}
+#endif
OpenPOWER on IntegriCloud