Add a -e (edit) option to allow the bootstrap options of an installed

bootstrap or a file containing such a bootstrap to be changed/displayed.
In particular this will (soon) let you modify the parameters for pxeboot.
This commit is contained in:
dsl 2005-11-11 21:09:50 +00:00
parent e68103df2a
commit 8c893c964a
5 changed files with 250 additions and 92 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: i386.c,v 1.18 2004/08/16 05:57:52 yamt Exp $ */
/* $NetBSD: i386.c,v 1.19 2005/11/11 21:09:50 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: i386.c,v 1.18 2004/08/16 05:57:52 yamt Exp $");
__RCSID("$NetBSD: i386.c,v 1.19 2005/11/11 21:09:50 dsl Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -58,6 +58,101 @@ __RCSID("$NetBSD: i386.c,v 1.18 2004/08/16 05:57:52 yamt Exp $");
#include "installboot.h"
#define nelem(x) (sizeof (x)/sizeof *(x))
static const char *const console_names[] = {
"pc", "com0", "com1", "com2", "com3",
"com0kbd", "com1kbd", "com2kbd", "com3kbd",
NULL };
static void
show_i386_boot_params(struct x86_boot_params *bpp)
{
uint32_t i;
printf("Boot options: ");
printf("timeout %d, ", le32toh(bpp->bp_timeout));
printf("flags %x, ", le32toh(bpp->bp_flags));
printf("speed %d, ", le32toh(bpp->bp_conspeed));
printf("ioaddr %x, ", le32toh(bpp->bp_consaddr));
i = le32toh(bpp->bp_consdev);
if (i < nelem(console_names) - 1)
printf("console %s\n", console_names[i]);
else
printf("console %d\n", i);
if (bpp->bp_keymap[0])
printf(" keymap %s\n", bpp->bp_keymap);
}
static int
update_i386_boot_params(ib_params *params, struct x86_boot_params *bpp)
{
struct x86_boot_params bp;
int bplen;
int i;
bplen = le32toh(bpp->bp_length);
if (bplen > sizeof bp)
/* Ignore pad space in bootxx */
bplen = sizeof bp;
/* Take (and update) local copy so we handle size mismatches */
memset(&bp, 0, sizeof bp);
memcpy(&bp, bpp, bplen);
if (params->flags & IB_TIMEOUT)
bp.bp_timeout = htole32(params->timeout);
if (params->flags & IB_RESETVIDEO)
bp.bp_flags ^= htole32(X86_BP_FLAGS_RESET_VIDEO);
if (params->flags & IB_CONSPEED)
bp.bp_conspeed = htole32(params->conspeed);
if (params->flags & IB_CONSADDR)
bp.bp_consaddr = htole32(params->consaddr);
if (params->flags & IB_CONSOLE) {
for (i = 0; ; i++) {
if (console_names[i] == NULL) {
warnx("invalid console name, valid names are:");
fprintf(stderr, "\t%s", console_names[0]);
for (i = 1; console_names[i] != NULL; i++)
fprintf(stderr, ", %s", console_names[i]);
fprintf(stderr, "\n");
return 1;
}
if (strcmp(console_names[i], params->console) == 0)
break;
}
bp.bp_consdev = htole32(i);
}
if (params->flags & IB_PASSWORD) {
if (params->password[0]) {
MD5_CTX md5ctx;
MD5Init(&md5ctx);
MD5Update(&md5ctx, params->password,
strlen(params->password));
MD5Final(bp.bp_password, &md5ctx);
bp.bp_flags |= htole32(X86_BP_FLAGS_PASSWORD);
} else {
memset(&bp.bp_password, 0, sizeof bp.bp_password);
bp.bp_flags &= ~htole32(X86_BP_FLAGS_PASSWORD);
}
}
if (params->flags & IB_KEYMAP)
strlcpy(bp.bp_keymap, params->keymap, sizeof bp.bp_keymap);
if (params->flags & (IB_NOWRITE | IB_VERBOSE))
show_i386_boot_params(&bp);
/* Check we aren't trying to set anything we can't save */
if (bplen < sizeof bp && memcmp((char *)&bp + bplen,
(char *)&bp + bplen + 1,
sizeof bp - bplen - 1) != 0) {
warnx("Patch area in stage1 bootstrap is too small");
return 1;
}
memcpy(bpp, &bp, bplen);
return 0;
}
int
i386_setboot(ib_params *params)
{
@ -66,8 +161,7 @@ i386_setboot(ib_params *params)
u_int bootstrapsize;
ssize_t rv;
uint32_t magic;
struct x86_boot_params bp, *bpp;
int bplen;
struct x86_boot_params *bpp;
struct mbr_sector mbr;
assert(params != NULL);
@ -188,57 +282,8 @@ i386_setboot(ib_params *params)
* See sys/arch/i386/stand/bootxx/bootxx.S for more information.
*/
bpp = (void *)(bootstrapbuf + 512 * 2 + 8);
bplen = le32toh(bpp->bp_length);
if (bplen > sizeof bp)
/* Ignore pad space in bootxx */
bplen = sizeof bp;
/* Take (and update) local copy so we handle size mismatches */
memset(&bp, 0, sizeof bp);
memcpy(&bp, bpp, bplen);
if (params->flags & IB_TIMEOUT)
bp.bp_timeout = htole32(params->timeout);
if (params->flags & IB_RESETVIDEO)
bp.bp_flags |= htole32(X86_BP_FLAGS_RESET_VIDEO);
if (params->flags & IB_CONSPEED)
bp.bp_conspeed = htole32(params->conspeed);
if (params->flags & IB_CONSADDR)
bp.bp_consaddr = htole32(params->consaddr);
if (params->flags & IB_CONSOLE) {
static const char *names[] = {
"pc", "com0", "com1", "com2", "com3",
"com0kbd", "com1kbd", "com2kbd", "com3kbd",
NULL };
for (i = 0; ; i++) {
if (names[i] == NULL) {
warnx("invalid console name, valid names are:");
fprintf(stderr, "\t%s", names[0]);
for (i = 1; names[i] != NULL; i++)
fprintf(stderr, ", %s", names[i]);
fprintf(stderr, "\n");
goto done;
}
if (strcmp(names[i], params->console) == 0)
break;
}
bp.bp_consdev = htole32(i);
}
if (params->flags & IB_PASSWORD) {
MD5_CTX md5ctx;
MD5Init(&md5ctx);
MD5Update(&md5ctx, params->password, strlen(params->password));
MD5Final(bp.bp_password, &md5ctx);
bp.bp_flags |= htole32(X86_BP_FLAGS_PASSWORD);
}
if (params->flags & IB_KEYMAP)
strlcpy(bp.bp_keymap, params->keymap, sizeof bp.bp_keymap);
/* Check we aren't trying to set anything we can't save */
if (bplen < sizeof bp && memcmp((char *)&bp + bplen,
(char *)&bp + bplen + 1,
sizeof bp - bplen - 1) != 0) {
warnx("Patch area in stage1 bootstrap is too small");
if (update_i386_boot_params(params, bpp))
goto done;
}
memcpy(bpp, &bp, bplen);
if (params->flags & IB_NOWRITE) {
retval = 1;
@ -277,3 +322,77 @@ i386_setboot(ib_params *params)
free(bootstrapbuf);
return retval;
}
int
i386_editboot(ib_params *params)
{
int retval;
uint8_t buf[512];
ssize_t rv;
uint32_t magic;
uint32_t offset;
struct x86_boot_params *bpp;
assert(params != NULL);
assert(params->fsfd != -1);
assert(params->filesystem != NULL);
retval = 0;
/*
* Read in the existing bootstrap.
*/
bpp = NULL;
for (offset = 0; offset < 4 * 512; offset += 512) {
rv = pread(params->fsfd, &buf, sizeof buf, offset);
if (rv == -1) {
warn("Reading `%s'", params->filesystem);
goto done;
} else if (rv != sizeof buf) {
warnx("Reading `%s': short read", params->filesystem);
goto done;
}
magic = *(uint32_t *)(buf + 4) | 0xf;
if (magic != htole32(X86_BOOT_MAGIC_1 | 0xf))
continue;
bpp = (void *)(buf + 8);
break;
}
if (bpp == NULL) {
warnx("Invalid magic in stage1 boostrap");
goto done;
}
/*
* Fill in any user-specified options into the
* struct x86_boot_params
* that's 8 bytes in from the start of the third sector.
* See sys/arch/i386/stand/bootxx/bootxx.S for more information.
*/
if (update_i386_boot_params(params, bpp))
goto done;
if (params->flags & IB_NOWRITE) {
retval = 1;
goto done;
}
/*
* Write boot code back
*/
rv = pwrite(params->fsfd, buf, sizeof buf, offset);
if (rv == -1) {
warn("Writing `%s'", params->filesystem);
goto done;
} else if (rv != sizeof buf) {
warnx("Writing `%s': short write", params->filesystem);
goto done;
}
retval = 1;
done:
return retval;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: installboot.8,v 1.47 2005/10/10 05:41:28 dyoung Exp $
.\" $NetBSD: installboot.8,v 1.48 2005/11/11 21:09:50 dsl Exp $
.\"
.\" Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -34,7 +34,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd October 6, 2005
.Dd November 11, 2006
.Dt INSTALLBOOT 8
.Os
.Sh NAME
@ -75,6 +75,16 @@
.Op Fl t Ar fstype
.Ek
.Ar filesystem
.Nm
.Fl e
.Op Fl nv
.Bk -words
.Op Fl m Ar machine
.Ek
.Bk -words
.Op Fl o Ar options
.Ek
.Ar bootstrap
.
.Sh DESCRIPTION
The
@ -183,6 +193,10 @@ so that its size can be determined.
.It Fl c
Clear (remove) any existing bootstrap instead of installing one.
.
.It Fl e
Edit the options of an existing bootstrap.
.Sy [ amd64 , i386 ]
.
.It Fl m Ar machine
Use
.Ar machine

View File

@ -1,4 +1,4 @@
/* $NetBSD: installboot.c,v 1.18 2005/07/10 07:12:13 isaki Exp $ */
/* $NetBSD: installboot.c,v 1.19 2005/11/11 21:09:50 dsl Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: installboot.c,v 1.18 2005/07/10 07:12:13 isaki Exp $");
__RCSID("$NetBSD: installboot.c,v 1.19 2005/11/11 21:09:50 dsl Exp $");
#endif /* !__lint */
#include <sys/utsname.h>
@ -117,7 +117,7 @@ main(int argc, char *argv[])
if ((p = getenv("MACHINE")) != NULL)
getmachine(params, p, "$MACHINE");
while ((ch = getopt(argc, argv, "b:B:cm:no:t:v")) != -1) {
while ((ch = getopt(argc, argv, "b:B:cem:no:t:v")) != -1) {
switch (ch) {
case 'b':
@ -142,6 +142,10 @@ main(int argc, char *argv[])
params->flags |= IB_CLEAR;
break;
case 'e':
params->flags |= IB_EDIT;
break;
case 'm':
getmachine(params, optarg, "-m");
break;
@ -172,11 +176,12 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
if (((params->flags & IB_CLEAR) != 0 && argc != 1) ||
((params->flags & IB_CLEAR) == 0 && (argc < 2 || argc > 3)))
if (params->flags & IB_CLEAR && params->flags & IB_EDIT)
usage();
if (argc < 1 || argc + 2 * !!(params->flags & (IB_CLEAR | IB_EDIT)) > 3)
usage();
/* set missing defaults */
/* set missing defaults */
if (params->machine == NULL) {
if (uname(&utsname) == -1)
err(1, "Determine uname");
@ -185,7 +190,7 @@ main(int argc, char *argv[])
/* Check that options are supported by this system */
unsupported_flags = params->flags & ~params->machine->valid_flags;
unsupported_flags &= ~(IB_VERBOSE | IB_NOWRITE |IB_CLEAR);
unsupported_flags &= ~(IB_VERBOSE | IB_NOWRITE | IB_CLEAR | IB_EDIT);
if (unsupported_flags != 0) {
int ndx;
for (ndx = 0; options[ndx].name != NULL; ndx++) {
@ -261,14 +266,18 @@ main(int argc, char *argv[])
printf("File system type: %s (blocksize %u, needswap %d)\n",
params->fstype->name,
params->fstype->blocksize, params->fstype->needswap);
printf("Primary bootstrap: %s\n",
(params->flags & IB_CLEAR) ? "(to be cleared)"
: params->stage1);
if (!(params->flags & IB_EDIT))
printf("Primary bootstrap: %s\n",
(params->flags & IB_CLEAR) ? "(to be cleared)"
: params->stage1 ? params->stage1 : "(none)" );
if (params->stage2 != NULL)
printf("Secondary bootstrap: %s\n", params->stage2);
}
if (params->flags & IB_CLEAR) {
if (params->flags & IB_EDIT) {
op = "Edit";
rv = params->machine->editboot(params);
} else if (params->flags & IB_CLEAR) {
op = "Clear";
rv = params->machine->clearboot(params);
} else {
@ -404,7 +413,6 @@ no_setboot(ib_params *params)
assert(params != NULL);
/* bootstrap installation is not supported */
warnx("%s: bootstrap installation is not supported",
params->machine->name);
return (0);
@ -416,12 +424,22 @@ no_clearboot(ib_params *params)
assert(params != NULL);
/* bootstrap removal is not supported */
warnx("%s: bootstrap removal is not supported",
params->machine->name);
return (0);
}
int
no_editboot(ib_params *params)
{
assert(params != NULL);
warnx("%s: bootstrap editing is not supported",
params->machine->name);
return (0);
}
static void
getmachine(ib_params *param, const char *mach, const char *provider)
@ -514,8 +532,9 @@ usage(void)
fprintf(stderr,
"usage: %s [-nv] [-m machine] [-o options] [-t fstype]\n"
"\t\t [-b s1start] [-B s2start] filesystem primary [secondary]\n"
"usage: %s -c [-nv] [-m machine] [-o options] [-t fstype] filesystem\n",
prog, prog);
"usage: %s -c [-nv] [-m machine] [-o options] [-t fstype] filesystem\n"
"usage: %s -e [-nv] [-m machine] [-o options] bootstrap\n",
prog, prog, prog);
machine_usage();
fstype_usage();
options_usage();

View File

@ -1,4 +1,4 @@
/* $NetBSD: installboot.h,v 1.26 2005/05/14 14:46:21 chs Exp $ */
/* $NetBSD: installboot.h,v 1.27 2005/11/11 21:09:50 dsl Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -55,6 +55,7 @@ typedef enum {
IB_VERBOSE = 1<<0, /* verbose operation */
IB_NOWRITE = 1<<1, /* don't write */
IB_CLEAR = 1<<2, /* clear boot block */
IB_EDIT = 1<<3, /* edit boot parameters */
/* flags from -o options */
IB_ALPHASUM = 1<<8, /* set Alpha checksum */
@ -104,6 +105,7 @@ struct ib_mach {
const char *name;
int (*setboot) (ib_params *);
int (*clearboot) (ib_params *);
int (*editboot) (ib_params *);
ib_flags valid_flags;
};
@ -143,6 +145,7 @@ uint16_t compute_sunsum(const uint16_t *);
int set_sunsum(ib_params *, uint16_t *, uint16_t);
int no_setboot(ib_params *);
int no_clearboot(ib_params *);
int no_editboot(ib_params *);
/* bbinfo.c */
int shared_bbinfo_clearboot(ib_params *, struct bbinfo_params *,
@ -165,6 +168,7 @@ int hp300_setboot(ib_params *);
int hp700_setboot(ib_params *);
int hp700_clearboot(ib_params *);
int i386_setboot(ib_params *);
int i386_editboot(ib_params *);
int macppc_setboot(ib_params *);
int macppc_clearboot(ib_params *);
int news68k_setboot(ib_params *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: machines.c,v 1.28 2005/07/16 10:43:00 hannken Exp $ */
/* $NetBSD: machines.c,v 1.29 2005/11/11 21:09:50 dsl Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -42,48 +42,50 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: machines.c,v 1.28 2005/07/16 10:43:00 hannken Exp $");
__RCSID("$NetBSD: machines.c,v 1.29 2005/11/11 21:09:50 dsl Exp $");
#endif /* !__lint */
#include <sys/types.h>
#include "installboot.h"
struct ib_mach machines[] = {
{ "alpha", alpha_setboot, alpha_clearboot,
{ "alpha", alpha_setboot, alpha_clearboot, no_editboot,
IB_STAGE1START | IB_ALPHASUM | IB_APPEND | IB_SUNSUM },
{ "amd64", i386_setboot, no_clearboot,
{ "amd64", i386_setboot, no_clearboot, i386_editboot,
IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR |
IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT },
{ "amiga", amiga_setboot, no_clearboot,
{ "amiga", amiga_setboot, no_clearboot, no_editboot,
IB_STAGE1START | IB_STAGE2START | IB_COMMAND },
{ "hp300", hp300_setboot, no_clearboot,
{ "hp300", hp300_setboot, no_clearboot, no_editboot,
IB_APPEND },
{ "hp700", hp700_setboot, hp700_clearboot,
{ "hp700", hp700_setboot, hp700_clearboot, no_editboot,
0 },
{ "i386", i386_setboot, no_clearboot,
{ "i386", i386_setboot, no_clearboot, i386_editboot,
IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR |
IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT },
{ "macppc", macppc_setboot, macppc_clearboot,
{ "macppc", macppc_setboot, macppc_clearboot, no_editboot,
IB_STAGE2START },
{ "news68k", news68k_setboot, news68k_clearboot,
{ "news68k", news68k_setboot, news68k_clearboot, no_editboot,
IB_STAGE2START },
{ "newsmips", newsmips_setboot, newsmips_clearboot,
{ "newsmips", newsmips_setboot, newsmips_clearboot, no_editboot,
IB_STAGE2START },
{ "next68k", next68k_setboot, no_clearboot,
{ "next68k", next68k_setboot, no_clearboot, no_editboot,
0 },
{ "pmax", pmax_setboot, pmax_clearboot,
{ "pmax", pmax_setboot, pmax_clearboot, no_editboot,
IB_STAGE1START | IB_APPEND | IB_SUNSUM },
{ "shark", no_setboot, no_clearboot, },
{ "sparc", sparc_setboot, sparc_clearboot,
{ "shark", no_setboot, no_clearboot, no_editboot,
0 },
{ "sparc", sparc_setboot, sparc_clearboot, no_editboot,
IB_STAGE2START },
{ "sparc64", sparc64_setboot, sparc64_clearboot },
{ "sun2", sun68k_setboot, sun68k_clearboot,
{ "sparc64", sparc64_setboot, sparc64_clearboot, no_editboot,
0 },
{ "sun2", sun68k_setboot, sun68k_clearboot, no_editboot,
IB_STAGE2START },
{ "sun3", sun68k_setboot, sun68k_clearboot,
{ "sun3", sun68k_setboot, sun68k_clearboot, no_editboot,
IB_STAGE2START },
{ "vax", vax_setboot, vax_clearboot,
{ "vax", vax_setboot, vax_clearboot, no_editboot,
IB_STAGE1START | IB_APPEND | IB_SUNSUM },
{ "x68k", x68k_setboot, x68k_clearboot,
{ "x68k", x68k_setboot, x68k_clearboot, no_editboot,
IB_STAGE1START | IB_STAGE2START },
{ 0, 0, 0, 0 },
};