Change "Boot:" prompt option parsing to be more in line with the default
(no prompt) behaviour - it is now possible to "boot net:dhcp -a" and then say "disk" at the "Boot:" prompt - result should be equivalent to "boot disk", but the ofwboot was loaded from the network. While there fix a few minor errors, and one significant: if the "a" partition should not start at the beginning of the disk, the previous code failed to read a disklabel. Use the "c" partition now to find the disklabel now always.
This commit is contained in:
parent
8b937dec65
commit
e3218c4391
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: boot.c,v 1.14 2007/06/05 08:52:20 martin Exp $ */
|
||||
/* $NetBSD: boot.c,v 1.15 2007/09/16 23:12:31 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1999 Eduardo E. Horvath. All rights reserved.
|
||||
@ -111,10 +111,12 @@ prom2boot(char *dev)
|
||||
#endif
|
||||
|
||||
static int
|
||||
bootoptions(const char *ap, char *kernel, char *options)
|
||||
bootoptions(const char *ap, char *loaddev, char *kernel, char *options)
|
||||
{
|
||||
int v = 0;
|
||||
const char *cp;
|
||||
const char *start1 = NULL, *end1 = NULL, *start2 = NULL, *end2 = NULL;
|
||||
const char *path;
|
||||
char partition;
|
||||
|
||||
*kernel = '\0';
|
||||
*options = '\0';
|
||||
@ -127,18 +129,53 @@ bootoptions(const char *ap, char *kernel, char *options)
|
||||
ap++;
|
||||
}
|
||||
|
||||
cp = ap;
|
||||
if (*ap != '-') {
|
||||
start1 = ap;
|
||||
while (*ap != '\0' && *ap != ' ') {
|
||||
ap++;
|
||||
}
|
||||
|
||||
memcpy(kernel, cp, (ap - cp));
|
||||
kernel[ap - cp] = '\0';
|
||||
end1 = ap;
|
||||
|
||||
while (*ap != '\0' && *ap == ' ') {
|
||||
ap++;
|
||||
}
|
||||
|
||||
if (*ap != '-') {
|
||||
start2 = ap;
|
||||
while (*ap != '\0' && *ap != ' ') {
|
||||
ap++;
|
||||
}
|
||||
end2 = ap;
|
||||
while (*ap != '\0' && *ap == ' ') {
|
||||
ap++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (end2 == start2) {
|
||||
start2 = end2 = NULL;
|
||||
}
|
||||
if (end1 == start1) {
|
||||
start1 = end1 = NULL;
|
||||
}
|
||||
|
||||
if (start1 == NULL) {
|
||||
/* only options */
|
||||
} else if (start2 == NULL) {
|
||||
memcpy(kernel, start1, (end1 - start1));
|
||||
kernel[end1 - start1] = '\0';
|
||||
path = filename(kernel, &partition);
|
||||
if (path && path != kernel) {
|
||||
/* copy device part */
|
||||
memcpy(loaddev, kernel, path-kernel);
|
||||
loaddev[path-kernel] = '\0';
|
||||
/* and kernel path */
|
||||
strcpy(kernel, path);
|
||||
}
|
||||
} else {
|
||||
memcpy(loaddev, start1, (end1-start1));
|
||||
loaddev[end1-start1] = '\0';
|
||||
memcpy(kernel, start2, (end2 - start2));
|
||||
kernel[end2 - start2] = '\0';
|
||||
}
|
||||
|
||||
strcpy(options, ap);
|
||||
@ -160,7 +197,8 @@ bootoptions(const char *ap, char *kernel, char *options)
|
||||
debug = 1;
|
||||
}
|
||||
|
||||
DPRINTF(("bootoptions: kernel='%s', options='%s'\n", kernel, options));
|
||||
DPRINTF(("bootoptions: device='%s', kernel='%s', options='%s'\n",
|
||||
loaddev, kernel, options));
|
||||
return (v);
|
||||
}
|
||||
|
||||
@ -318,6 +356,23 @@ start_kernel(char *kernel, char *bootline, void *ofw)
|
||||
(void)printf("Failed to load '%s'.\n", kernel);
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf( "enter a special command\n"
|
||||
" halt\n"
|
||||
" exit\n"
|
||||
" to return to OpenFirmware\n"
|
||||
" ?\n"
|
||||
" help\n"
|
||||
" to display this message\n"
|
||||
"or a boot specification:\n"
|
||||
" [device] [kernel] [options]\n"
|
||||
"\n"
|
||||
"for example:\n"
|
||||
" disk:a netbsd -s\n");
|
||||
}
|
||||
|
||||
void
|
||||
main(void *ofw)
|
||||
{
|
||||
@ -331,12 +386,11 @@ main(void *ofw)
|
||||
prom_init();
|
||||
|
||||
printf("\r>> %s, Revision %s\n", bootprog_name, bootprog_rev);
|
||||
printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
|
||||
DPRINTF((">> (%s, %s)\n", bootprog_maker, bootprog_date));
|
||||
|
||||
/* Figure boot arguments */
|
||||
boothowto = bootoptions(prom_getbootargs(), kernel, bootline);
|
||||
strncpy(bootdev, prom_getbootpath(), sizeof(bootdev) - 1);
|
||||
strncpy(bootline, prom_getbootargs(), sizeof(bootline) - 1);
|
||||
boothowto = bootoptions(prom_getbootargs(), bootdev, kernel, bootline);
|
||||
|
||||
for (;; *kernel = '\0') {
|
||||
if (boothowto & RB_ASKNAME) {
|
||||
@ -345,12 +399,19 @@ main(void *ofw)
|
||||
printf("Boot: ");
|
||||
gets(cmdline);
|
||||
|
||||
boothowto = bootoptions(cmdline, kernel, bootline);
|
||||
boothowto |= RB_ASKNAME;
|
||||
|
||||
if (!strcmp(kernel,"exit") || !strcmp(kernel,"halt")) {
|
||||
if (!strcmp(cmdline,"exit") ||
|
||||
!strcmp(cmdline,"halt")) {
|
||||
prom_halt();
|
||||
} else if (!strcmp(cmdline, "?") ||
|
||||
!strcmp(cmdline, "help")) {
|
||||
help();
|
||||
continue;
|
||||
}
|
||||
|
||||
boothowto = bootoptions(cmdline, bootdev, kernel,
|
||||
bootline);
|
||||
boothowto |= RB_ASKNAME;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (*kernel == '\0') {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: boot.h,v 1.2 2007/06/05 08:52:20 martin Exp $ */
|
||||
/* $NetBSD: boot.h,v 1.3 2007/09/16 23:12:32 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||
@ -72,4 +72,7 @@ extern u_int get_cpuid(void);
|
||||
#define LOADFILE_MMU_ALLOCATOR 0x2
|
||||
extern void loadfile_set_allocator(int);
|
||||
|
||||
/* ofdev.c */
|
||||
char *filename(char*, char*);
|
||||
|
||||
#endif /* _BOOT_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ofdev.c,v 1.14 2007/09/14 09:26:46 martin Exp $ */
|
||||
/* $NetBSD: ofdev.c,v 1.15 2007/09/16 23:12:32 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
|
||||
@ -53,6 +53,7 @@
|
||||
#include <machine/promlib.h>
|
||||
|
||||
#include "ofdev.h"
|
||||
#include "boot.h"
|
||||
|
||||
extern char bootdev[];
|
||||
|
||||
@ -63,7 +64,7 @@ extern char bootdev[];
|
||||
*
|
||||
*/
|
||||
|
||||
static char *
|
||||
char *
|
||||
filename(char *str, char *ppart)
|
||||
{
|
||||
char *cp, *lp;
|
||||
@ -81,10 +82,8 @@ filename(char *str, char *ppart)
|
||||
*cp = 0;
|
||||
/* ...look whether there is a device with this name */
|
||||
dhandle = prom_finddevice(str);
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("filename: prom_finddevice(%s) returned %x\n",
|
||||
str, dhandle);
|
||||
#endif
|
||||
DPRINTF(("filename: prom_finddevice(%s) returned %x\n",
|
||||
str, dhandle));
|
||||
*cp = savec;
|
||||
if (dhandle == -1) {
|
||||
/*
|
||||
@ -93,10 +92,8 @@ filename(char *str, char *ppart)
|
||||
*/
|
||||
if (!strcmp(devtype, "block")) {
|
||||
/* search for arguments */
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("filename: hunting for arguments "
|
||||
"in %s\n", str);
|
||||
#endif
|
||||
DPRINTF(("filename: hunting for arguments "
|
||||
"in %s\n", str));
|
||||
for (cp = lp; ; ) {
|
||||
cp--;
|
||||
if (cp < str ||
|
||||
@ -113,16 +110,12 @@ filename(char *str, char *ppart)
|
||||
*--cp = '\0';
|
||||
}
|
||||
}
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("filename: found %s\n",lp);
|
||||
#endif
|
||||
DPRINTF(("filename: found %s\n",lp));
|
||||
return lp;
|
||||
} else if (_prom_getprop(dhandle, "device_type", devtype, sizeof devtype) < 0)
|
||||
devtype[0] = 0;
|
||||
}
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("filename: not found\n",lp);
|
||||
#endif
|
||||
DPRINTF(("filename: not found\n",lp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -296,9 +289,7 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
|
||||
npp = &lp->d_partitions[i];
|
||||
npp->p_offset = spp->sdkp_cyloffset * secpercyl;
|
||||
npp->p_size = spp->sdkp_nsectors;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("partition %d start %x size %x\n", i, (int)npp->p_offset, (int)npp->p_size);
|
||||
#endif
|
||||
DPRINTF(("partition %d start %x size %x\n", i, (int)npp->p_offset, (int)npp->p_size));
|
||||
if (npp->p_size == 0) {
|
||||
npp->p_fstype = FS_UNUSED;
|
||||
} else {
|
||||
@ -317,9 +308,7 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
|
||||
|
||||
lp->d_checksum = 0;
|
||||
lp->d_checksum = dkcksum(lp);
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("disklabel_sun_to_bsd: success!\n");
|
||||
#endif
|
||||
DPRINTF(("disklabel_sun_to_bsd: success!\n"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -357,9 +346,7 @@ search_label(struct of_dev *devp, u_long off, char *buf,
|
||||
if (dkcksum(dlp))
|
||||
return ("NetBSD disk label corrupted");
|
||||
*lp = *dlp;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("search_label: found NetBSD label\n");
|
||||
#endif
|
||||
DPRINTF(("search_label: found NetBSD label\n"));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -384,18 +371,16 @@ devopen(struct open_file *of, const char *name, char **file)
|
||||
struct disklabel label;
|
||||
} b;
|
||||
struct disklabel label;
|
||||
int handle, part;
|
||||
int handle, part, try = 0;
|
||||
size_t read;
|
||||
char *errmsg = NULL;
|
||||
char *errmsg = NULL, *pp, savedpart = 0;
|
||||
int error = 0;
|
||||
|
||||
if (ofdev.handle != -1)
|
||||
panic("devopen");
|
||||
if (of->f_flags != F_READ)
|
||||
return EPERM;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: you want %s\n", name);
|
||||
#endif
|
||||
DPRINTF(("devopen: you want %s\n", name));
|
||||
strcpy(fname, name);
|
||||
cp = filename(fname, &partition);
|
||||
if (cp) {
|
||||
@ -417,46 +402,58 @@ devopen(struct open_file *of, const char *name, char **file)
|
||||
if (b.buf[0] != '/')
|
||||
strcat(opened_name, "/");
|
||||
strcat(opened_name, b.buf);
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: trying %s\n", fname);
|
||||
#endif
|
||||
DPRINTF(("devopen: trying %s\n", fname));
|
||||
if ((handle = prom_finddevice(fname)) == -1)
|
||||
return ENOENT;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: found %s\n", fname);
|
||||
#endif
|
||||
DPRINTF(("devopen: found %s\n", fname));
|
||||
if (_prom_getprop(handle, "name", b.buf, sizeof b.buf) < 0)
|
||||
return ENXIO;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: %s is called %s\n", fname, b.buf);
|
||||
#endif
|
||||
DPRINTF(("devopen: %s is called %s\n", fname, b.buf));
|
||||
floppyboot = !strcmp(b.buf, "floppy");
|
||||
if (_prom_getprop(handle, "device_type", b.buf, sizeof b.buf) < 0)
|
||||
return ENXIO;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: %s is a %s device\n", fname, b.buf);
|
||||
#endif
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: opening %s\n", fname);
|
||||
#endif
|
||||
DPRINTF(("devopen: %s is a %s device\n", fname, b.buf));
|
||||
if (!strcmp(b.buf, "block")) {
|
||||
pp = strrchr(fname, ':');
|
||||
if (pp && pp[1] >= 'a' && pp[1] <= 'f' && pp[2] == 0) {
|
||||
savedpart = pp[1];
|
||||
} else {
|
||||
savedpart = 'a';
|
||||
pp = fname + strlen(fname);
|
||||
pp[0] = ':';
|
||||
pp[2] = '\0';
|
||||
}
|
||||
pp[1] = 'c';
|
||||
DPRINTF(("devopen: replacing by whole disk device %s\n",
|
||||
fname));
|
||||
}
|
||||
|
||||
open_again:
|
||||
DPRINTF(("devopen: opening %s\n", fname));
|
||||
if ((handle = prom_open(fname)) == -1) {
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: open of %s failed\n", fname);
|
||||
#endif
|
||||
DPRINTF(("devopen: open of %s failed\n", fname));
|
||||
if (pp && savedpart) {
|
||||
if (try == 0) {
|
||||
pp[0] = '\0';
|
||||
try = 1;
|
||||
} else {
|
||||
pp[0] = ':';
|
||||
pp[1] = savedpart;
|
||||
pp = NULL;
|
||||
savedpart = '\0';
|
||||
}
|
||||
goto open_again;
|
||||
}
|
||||
return ENXIO;
|
||||
}
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: %s is now open\n", fname);
|
||||
#endif
|
||||
DPRINTF(("devopen: %s is now open\n", fname));
|
||||
bzero(&ofdev, sizeof ofdev);
|
||||
ofdev.handle = handle;
|
||||
if (!strcmp(b.buf, "block")) {
|
||||
ofdev.type = OFDEV_DISK;
|
||||
ofdev.bsize = DEV_BSIZE;
|
||||
/* First try to find a disklabel without MBR partitions */
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: trying to read disklabel\n");
|
||||
#endif
|
||||
DPRINTF(("devopen: trying to read disklabel\n"));
|
||||
if (strategy(&ofdev, F_READ,
|
||||
LABELSECTOR, DEV_BSIZE, b.buf, &read) != 0
|
||||
|| read != DEV_BSIZE
|
||||
@ -473,27 +470,33 @@ devopen(struct open_file *of, const char *name, char **file)
|
||||
}
|
||||
|
||||
if (error == ERDLAB) {
|
||||
if (partition)
|
||||
/* User specified a parititon, but there is none */
|
||||
goto bad;
|
||||
/* No, label, just use complete disk */
|
||||
ofdev.partoff = 0;
|
||||
if (pp && savedpart) {
|
||||
pp[1] = savedpart;
|
||||
prom_close(handle);
|
||||
if ((handle = prom_open(fname)) == -1) {
|
||||
DPRINTF(("devopen: open of %s failed\n",
|
||||
fname));
|
||||
return ENXIO;
|
||||
}
|
||||
ofdev.handle = handle;
|
||||
DPRINTF(("devopen: back to original device %s\n",
|
||||
fname));
|
||||
}
|
||||
} else {
|
||||
part = partition ? partition - 'a' : 0;
|
||||
ofdev.partoff = label.d_partitions[part].p_offset;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: setting partition %d offset %x\n",
|
||||
part, ofdev.partoff);
|
||||
#endif
|
||||
DPRINTF(("devopen: setting partition %d offset %x\n",
|
||||
part, ofdev.partoff));
|
||||
if (label.d_partitions[part].p_fstype == FS_RAID) {
|
||||
ofdev.partoff += RF_PROTECTED_SECTORS;
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: found RAID partition, "
|
||||
"adjusting offset to %x\n", ofdev.partoff);
|
||||
#endif
|
||||
DPRINTF(("devopen: found RAID partition, "
|
||||
"adjusting offset to %x\n", ofdev.partoff));
|
||||
}
|
||||
}
|
||||
|
||||
nfsys = 0;
|
||||
of->f_dev = ofdevsw;
|
||||
of->f_devdata = &ofdev;
|
||||
#ifdef SPARC_BOOT_UFS
|
||||
@ -503,9 +506,7 @@ devopen(struct open_file *of, const char *name, char **file)
|
||||
bcopy(&file_system_cd9660, &file_system[nfsys++],
|
||||
sizeof file_system[0]);
|
||||
#endif
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: return 0\n");
|
||||
#endif
|
||||
DPRINTF(("devopen: return 0\n"));
|
||||
return 0;
|
||||
}
|
||||
#ifdef NETBOOT
|
||||
@ -522,9 +523,7 @@ devopen(struct open_file *of, const char *name, char **file)
|
||||
#endif
|
||||
error = EFTYPE;
|
||||
bad:
|
||||
#ifdef NOTDEF_DEBUG
|
||||
printf("devopen: error %d, cannot open device\n", error);
|
||||
#endif
|
||||
DPRINTF(("devopen: error %d, cannot open device\n", error));
|
||||
prom_close(handle);
|
||||
ofdev.handle = -1;
|
||||
return error;
|
||||
|
Loading…
Reference in New Issue
Block a user