Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Mar 2013 09:25:10 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 227083 for review
Message-ID:  <201303260925.r2Q9PAhe028266@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@227083?ac=10

Change 227083 by rwatson@rwatson_zenith_cl_cam_ac_uk on 2013/03/26 09:24:36

	Re-port FreeBSD's boot2 to MIPS / BERI based on i386 rather than
	arm.  We don't have the space constraints that caused an axe to be
	taken to the arm version, meaning that we can leave room for
	features such as partition tables, directory listings, etc.  This
	still involves copying boot2.c, but trying to create a machine-
	independent boot2 is a project for another day.  Not yet tested,
	but does link.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/boot/mips/beri/boot2/altera_jtag_uart.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/boot/mips/beri/boot2/boot2.c#4 edit
.. //depot/projects/ctsrd/beribsd/src/sys/boot/mips/beri/boot2/cons.h#2 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/boot/mips/beri/boot2/altera_jtag_uart.c#2 (text+ko) ====

@@ -160,22 +160,31 @@
 }
 
 int
-getc(int seconds)
+keyhit(int seconds)
 {
 	register_t stoptime;
 
 	stoptime = cp0_count_get() + seconds * 100000000;
 	while (cp0_count_get() < stoptime) {
-		if (uart_readable()) {
-			buffer_valid = 0;
-			return (buffer_data);
-		}
+		if (uart_readable())
+			return (1);
+	}
+	return (0);
+}
+
+int
+getc(int seconds)
+{
+
+	if (keyhit(seconds)) {
+		buffer_valid = 0;
+		return (buffer_data);
 	}
 	return (0);
 }
 
 void
-putchar(int ch)
+putc(int ch)
 {
 
 	uart_data_write(ch);

==== //depot/projects/ctsrd/beribsd/src/sys/boot/mips/beri/boot2/boot2.c#4 (text+ko) ====

@@ -27,8 +27,6 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Copyright (c) 2008 John Hay
- * Copyright (c) 2006 Warner Losh
  * Copyright (c) 1998 Robert Nordier
  * All rights reserved.
  *
@@ -44,14 +42,16 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/arm/at91/boot2/boot2.c 235988 2012-05-25 09:36:39Z gleb $");
+__FBSDID("$FreeBSD: head/sys/boot/i386/boot2/boot2.c 241301 2012-10-06 20:08:29Z avg $");
 
 #include <sys/param.h>
 #include <sys/disklabel.h>
 #include <sys/diskmbr.h>
 #include <sys/dirent.h>
+#include <sys/endian.h>
 #include <sys/reboot.h>
 
+#include <machine/bootinfo.h>
 #include <machine/elf.h>
 
 #include <stdarg.h>
@@ -59,8 +59,10 @@
 #include "cons.h"
 #include "drv.h"
 
-//#include "lib.h"
-//#include "board.h"
+#define IO_KEYBOARD	1
+#define IO_SERIAL	2
+
+#define SECOND		18	/* Circa that many ticks in a second. */
 
 #define RBX_ASKNAME	0x0	/* -a */
 #define RBX_SINGLE	0x1	/* -s */
@@ -68,363 +70,628 @@
 /* 0x3 is reserved for log2(RB_HALT). */
 /* 0x4 is reserved for log2(RB_INITNAME). */
 #define RBX_DFLTROOT	0x5	/* -r */
-/* #define RBX_KDB 	0x6	   -d */
+#define RBX_KDB 	0x6	/* -d */
 /* 0x7 is reserved for log2(RB_RDONLY). */
 /* 0x8 is reserved for log2(RB_DUMP). */
 /* 0x9 is reserved for log2(RB_MINIROOT). */
 #define RBX_CONFIG	0xa	/* -c */
 #define RBX_VERBOSE	0xb	/* -v */
-/* #define RBX_SERIAL	0xc	   -h */
-/* #define RBX_CDROM	0xd	   -C */
+#define RBX_SERIAL	0xc	/* -h */
+#define RBX_CDROM	0xd	/* -C */
 /* 0xe is reserved for log2(RB_POWEROFF). */
 #define RBX_GDB 	0xf	/* -g */
-/* #define RBX_MUTE	0x10	   -m */
+#define RBX_MUTE	0x10	/* -m */
 /* 0x11 is reserved for log2(RB_SELFTEST). */
 /* 0x12 is reserved for boot programs. */
 /* 0x13 is reserved for boot programs. */
-/* #define RBX_PAUSE	0x14	   -p */
-/* #define RBX_QUIET	0x15	   -q */
+#define RBX_PAUSE	0x14	/* -p */
+#define RBX_QUIET	0x15	/* -q */
 #define RBX_NOINTR	0x1c	/* -n */
 /* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
-/* #define RBX_DUAL	0x1d	   -D */
+#define RBX_DUAL	0x1d	/* -D */
 /* 0x1f is reserved for log2(RB_BOOTINFO). */
 
-/* pass: -a, -s, -r, -v, -g */
+/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
 #define RBX_MASK	(OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
-			OPT_SET(RBX_DFLTROOT) | \
-			OPT_SET(RBX_VERBOSE) | \
-			OPT_SET(RBX_GDB))
+			OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
+			OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
+			OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
+			OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
+			OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
 
 #define PATH_DOTCONFIG	"/boot.config"
 #define PATH_CONFIG	"/boot/config"
+#define PATH_BOOT3	"/boot/loader"
 #define PATH_KERNEL	"/boot/kernel/kernel"
 
-extern uint32_t _end;
+#define ARGS		0x900
+#define NOPT		14
+#define NDEV		3
+#define MEM_BASE	0x12
+#define MEM_EXT 	0x15
+
+#define DRV_HARD	0x80
+#define DRV_MASK	0x7f
 
-#define NOPT		6
+#define TYPE_AD		0
+#define TYPE_DA		1
+#define TYPE_MAXHARD	TYPE_DA
+#define TYPE_FD		2
 
 #define OPT_SET(opt)	(1 << (opt))
 #define OPT_CHECK(opt)	((opts) & OPT_SET(opt))
 
-static const char optstr[NOPT] = "agnrsv";
+extern uint32_t _end;
+
+static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
 static const unsigned char flags[NOPT] = {
-	RBX_ASKNAME,
-	RBX_GDB,
-	RBX_NOINTR,
-	RBX_DFLTROOT,
-	RBX_SINGLE,
-	RBX_VERBOSE
+    RBX_DUAL,
+    RBX_SERIAL,
+    RBX_ASKNAME,
+    RBX_CDROM,
+    RBX_CONFIG,
+    RBX_KDB,
+    RBX_GDB,
+    RBX_MUTE,
+    RBX_NOINTR,
+    RBX_PAUSE,
+    RBX_QUIET,
+    RBX_DFLTROOT,
+    RBX_SINGLE,
+    RBX_VERBOSE
 };
 
-unsigned board_id; /* board type to pass to kernel, if set by board_* code */
-unsigned dsk_start;
-static char cmd[512];
-static char kname[1024];
+static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
+static const unsigned char dev_maj[NDEV] = {30, 4, 2};
+
+static struct dmadat __dmadat;
+
+static struct dsk {
+    unsigned drive;
+    unsigned type;
+    unsigned unit;
+    uint8_t slice;
+    uint8_t part;
+    unsigned start;
+    int init;
+} dsk;
+static char cmd[512], cmddup[512], knamebuf[1024];
+static const char *kname;
 static uint32_t opts;
-static uint8_t dsk_meta;
+#if 0
+static int comspeed = SIOSPD;
+static struct bootinfo bootinfo;
+#endif
+static uint8_t ioctrl = IO_KEYBOARD;
 
+void exit(int);
 static void load(void);
 static int parse(void);
 static int dskread(void *, unsigned, unsigned);
-#ifdef FIXUP_BOOT_DRV
-static void fixup_boot_drv(caddr_t, int, int, int);
+static void printf(const char *,...);
+static void putchar(int);
+#if 0
+static int drvread(void *, unsigned, unsigned);
+static int keyhit(unsigned);
+#endif
+static int xputc(int);
+static int xgetc(int);
+#if 0
+static inline int getc(int);
+#endif
+
+#if 0
+void memcpy(void *, const void *, int);
 #endif
+void
+memcpy(void *dst, const void *src, int len)
+{
+    const char *s = src;
+    char *d = dst;
+
+    while (len--)
+        *d++ = *s++;
+}
 
-#include "util.c"
+static inline int
+strcmp(const char *s1, const char *s2)
+{
+    for (; *s1 == *s2 && *s1; s1++, s2++);
+    return (unsigned char)*s1 - (unsigned char)*s2;
+}
+
 #define	UFS_SMALL_CGBASE
 #include "ufsread.c"
 
-static struct dmadat __dmadat;
-
-#ifdef DEBUG
-#define	DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
-#else
-#define	DPRINTF(fmt, ...)
-#endif
-
 static inline int
 xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
 {
-	if ((size_t)fsread(inode, buf, nbyte) != nbyte)
-		return -1;
-	return 0;
+    if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
+	printf("Invalid %s\n", "format");
+	return -1;
+    }
+    return 0;
 }
 
 static inline void
-getstr(int c)
+getstr(void)
 {
-	char *s;
+    char *s;
+    int c;
 
-	s = cmd;
-	if (c == 0)
-		c = getc(10000);
-	for (;;) {
-		switch (c) {
-		case 0:
-			break;
-		case '\177':
-		case '\b':
-			if (s > cmd) {
-				s--;
-				printf("\b \b");
-			}
-			break;
-		case '\n':
-		case '\r':
-			*s = 0;
-			return;
-		default:
-			if (s - cmd < sizeof(cmd) - 1)
-				*s++ = c;
-			putchar(c);
-		}
-		c = getc(10000);
+    s = cmd;
+    for (;;) {
+	switch (c = xgetc(0)) {
+	case 0:
+	    break;
+	case '\177':
+	case '\b':
+	    if (s > cmd) {
+		s--;
+		printf("\b \b");
+	    }
+	    break;
+	case '\n':
+	case '\r':
+	    *s = 0;
+	    return;
+	default:
+	    if (s - cmd < sizeof(cmd) - 1)
+		*s++ = c;
+	    putchar(c);
 	}
+    }
 }
 
 int
 main(void)
 {
-	int autoboot, c = 0;
-	ufs_ino_t ino;
+    uint8_t autoboot;
+    ufs_ino_t ino;
+    size_t nbyte;
+
+    dmadat = &__dmadat;
+#if 0
+    /* XXXRW: more here. */
+    v86.ctl = V86_FLAGS;
+    v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
+    dsk.drive = *(uint8_t *)PTOV(ARGS);
+    dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
+    dsk.unit = dsk.drive & DRV_MASK;
+    dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1;
+    bootinfo.bi_version = BOOTINFO_VERSION;
+    bootinfo.bi_size = sizeof(bootinfo);
+#endif
+
+    /* Process configuration file */
+
+    autoboot = 1;
 
-	dmadat = &__dmadat;
-	//board_init();
+    if ((ino = lookup(PATH_CONFIG)) ||
+        (ino = lookup(PATH_DOTCONFIG))) {
+	nbyte = fsread(ino, cmd, sizeof(cmd) - 1);
+	cmd[nbyte] = '\0';
+    }
 
-	autoboot = 1;
+    if (*cmd) {
+	memcpy(cmddup, cmd, sizeof(cmd));
+	if (parse())
+	    autoboot = 0;
+	if (!OPT_CHECK(RBX_QUIET))
+	    printf("%s: %s", PATH_CONFIG, cmddup);
+	/* Do not process this command twice */
+	*cmd = 0;
+    }
 
-	/* Process configuration file */
-	if ((ino = lookup(PATH_CONFIG)) ||
-	    (ino = lookup(PATH_DOTCONFIG)))
-		fsread(ino, cmd, sizeof(cmd));
+    /*
+     * Try to exec stage 3 boot loader. If interrupted by a keypress,
+     * or in case of failure, try to load a kernel directly instead.
+     */
 
-	if (*cmd) {
-		if (parse())
-			autoboot = 0;
-		printf("%s: %s\n", PATH_CONFIG, cmd);
-		/* Do not process this command twice */
-		*cmd = 0;
+    if (!kname) {
+	kname = PATH_BOOT3;
+	if (autoboot && !keyhit(3*SECOND)) {
+	    load();
+	    kname = PATH_KERNEL;
 	}
+    }
+
+    /* Present the user with the boot2 prompt. */
 
-	if (*kname == '\0')
-		strcpy(kname, PATH_KERNEL);
+    for (;;) {
+	if (!autoboot || !OPT_CHECK(RBX_QUIET))
+	    printf("\nFreeBSD/x86 boot\n"
+		   "Default: %u:%s(%u,%c)%s\n"
+		   "boot: ",
+		   dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
+		   'a' + dsk.part, kname);
+#if 0
+	if (ioctrl & IO_SERIAL)
+	    sio_flush();
+#endif
+	if (!autoboot || keyhit(3*SECOND))
+	    getstr();
+	else if (!autoboot || !OPT_CHECK(RBX_QUIET))
+	    putchar('\n');
+	autoboot = 0;
+	if (parse())
+	    putchar('\a');
+	else
+	    load();
+    }
+}
 
-	/* Present the user with the boot2 prompt. */
-	for (;;) {
-		printf("\nDefault: %s\nboot: ", kname);
-		if (!autoboot ||
-		    (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
-			getstr(c);
-		printf("\n");
-		autoboot = 0;
-		c = 0;
-		if (parse())
-			putchar('\a');
-		else
-			load();
-	}
+/* XXX - Needed for btxld to link the boot2 binary; do not remove. */
+void
+exit(int x)
+{
 }
 
 static void
 load(void)
 {
+    union {
 	Elf64_Ehdr eh;
-	static Elf64_Phdr ep[2];
-	caddr_t p;
-	ufs_ino_t ino;
-	uint64_t addr;
-	int i, j;
-#ifdef FIXUP_BOOT_DRV
-	caddr_t staddr;
-	int klen;
+    } hdr;
+    static Elf64_Phdr ep[2];
+#if 0
+    static Elf64_Shdr es[2];
+#endif
+    caddr_t p;
+    ufs_ino_t ino;
+    uint64_t addr;
+    int i, j;
+
+    if (!(ino = lookup(kname))) {
+	if (!ls)
+	    printf("No %s\n", kname);
+	return;
+    }
+    if (xfsread(ino, &hdr, sizeof(hdr)))
+	return;
 
-	staddr = (caddr_t)0xffffffff;
-	klen = 0;
-#endif
-	if (!(ino = lookup(kname))) {
-		if (!ls)
-			printf("No %s\n", kname);
+    if (IS_ELF(hdr.eh)) {
+	fs_off = hdr.eh.e_phoff;
+	for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
+	    if (xfsread(ino, ep + j, sizeof(ep[0])))
 		return;
+	    if (ep[j].p_type == PT_LOAD)
+		j++;
 	}
-	if (xfsread(ino, &eh, sizeof(eh)))
+	for (i = 0; i < 2; i++) {
+	    p = (caddr_t)ep[i].p_paddr;
+	    fs_off = ep[i].p_offset;
+	    if (xfsread(ino, p, ep[i].p_filesz))
 		return;
-	if (!IS_ELF(eh)) {
-		printf("Invalid %s\n", "format");
+	}
+	p += roundup2(ep[1].p_memsz, PAGE_SIZE);
+#if 0
+	bootinfo.bi_symtab = VTOP(p);
+	if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
+	    fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
+		(hdr.eh.e_shstrndx + 1);
+	    if (xfsread(ino, &es, sizeof(es)))
 		return;
+	    for (i = 0; i < 2; i++) {
+		*(Elf32_Word *)p = es[i].sh_size;
+		p += sizeof(es[i].sh_size);
+		fs_off = es[i].sh_offset;
+		if (xfsread(ino, p, es[i].sh_size))
+		    return;
+		p += es[i].sh_size;
+	    }
 	}
-	fs_off = eh.e_phoff;
-	for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
-		if (xfsread(ino, ep + j, sizeof(ep[0])))
-			return;
-		if (ep[j].p_type == PT_LOAD)
-			j++;
-	}
-	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
+	addr = hdr.eh.e_entry;
+#if 0
+	bootinfo.bi_esymtab = VTOP(p);
 #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);
+    } else {
+	printf("Invalid %s\n", "format");
+	return;
+    }
+
+#if 0
+    bootinfo.bi_kernelname = VTOP(kname);
+    bootinfo.bi_bios_dev = dsk.drive;
+    __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
+	   MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part),
+	   0, 0, 0, VTOP(&bootinfo));
 #endif
-	((void(*)(int, int, int, int))addr)(opts & RBX_MASK, board_id, 0, 0);
+    ((void(*)(int, int, int, int))addr)(opts & RBX_MASK, /* board_id */ 0, 0,
+	0);
 }
 
 static int
 parse()
 {
-	char *arg = cmd;
-	char *ep, *p;
-	int c, i;
+    char *arg = cmd;
+    char *ep, *p, *q;
+#if 0
+    const char *cp;
+#endif
+    unsigned int drv;
+#if 0
+    int c, i, j;
+#else
+    int c, i;
+#endif
 
-	while ((c = *arg++)) {
-		if (c == ' ' || c == '\t' || c == '\n')
-			continue;
-		for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
-		ep = p;
-		if (*p)
-			*p++ = 0;
-		if (c == '-') {
-			while ((c = *arg++)) {
-				for (i = 0; c != optstr[i]; i++)
-					if (i == NOPT - 1)
-						return -1;
-				opts ^= OPT_SET(flags[i]);
-			}
-		} else {
-			arg--;
-			if ((i = ep - arg)) {
-				if ((size_t)i >= sizeof(kname))
-					return -1;
-				memcpy(kname, arg, i + 1);
-			}
+    while ((c = *arg++)) {
+	if (c == ' ' || c == '\t' || c == '\n')
+	    continue;
+	for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
+	ep = p;
+	if (*p)
+	    *p++ = 0;
+	if (c == '-') {
+	    while ((c = *arg++)) {
+#if 0
+		if (c == 'P') {
+		    if (*(uint8_t *)PTOV(0x496) & 0x10) {
+			cp = "yes";
+		    } else {
+			opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL);
+			cp = "no";
+		    }
+		    printf("Keyboard: %s\n", cp);
+		    continue;
+		} else if (c == 'S') {
+		    j = 0;
+		    while ((unsigned int)(i = *arg++ - '0') <= 9)
+			j = j * 10 + i;
+		    if (j > 0 && i == -'0') {
+			comspeed = j;
+			break;
+		    }
+		    /* Fall through to error below ('S' not in optstr[]). */
+		}
+#endif
+		for (i = 0; c != optstr[i]; i++)
+		    if (i == NOPT - 1)
+			return -1;
+		opts ^= OPT_SET(flags[i]);
+	    }
+	    ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
+		     OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
+#if 0
+	    if (ioctrl & IO_SERIAL) {
+	        if (sio_init(115200 / comspeed) != 0)
+		    ioctrl &= ~IO_SERIAL;
+	    }
+#endif
+	} else {
+	    for (q = arg--; *q && *q != '('; q++);
+	    if (*q) {
+		drv = -1;
+		if (arg[1] == ':') {
+		    drv = *arg - '0';
+		    if (drv > 9)
+			return (-1);
+		    arg += 2;
+		}
+		if (q - arg != 2)
+		    return -1;
+		for (i = 0; arg[0] != dev_nm[i][0] ||
+			    arg[1] != dev_nm[i][1]; i++)
+		    if (i == NDEV - 1)
+			return -1;
+		dsk.type = i;
+		arg += 3;
+		dsk.unit = *arg - '0';
+		if (arg[1] != ',' || dsk.unit > 9)
+		    return -1;
+		arg += 2;
+		dsk.slice = WHOLE_DISK_SLICE;
+		if (arg[1] == ',') {
+		    dsk.slice = *arg - '0' + 1;
+		    if (dsk.slice > NDOSPART + 1)
+			return -1;
+		    arg += 2;
 		}
-		arg = p;
+		if (arg[1] != ')')
+		    return -1;
+		dsk.part = *arg - 'a';
+		if (dsk.part > 7)
+		    return (-1);
+		arg += 2;
+		if (drv == -1)
+		    drv = dsk.unit;
+		dsk.drive = (dsk.type <= TYPE_MAXHARD
+			     ? DRV_HARD : 0) + drv;
+		dsk_meta = 0;
+	    }
+	    if ((i = ep - arg)) {
+		if ((size_t)i >= sizeof(knamebuf))
+		    return -1;
+		memcpy(knamebuf, arg, i + 1);
+		kname = knamebuf;
+	    }
 	}
-	return 0;
+	arg = p;
+    }
+    return 0;
 }
 
 static int
 dskread(void *buf, unsigned lba, unsigned nblk)
 {
-#if 0
-	struct dos_partition *dp;
-	struct disklabel *d;
-	char *sec;
-	int i;
+    struct dos_partition *dp;
+    struct disklabel *d;
+    char *sec;
+    unsigned i;
+    uint8_t sl;
 
-	if (!dsk_meta) {
-		sec = dmadat->secbuf;
-		dsk_start = 0;
-		if (drvread(sec, DOSBBSECTOR, 1))
-			return -1;
-		dp = (void *)(sec + DOSPARTOFF);
-		for (i = 0; i < NDOSPART; i++) {
-			if (dp[i].dp_typ == DOSPTYP_386BSD)
-				break;
+    if (!dsk_meta) {
+	sec = dmadat->secbuf;
+	dsk.start = 0;
+	if (drvread(sec, DOSBBSECTOR, 1))
+	    return -1;
+	dp = (void *)(sec + DOSPARTOFF);
+	sl = dsk.slice;
+	if (sl < BASE_SLICE) {
+	    for (i = 0; i < NDOSPART; i++)
+		if (dp[i].dp_typ == DOSPTYP_386BSD &&
+		    (dp[i].dp_flag & 0x80 || sl < BASE_SLICE)) {
+		    sl = BASE_SLICE + i;
+		    if (dp[i].dp_flag & 0x80 ||
+			dsk.slice == COMPATIBILITY_SLICE)
+			break;
 		}
-		if (i == NDOSPART)
-			return -1;
-		/*
-		 * Although dp_start is aligned within the disk
-		 * partition structure, DOSPARTOFF is 446, which is
-		 * only word (2) aligned, not longword (4) aligned.
-		 * Cope by using memcpy to fetch the start of this
-		 * partition.
-		 */
-		memcpy(&dsk_start, &dp[1].dp_start, 4);
-		if (drvread(sec, dsk_start + LABELSECTOR, 1))
-			return -1;
-		d = (void *)(sec + LABELOFFSET);
-		if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
-			printf("Invalid %s\n", "label");
-			return -1;
-		}
-		if (!d->d_partitions[0].p_size) {
-			printf("Invalid %s\n", "partition");
-			return -1;
-		}
-		dsk_start += d->d_partitions[0].p_offset;
-		dsk_start -= d->d_partitions[RAW_PART].p_offset;
-		dsk_meta++;
+	    if (dsk.slice == WHOLE_DISK_SLICE)
+		dsk.slice = sl;
+	}
+	if (sl != WHOLE_DISK_SLICE) {
+	    if (sl != COMPATIBILITY_SLICE)
+		dp += sl - BASE_SLICE;
+	    if (dp->dp_typ != DOSPTYP_386BSD) {
+		printf("Invalid %s\n", "slice");
+		return -1;
+	    }
+	    dsk.start = le32toh(dp->dp_start);
+	}
+	if (drvread(sec, dsk.start + LABELSECTOR, 1))
+		return -1;
+	d = (void *)(sec + LABELOFFSET);
+	if (le32toh(d->d_magic) != DISKMAGIC ||
+	    le32toh(d->d_magic2) != DISKMAGIC) {
+	    if (dsk.part != RAW_PART) {
+		printf("Invalid %s\n", "label");
+		return -1;
+	    }
+	} else {
+	    if (!dsk.init) {
+		if (le16toh(d->d_type) == DTYPE_SCSI)
+		    dsk.type = TYPE_DA;
+		dsk.init++;
+	    }
+	    if (dsk.part >= le16toh(d->d_npartitions) ||
+		!(le32toh(d->d_partitions[dsk.part].p_size))) {
+		printf("Invalid %s\n", "partition");
+		return -1;
+	    }
+	    dsk.start += le32toh(d->d_partitions[dsk.part].p_offset);
+	    dsk.start -= le32toh(d->d_partitions[RAW_PART].p_offset);
 	}
-#endif
-	return drvread(buf, dsk_start + lba, 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)
+printf(const char *fmt,...)
 {
-	const u_int8_t op[] = "ufs:ROOTDEVNAME";
-	const u_int8_t op2[] = "ufs:ad0";
-	u_int8_t *p, *ps;
+    va_list ap;
+    static char buf[10];
+    char *s;
+    unsigned u;
+    int c;
 
-	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';
-		}
+    va_start(ap, fmt);
+    while ((c = *fmt++)) {
+	if (c == '%') {
+	    c = *fmt++;
+	    switch (c) {
+	    case 'c':
+		putchar(va_arg(ap, int));
+		continue;
+	    case 's':
+		for (s = va_arg(ap, char *); *s; s++)
+		    putchar(*s);
+		continue;
+	    case 'u':
+		u = va_arg(ap, unsigned);
+		s = buf;
+		do
+		    *s++ = '0' + u % 10U;
+		while (u /= 10U);
+		while (--s >= buf)
+		    putchar(*s);
+		continue;
+	    }
 	}
-	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);
+	putchar(c);
+    }
+    va_end(ap);
+    return;
+}
+
+static void
+putchar(int c)
+{
+    if (c == '\n')
+	xputc('\r');
+    xputc(c);
+}
+
+#if 0
+static int
+drvread(void *buf, unsigned lba, unsigned nblk)
+{
+    static unsigned c = 0x2d5c7c2f;
+
+    if (!OPT_CHECK(RBX_QUIET))
+	printf("%c\b", c = c << 8 | c >> 24);
+    v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
+    v86.addr = XREADORG;		/* call to xread in boot1 */
+    v86.es = VTOPSEG(buf);
+    v86.eax = lba;
+    v86.ebx = VTOPOFF(buf);
+    v86.ecx = lba >> 16;
+    v86.edx = nblk << 8 | dsk.drive;
+    v86int();
+    v86.ctl = V86_FLAGS;
+    if (V86_CY(v86.efl)) {
+	printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
+	return -1;
+    }
+    return 0;
+}
+
+static int
+keyhit(unsigned ticks)
+{
+    uint32_t t0, t1;
+
+    if (OPT_CHECK(RBX_NOINTR))
+	return 0;
+    t0 = 0;
+    for (;;) {
+	if (xgetc(1))
+	    return 1;
+	t1 = *(uint32_t *)PTOV(0x46c);
+	if (!t0)
+	    t0 = t1;
+	if ((uint32_t)(t1 - t0) >= ticks)
+	    return 0;
+    }
+}
+#endif
+
+static int
+xputc(int c)
+{
+    if (ioctrl & IO_KEYBOARD)
+	putc(c);
+#if 0
+    if (ioctrl & IO_SERIAL)
+	sio_putc(c);
+#endif
+    return c;
 }
+
+static int
+xgetc(int fn)
+{
+    if (OPT_CHECK(RBX_NOINTR))
+	return 0;
+    for (;;) {
+	if (ioctrl & IO_KEYBOARD && getc(1))
+	    return fn ? 1 : getc(0);
+#if 0
+	if (ioctrl & IO_SERIAL && sio_ischar())
+	    return fn ? 1 : sio_getc();
 #endif
+	if (fn)
+	    return 0;
+    }
+}

==== //depot/projects/ctsrd/beribsd/src/sys/boot/mips/beri/boot2/cons.h#2 (text+ko) ====

@@ -32,6 +32,7 @@
 #define	_CONS_H_
 
 int	getc(int);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303260925.r2Q9PAhe028266>