Add a prompt to specify a kernel filename to be loaded on bootloader.

This commit is contained in:
tsutsui 2004-04-10 12:30:26 +00:00
parent f3c773016a
commit 69e737058e
4 changed files with 225 additions and 59 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.6 2004/01/27 21:03:18 cdi Exp $ # $NetBSD: Makefile,v 1.7 2004/04/10 12:30:26 tsutsui Exp $
NOMAN= # defined NOMAN= # defined
@ -68,7 +68,7 @@ LDSCRIPT?= ${MIPS}/conf/stand.ldscript
PROG= boot PROG= boot
# common sources # common sources
SRCS+= start.S boot.c devopen.c conf.c clock.c bootinfo.c SRCS+= start.S boot.c devopen.c conf.c clock.c bootinfo.c
SRCS+= prf.c com.c cons.c ns16550.c pciide.c wdc.c wd.c SRCS+= prf.c com.c cons.c ns16550.c pciide.c tgets.c wdc.c wd.c
SRCS+= vers.c SRCS+= vers.c
CLEANFILES+= vers.c CLEANFILES+= vers.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: boot.c,v 1.3 2004/01/07 12:43:44 cdi Exp $ */ /* $NetBSD: boot.c,v 1.4 2004/04/10 12:30:26 tsutsui Exp $ */
/*- /*-
* Copyright (c) 2003 The NetBSD Foundation, Inc. * Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -79,6 +79,7 @@
#include <lib/libkern/libkern.h> #include <lib/libkern/libkern.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/boot_flag.h>
#include <sys/exec.h> #include <sys/exec.h>
#include <sys/exec_elf.h> #include <sys/exec_elf.h>
@ -109,7 +110,8 @@ void start(void);
static char *bootstring; static char *bootstring;
static int patch_bootstring (char *bootspec); static int patch_bootstring (char *bootspec);
static int get_bsdbootname (char **dev, char **name, char **kname); static int get_bsdbootname(char **, char **);
static int parse_bootname(char *, int, char **, char **);
static int prominit (unsigned int memsize); static int prominit (unsigned int memsize);
static int print_banner (unsigned int memsize); static int print_banner (unsigned int memsize);
@ -189,53 +191,120 @@ patch_bootstring(bootspec)
/* /*
* Extract NetBSD boot specification * Extract NetBSD boot specification
*/ */
int static int
get_bsdbootname(dev, name, kname) get_bsdbootname(dev, kname)
char **dev; char **dev;
char **name;
char **kname; char **kname;
{ {
char *spec; int len, error;
char *bootstr_dev, *bootstr_kname;
char *prompt_dev, *prompt_kname;
char *ptr, *spec;
char c, namebuf[PATH_MAX];
*dev = NULL; bootstr_dev = prompt_dev = NULL;
*name = NULL; bootstr_kname = prompt_kname = NULL;
*kname = NULL;
if ( (spec = strstr(bootstring, "nbsd=")) != NULL) {
int len;
char *ptr = strchr(spec, ' ');
/* first, get bootname from bootstrings */
if ((spec = strstr(bootstring, "nbsd=")) != NULL) {
ptr = strchr(spec, ' ');
spec += 5; /* skip 'nbsd=' */ spec += 5; /* skip 'nbsd=' */
len = (ptr == NULL) ? strlen(spec) : ptr - spec; len = (ptr == NULL) ? strlen(spec) : ptr - spec;
if (len > 0) { if (len > 0) {
char *devname = alloc(len + 1); if (parse_bootname(spec, len,
if (devname != NULL) { &bootstr_dev, &bootstr_kname))
memcpy(devname, spec, len); return 1;
devname[len] = '\0';
if ( (ptr = memchr(devname,':',len)) != NULL) {
/* wdXX:kernel */
*ptr = '\0';
*dev = devname;
if (*++ptr)
*kname = ptr;
devname = alloc(len + 1);
if (devname != NULL) {
memcpy(devname, spec, len);
devname[len] = '\0';
}
}
*name = devname;
return (0);
}
} }
} }
return (1); DPRINTF(("bootstr_dev = %s, bootstr_kname = %s\n",
bootstr_dev ? bootstr_dev : "<NULL>",
bootstr_kname ? bootstr_kname : "<NULL>"));
spec = NULL;
len = 0;
memset(namebuf, 0, sizeof namebuf);
printf("Boot [%s:%s]: ",
bootstr_dev ? bootstr_dev : DEFBOOTDEV,
bootstr_kname ? bootstr_kname : DEFKERNELNAME);
if (tgets(namebuf) == -1)
printf("\n");
ptr = namebuf;
while ((c = *ptr) != '\0') {
while (c == ' ')
c = *++ptr;
if (c == '\0')
break;
if (c == '-') {
while ((c = *++ptr) && c != ' ')
;
#if notyet
BOOT_FLAG(c, boothowto);
#endif
} else {
spec = ptr;
while ((c = *++ptr) && c != ' ')
;
if (c)
*ptr++ = '\0';
len = strlen(spec);
}
}
if (len > 0) {
if (parse_bootname(spec, len, &prompt_dev, &prompt_kname))
return 1;
}
DPRINTF(("prompt_dev = %s, prompt_kname = %s\n",
prompt_dev ? prompt_dev : "<NULL>",
prompt_kname ? prompt_kname : "<NULL>"));
if (prompt_dev)
*dev = prompt_dev;
else
*dev = bootstr_dev;
if (prompt_kname)
*kname = prompt_kname;
else
*kname = bootstr_kname;
DPRINTF(("dev = %s, kname = %s\n",
*dev ? *dev : "<NULL>",
*kname ? *kname : "<NULL>"));
return 0;
}
static int
parse_bootname(spec, len, dev, kname)
char *spec;
int len;
char **dev;
char **kname;
{
char *bootname, *ptr;
bootname = alloc(len + 1);
if (bootname == NULL)
return 1;
memcpy(bootname, spec, len);
bootname[len] = '\0';
if ((ptr = memchr(bootname, ':', len)) != NULL) {
/* "wdXX:kernel" */
*ptr = '\0';
*dev = bootname;
if (*++ptr)
*kname = ptr;
} else
/* "kernel" */
*kname = bootname;
return 0;
} }
/* /*
@ -272,7 +341,7 @@ int
main(memsize) main(memsize)
unsigned int memsize; unsigned int memsize;
{ {
char *name, **namep, *dev, *kernel, *spec, *bi_addr; char **namep, *dev, *kernel, *bi_addr;
char bootpath[PATH_MAX]; char bootpath[PATH_MAX];
int win; int win;
u_long marks[MARK_MAX]; u_long marks[MARK_MAX];
@ -295,31 +364,30 @@ main(memsize)
print_banner(memsize); print_banner(memsize);
memset(marks, 0, sizeof marks); memset(marks, 0, sizeof marks);
get_bsdbootname(&dev, &name, &kernel); get_bsdbootname(&dev, &kernel);
if (kernel != NULL) { if (kernel != NULL) {
DPRINTF(("kernel: %s\n", kernel)); DPRINTF(("kernel: %s\n", kernel));
patch_bootstring(name); kernelnames[0] = kernel;
win = (loadfile(name, marks, LOAD_KERNEL) == 0); kernelnames[1] = NULL;
} else { } else {
win = 0;
DPRINTF(("kernel: NULL\n")); DPRINTF(("kernel: NULL\n"));
DPRINTF(("Kernel names: %p\n", kernelnames)); }
for (namep = kernelnames, win = 0;
(*namep != NULL) && !win;
namep++) {
kernel = *namep;
bootpath[0] = '\0'; win = 0;
DPRINTF(("Kernel names: %p\n", kernelnames));
for (namep = kernelnames, win = 0; (*namep != NULL) && !win; namep++) {
kernel = *namep;
strcpy(bootpath, (dev != NULL) ? dev : "wd0a"); bootpath[0] = '\0';
strcat(bootpath, ":");
strcat(bootpath, kernel);
printf("Loading: %s\n", bootpath); strcpy(bootpath, dev ? dev : DEFBOOTDEV);
patch_bootstring(bootpath); strcat(bootpath, ":");
win = (loadfile(bootpath, marks, LOAD_ALL) != -1); strcat(bootpath, kernel);
}
printf("Loading: %s\n", bootpath);
patch_bootstring(bootpath);
win = (loadfile(bootpath, marks, LOAD_ALL) != -1);
} }
if (win) { if (win) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: boot.h,v 1.1 2003/06/25 17:24:22 cdi Exp $ */ /* $NetBSD: boot.h,v 1.2 2004/04/10 12:30:26 tsutsui Exp $ */
/*- /*-
* Copyright (c) 2003 The NetBSD Foundation, Inc. * Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -40,6 +40,7 @@
#endif #endif
#define MAXDEVNAME 16 #define MAXDEVNAME 16
#define DEFBOOTDEV "wd0a"
#define DEFKERNELNAME kernelnames[0] #define DEFKERNELNAME kernelnames[0]
extern char *kernelnames[]; extern char *kernelnames[];
@ -74,3 +75,5 @@ int wdclose __P((struct open_file *));
*/ */
int devparse (const char *fname, int *dev, u_int8_t *unit, int devparse (const char *fname, int *dev, u_int8_t *unit,
u_int8_t *part, const char **file); u_int8_t *part, const char **file);
int tgets(char *);

View File

@ -0,0 +1,95 @@
/* $NetBSD: tgets.c,v 1.1 2004/04/10 12:30:26 tsutsui Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)gets.c 8.1 (Berkeley) 6/11/93
*/
#include <lib/libsa/stand.h>
#include "boot.h"
#define USE_SCAN
int
tgets(buf)
char *buf;
{
int c;
char *lp;
#ifdef USE_SCAN
int i;
#define SCANWAIT 10000
#define PWAIT 500
for (i = 0; i < PWAIT; i++) {
if ((c = cnscan()) != -1)
goto next;
delay(SCANWAIT / 32); /* XXX */
}
return (-1);
next:
#else
c = getchar();
#endif
for (lp = buf;; c = getchar()) {
switch (c & 0177) {
case '\n':
case '\r':
*lp = '\0';
putchar('\n');
return 0;
case '\b':
case '\177':
if (lp > buf) {
lp--;
putchar('\b');
putchar(' ');
putchar('\b');
}
break;
case 'r' & 037: {
char *p;
putchar('\n');
for (p = buf; p < lp; ++p)
putchar(*p);
break;
}
case 'u' & 037:
case 'w' & 037:
lp = buf;
putchar('\n');
break;
default:
*lp++ = c;
putchar(c);
}
}
}