Make the bootselector configurable by fdisk. Add a -B flag to this
effect (i386 only of course). Also change one branch in the bootselector code to an explicit 16 bit one, and check both the boot menu and partition tables to see if the partition requested by the user should be booted. This check just in case, should the bootselector menu and partition table get out of sync somehow. (mmm, bytesqueezing)
This commit is contained in:
parent
6299fb0813
commit
48c1c25ba5
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: fdisk.8,v 1.17 1999/03/07 11:02:05 mycroft Exp $
|
||||
.\" $NetBSD: fdisk.8,v 1.18 1999/04/17 01:38:00 fvdl Exp $
|
||||
.\"
|
||||
.Dd April 4, 1993
|
||||
.Dt FDISK 8
|
||||
@ -8,7 +8,7 @@
|
||||
.Nd DOS partition maintenance program
|
||||
.Sh SYNOPSIS
|
||||
.Nm ""
|
||||
.Op Fl aiufS
|
||||
.Op Fl aiufBS
|
||||
.Bk -words
|
||||
.Op Fl 0 | 1 | 2 | 3
|
||||
.Ek
|
||||
@ -51,16 +51,13 @@ serves a similar purpose to the DOS program.
|
||||
When called with no arguments, it prints the sector 0 partition table.
|
||||
An example follows:
|
||||
.Bd -literal
|
||||
******* Working on device /dev/rwd0d *******
|
||||
Warning: BIOS sector numbering starts with sector 1
|
||||
parameters extracted from in-core disklabel are:
|
||||
cylinders=769 heads=15 sectors/track=33 (495 sectors/cylinder)
|
||||
NetBSD disklabel disk geometry:
|
||||
cylinders: 769 heads: 15 sectors/track: 33 (495 sectors/cylinder)
|
||||
|
||||
parameters to be used for BIOS calculations are:
|
||||
cylinders=769 heads=15 sectors/track=33 (495 sectors/cylinder)
|
||||
|
||||
Information from DOS bootblock is:
|
||||
The data for partition 0 is:
|
||||
BIOS geometry:
|
||||
cylinders: 769 heads: 15 sectors/track: 33 (495 sectors/cylinder)
|
||||
|
||||
Partition table:
|
||||
0: sysid 169 (NetBSD)
|
||||
start 495, size 380160 (185 MB), flag 0
|
||||
beg: cylinder 1, head 0, sector 1
|
||||
@ -183,6 +180,11 @@ should read the bootcode from. The default is to read from
|
||||
if run on an i386, end leave the bootcode empty for other
|
||||
machines.
|
||||
.Pp
|
||||
The
|
||||
.Fl B
|
||||
flag can be used to install/update the bootselect code on i386
|
||||
platforms.
|
||||
.Pp
|
||||
The flags
|
||||
.Fl 0 ,
|
||||
.Fl 1 ,
|
||||
@ -253,9 +255,11 @@ lose all the data in that partition.
|
||||
You should run this program interactively once or twice to see how it works.
|
||||
This is completely safe as long as you answer the last question in the negative.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/mdec/mbrxx -compact
|
||||
.Bl -tag -width /usr/mdec/mbrxxxxxxxx -compact
|
||||
.It Pa /usr/mdec/mbr
|
||||
Default location of i386 bootcode
|
||||
.It Pa /usr/mdec/mbr_bootsel
|
||||
Default location of i386 bootselect code
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr disklabel 8
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fdisk.c,v 1.33 1999/02/09 19:11:46 perry Exp $ */
|
||||
/* $NetBSD: fdisk.c,v 1.34 1999/04/17 01:38:00 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Mach Operating System
|
||||
@ -29,7 +29,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: fdisk.c,v 1.33 1999/02/09 19:11:46 perry Exp $");
|
||||
__RCSID("$NetBSD: fdisk.c,v 1.34 1999/04/17 01:38:00 fvdl Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -50,6 +50,12 @@ __RCSID("$NetBSD: fdisk.c,v 1.33 1999/02/09 19:11:46 perry Exp $");
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifdef __i386__
|
||||
#include <ctype.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#define LBUF 100
|
||||
static char lbuf[LBUF];
|
||||
|
||||
@ -74,7 +80,27 @@ struct mboot {
|
||||
struct mboot mboot;
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
struct mbr_bootsel {
|
||||
u_int8_t defkey;
|
||||
u_int8_t flags;
|
||||
u_int16_t timeo;
|
||||
char nametab[4][9];
|
||||
u_int16_t magic;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BFL_SELACTIVE 0x01
|
||||
|
||||
#define SCAN_ENTER 0x1c
|
||||
#define SCAN_F1 0x3b
|
||||
|
||||
#define MBR_BOOTSELOFF (MBR_PARTOFF - sizeof (struct mbr_bootsel))
|
||||
|
||||
#define DEFAULT_BOOTCODE "/usr/mdec/mbr"
|
||||
#define DEFAULT_BOOTSELCODE "/usr/mdec/mbr_bootsel"
|
||||
#define OPTIONS "0123BSafius:b:c:"
|
||||
#else
|
||||
#define OPTIONS "0123Safius:b:c:"
|
||||
#endif
|
||||
|
||||
#define ACTIVE 0x80
|
||||
@ -97,9 +123,12 @@ int sh_flag; /* Output data as shell defines */
|
||||
int f_flag; /* force --not interactive */
|
||||
int s_flag; /* set id,offset,size */
|
||||
int b_flag; /* Set cyl, heads, secs (as c/h/s) */
|
||||
int B_flag; /* Edit/install bootselect code */
|
||||
int b_cyl, b_head, b_sec; /* b_flag values. */
|
||||
int bootsel_modified;
|
||||
|
||||
unsigned char bootcode[8192]; /* maximum size of bootcode */
|
||||
unsigned char tempcode[8192];
|
||||
int bootsize; /* actual size of bootcode */
|
||||
|
||||
|
||||
@ -226,9 +255,11 @@ struct part_type {
|
||||
void usage __P((void));
|
||||
void print_s0 __P((int));
|
||||
void print_part __P((int));
|
||||
void read_boot __P((char *));
|
||||
int read_boot __P((char *, char *, size_t));
|
||||
void init_sector0 __P((int, int));
|
||||
void intuit_translated_geometry __P((void));
|
||||
void get_geometry __P((void));
|
||||
void get_diskname __P((char *, char *, size_t));
|
||||
int try_heads __P((quad_t, quad_t, quad_t, quad_t, quad_t, quad_t, quad_t,
|
||||
quad_t));
|
||||
int try_sectors __P((quad_t, quad_t, quad_t, quad_t, quad_t));
|
||||
@ -248,6 +279,9 @@ void decimal __P((char *, int *));
|
||||
int type_match __P((const void *, const void *));
|
||||
char *get_type __P((int));
|
||||
int get_mapping __P((int, int *, int *, int *, long *));
|
||||
#ifdef __i386__
|
||||
void configure_bootsel __P((void));
|
||||
#endif
|
||||
|
||||
static inline unsigned short getshort __P((void *));
|
||||
static inline void putshort __P((void *p, unsigned short));
|
||||
@ -269,7 +303,7 @@ main(argc, argv)
|
||||
|
||||
a_flag = i_flag = u_flag = sh_flag = f_flag = s_flag = b_flag = 0;
|
||||
csysid = cstart = csize = 0;
|
||||
while ((ch = getopt(argc, argv, "0123Safius:b:c:")) != -1)
|
||||
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
|
||||
switch (ch) {
|
||||
case '0':
|
||||
partition = 0;
|
||||
@ -283,6 +317,11 @@ main(argc, argv)
|
||||
case '3':
|
||||
partition = 3;
|
||||
break;
|
||||
#ifdef __i386__
|
||||
case 'B':
|
||||
B_flag = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'S':
|
||||
sh_flag = 1;
|
||||
break;
|
||||
@ -321,7 +360,7 @@ main(argc, argv)
|
||||
b_cyl = MAXCYL;
|
||||
break;
|
||||
case 'c':
|
||||
read_boot(optarg);
|
||||
bootsize = read_boot(optarg, bootcode, sizeof bootcode);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
@ -332,6 +371,9 @@ main(argc, argv)
|
||||
if (sh_flag && (a_flag || i_flag || u_flag || f_flag || s_flag))
|
||||
usage();
|
||||
|
||||
if (B_flag && (a_flag || i_flag || u_flag || f_flag || s_flag))
|
||||
usage();
|
||||
|
||||
if (partition == -1 && s_flag) {
|
||||
(void) fprintf (stderr,
|
||||
"-s flag requires a partition selected.\n");
|
||||
@ -341,16 +383,17 @@ main(argc, argv)
|
||||
if (argc > 0)
|
||||
disk = argv[0];
|
||||
|
||||
if (open_disk(a_flag || i_flag || u_flag) < 0)
|
||||
if (open_disk(B_flag || a_flag || i_flag || u_flag) < 0)
|
||||
exit(1);
|
||||
|
||||
if (read_s0())
|
||||
init_sector0(sectors > 63 ? 63 : sectors, 1);
|
||||
|
||||
#ifdef __i386__
|
||||
get_geometry();
|
||||
#else
|
||||
intuit_translated_geometry();
|
||||
|
||||
if (!sh_flag && !f_flag)
|
||||
printf("******* Working on device %s *******\n", disk);
|
||||
#endif
|
||||
|
||||
|
||||
if ((i_flag || u_flag) && (!f_flag || b_flag))
|
||||
@ -359,14 +402,11 @@ main(argc, argv)
|
||||
if (i_flag)
|
||||
init_sector0(dos_sectors > 63 ? 63 : dos_sectors, 0);
|
||||
|
||||
if (!sh_flag && !f_flag)
|
||||
printf("Warning: BIOS sector numbering starts with sector 1\n");
|
||||
|
||||
/* Do the update stuff! */
|
||||
if (u_flag) {
|
||||
if (!f_flag)
|
||||
printf("Information from DOS bootblock is:\n");
|
||||
if (partition == -1)
|
||||
printf("Partition table:\n");
|
||||
if (partition == -1)
|
||||
for (part = 0; part < NMBRPART; part++)
|
||||
change_part(part,-1, -1, -1);
|
||||
else
|
||||
@ -378,9 +418,17 @@ main(argc, argv)
|
||||
if (a_flag)
|
||||
change_active(partition);
|
||||
|
||||
#ifdef __i386__
|
||||
if (B_flag) {
|
||||
configure_bootsel();
|
||||
if (B_flag && bootsel_modified)
|
||||
write_s0();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (u_flag || a_flag || i_flag) {
|
||||
if (!f_flag) {
|
||||
printf("\nWe haven't changed the partition table "
|
||||
printf("\nWe haven't written the MBR back to disk "
|
||||
"yet. This is your last chance.\n");
|
||||
print_s0(-1);
|
||||
if (yesno("Should we write new partition table?"))
|
||||
@ -408,7 +456,7 @@ print_s0(which)
|
||||
|
||||
print_params();
|
||||
if (!sh_flag)
|
||||
printf("Information from DOS bootblock is:\n");
|
||||
printf("Partition table:\n");
|
||||
if (which == -1) {
|
||||
for (part = 0; part < NMBRPART; part++) {
|
||||
if (!sh_flag)
|
||||
@ -419,8 +467,6 @@ print_s0(which)
|
||||
print_part(which);
|
||||
}
|
||||
|
||||
static struct mbr_partition mtpart = { 0 };
|
||||
|
||||
static inline unsigned short
|
||||
getshort(p)
|
||||
void *p;
|
||||
@ -471,7 +517,7 @@ print_part(part)
|
||||
int empty;
|
||||
|
||||
partp = &mboot.parts[part];
|
||||
empty = !memcmp(partp, &mtpart, sizeof(struct mbr_partition));
|
||||
empty = (partp->mbrp_typ == 0);
|
||||
|
||||
if (sh_flag) {
|
||||
if (empty) {
|
||||
@ -511,33 +557,36 @@ print_part(part)
|
||||
partp->mbrp_ehd, MBR_PSECT(partp->mbrp_esect));
|
||||
}
|
||||
|
||||
void
|
||||
read_boot(name)
|
||||
int
|
||||
read_boot(name, buf, len)
|
||||
char *name;
|
||||
char *buf;
|
||||
size_t len;
|
||||
{
|
||||
int fd;
|
||||
int bfd, ret;
|
||||
struct stat st;
|
||||
|
||||
if ((fd = open(name, O_RDONLY)) < 0)
|
||||
if ((bfd = open(name, O_RDONLY)) < 0)
|
||||
err(1, "%s", name);
|
||||
if (fstat(fd, &st) == -1)
|
||||
if (fstat(bfd, &st) == -1)
|
||||
err(1, "%s", name);
|
||||
if (st.st_size > sizeof(bootcode))
|
||||
if (st.st_size > len)
|
||||
errx(1, "%s: bootcode too large", name);
|
||||
bootsize = st.st_size;
|
||||
if (bootsize < 0x200)
|
||||
ret = st.st_size;
|
||||
if (ret < 0x200)
|
||||
errx(1, "%s: bootcode too small", name);
|
||||
if (read(fd, bootcode, bootsize) != bootsize)
|
||||
if (read(bfd, buf, len) != ret)
|
||||
err(1, "%s", name);
|
||||
close(fd);
|
||||
close(bfd);
|
||||
|
||||
/*
|
||||
* Do some sanity checking here
|
||||
*/
|
||||
if (getshort(bootcode + MBR_MAGICOFF) != MBR_MAGIC)
|
||||
errx(1, "%s: invalid magic", name);
|
||||
bootsize = (bootsize + 0x1ff) / 0x200;
|
||||
bootsize *= 0x200;
|
||||
ret = (ret + 0x1ff) / 0x200;
|
||||
ret *= 0x200;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
@ -548,18 +597,280 @@ init_sector0(start, dopart)
|
||||
|
||||
#ifdef DEFAULT_BOOTCODE
|
||||
if (!bootsize)
|
||||
read_boot(DEFAULT_BOOTCODE);
|
||||
bootsize = read_boot(DEFAULT_BOOTCODE, bootcode,
|
||||
sizeof bootcode);
|
||||
#endif
|
||||
|
||||
memcpy(mboot.bootinst, bootcode, sizeof(mboot.bootinst));
|
||||
putshort(&mboot.signature, MBR_MAGIC);
|
||||
|
||||
if (dopart)
|
||||
for (i=0; i<3; i++)
|
||||
memset (&mboot.parts[i], 0, sizeof(struct mbr_partition));
|
||||
for (i=0; i<4; i++)
|
||||
memset(&mboot.parts[i], 0, sizeof(struct mbr_partition));
|
||||
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
void
|
||||
get_diskname(fullname, diskname, size)
|
||||
char *fullname;
|
||||
char *diskname;
|
||||
size_t size;
|
||||
{
|
||||
char *p;
|
||||
char *p2;
|
||||
size_t len;
|
||||
|
||||
p = strrchr(fullname, '/');
|
||||
if (p == NULL)
|
||||
p = fullname;
|
||||
else
|
||||
p++;
|
||||
|
||||
if (*p == 0) {
|
||||
strncpy(diskname, fullname, size - 1);
|
||||
diskname[size - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (*p == 'r')
|
||||
p++;
|
||||
|
||||
for (p2 = p; *p2 != 0; p2++)
|
||||
if (isdigit(*p2))
|
||||
break;
|
||||
if (*p2 == 0) {
|
||||
/* XXX invalid diskname? */
|
||||
strncpy(diskname, fullname, size - 1);
|
||||
diskname[size - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
while (isdigit(*p2))
|
||||
p2++;
|
||||
|
||||
len = p2 - p;
|
||||
if (len > size) {
|
||||
/* XXX */
|
||||
strncpy(diskname, fullname, size - 1);
|
||||
diskname[size - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(diskname, p, len);
|
||||
diskname[len] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
get_geometry()
|
||||
{
|
||||
int mib[2], i;
|
||||
size_t len;
|
||||
struct disklist *dl;
|
||||
struct biosdisk_info *bip;
|
||||
struct nativedisk_info *nip;
|
||||
char diskname[8];
|
||||
|
||||
mib[0] = CTL_MACHDEP;
|
||||
mib[1] = CPU_DISKINFO;
|
||||
if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0) {
|
||||
intuit_translated_geometry();
|
||||
return;
|
||||
}
|
||||
dl = (struct disklist *) malloc(len);
|
||||
sysctl(mib, 2, dl, &len, NULL, 0);
|
||||
|
||||
get_diskname(disk, diskname, sizeof diskname);
|
||||
|
||||
for (i = 0; i < dl->dl_nnativedisks; i++) {
|
||||
nip = &dl->dl_nativedisks[i];
|
||||
if (strcmp(diskname, nip->ni_devname))
|
||||
continue;
|
||||
/*
|
||||
* XXX listing possible matches is better. This is ok
|
||||
* for now because the user has a chance to change
|
||||
* it later.
|
||||
*/
|
||||
if (nip->ni_nmatches != 0) {
|
||||
bip = &dl->dl_biosdisks[nip->ni_biosmatches[0]];
|
||||
dos_cylinders = bip->bi_cyl;
|
||||
dos_heads = bip->bi_head;
|
||||
dos_sectors = bip->bi_sec;
|
||||
dos_cylindersectors = bip->bi_head * bip->bi_sec;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Allright, allright, make a stupid guess.. */
|
||||
intuit_translated_geometry();
|
||||
}
|
||||
|
||||
void
|
||||
configure_bootsel()
|
||||
{
|
||||
struct mbr_bootsel *mbs =
|
||||
(struct mbr_bootsel *)&mboot.bootinst[MBR_BOOTSELOFF];
|
||||
int i, nused, firstpart = -1, item;
|
||||
char desc[10], *p;
|
||||
int timo, entry_changed = 0;
|
||||
|
||||
for (i = nused = 0; i < NMBRPART; i++) {
|
||||
if (mboot.parts[i].mbrp_typ != 0) {
|
||||
if (firstpart == -1)
|
||||
firstpart = i;
|
||||
nused++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nused == 0) {
|
||||
printf("No used partitions found. Partition the disk first.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mbs->magic != MBR_MAGIC) {
|
||||
if (!yesno("Bootselector not yet installed. Install it now?")) {
|
||||
printf("Bootselector not installed.\n");
|
||||
return;
|
||||
}
|
||||
bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
|
||||
sizeof bootcode);
|
||||
memcpy(mboot.bootinst, bootcode, sizeof(mboot.bootinst));
|
||||
bootsel_modified = 1;
|
||||
mbs->flags |= BFL_SELACTIVE;
|
||||
} else {
|
||||
if (mbs->flags & BFL_SELACTIVE) {
|
||||
printf("The bootselector is installed and active.\n");
|
||||
if (!yesno("Do you want to change its settings?")) {
|
||||
if (yesno("Do you want to deactivate it?")) {
|
||||
mbs->flags &= ~BFL_SELACTIVE;
|
||||
bootsel_modified = 1;
|
||||
goto done;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("The bootselector is installed but not active.\n");
|
||||
if (yesno("Do you want to activate it?")) {
|
||||
mbs->flags |= BFL_SELACTIVE;
|
||||
bootsel_modified = 1;
|
||||
}
|
||||
if (!yesno("Do you want to change its settings?"))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\nPartition table:\n");
|
||||
for (i = 0; i < NMBRPART; i++) {
|
||||
printf("%d: ", i);
|
||||
print_part(i);
|
||||
}
|
||||
|
||||
printf("\n\nCurrent boot selection menu option names:\n");
|
||||
for (i = 0; i < NMBRPART; i++) {
|
||||
if (mbs->nametab[i][0] != 0)
|
||||
printf("%d: %s\n", i, &mbs->nametab[i][0]);
|
||||
else
|
||||
printf("%d: Unused\n", i);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
item = firstpart;
|
||||
|
||||
editentries:
|
||||
while (1) {
|
||||
decimal("Change which entry (-1 quits)?", &item);
|
||||
if (item == -1)
|
||||
break;
|
||||
if (item < 0 || item >= NMBRPART) {
|
||||
printf("Invalid entry number\n");
|
||||
continue;
|
||||
}
|
||||
if (mboot.parts[item].mbrp_typ == 0) {
|
||||
printf("The matching partition entry is unused\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Enter descriptions (max. 8 characters): ");
|
||||
rewind(stdin);
|
||||
fgets(desc, 10, stdin);
|
||||
p = strchr(desc, '\n');
|
||||
if (p != NULL)
|
||||
*p = 0;
|
||||
else
|
||||
desc[9] = 0;
|
||||
strcpy(&mbs->nametab[item][0], desc);
|
||||
entry_changed = bootsel_modified = 1;
|
||||
}
|
||||
|
||||
if (entry_changed)
|
||||
printf("Boot selection menu option names are now:\n");
|
||||
|
||||
firstpart = -1;
|
||||
for (i = 0; i < NMBRPART; i++) {
|
||||
if (mbs->nametab[i][0] != 0) {
|
||||
firstpart = i;
|
||||
if (entry_changed)
|
||||
printf("%d: %s\n", i, &mbs->nametab[i][0]);
|
||||
} else {
|
||||
if (entry_changed)
|
||||
printf("%d: Unused\n", i);
|
||||
}
|
||||
}
|
||||
if (entry_changed)
|
||||
printf("\n");
|
||||
|
||||
if (firstpart == -1) {
|
||||
printf("All menu entries are now inactive.\n");
|
||||
if (!yesno("Are you sure about this?"))
|
||||
goto editentries;
|
||||
} else {
|
||||
if (!(mbs->flags & BFL_SELACTIVE)) {
|
||||
printf("The bootselector is not yet active.\n");
|
||||
if (yesno("Activate it now?"))
|
||||
mbs->flags |= BFL_SELACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* The timeout value is in ticks, 18.2 Hz. Avoid using floats. */
|
||||
timo = ((1000 * mbs->timeo) / 18200);
|
||||
do {
|
||||
decimal("Timeout value", &timo);
|
||||
} while (timo < 0 || timo > 3600);
|
||||
mbs->timeo = (u_int16_t)((timo * 18200) / 1000);
|
||||
|
||||
printf("Select the default boot option. Options are:\n\n");
|
||||
for (i = 0; i < NMBRPART; i++) {
|
||||
if (mbs->nametab[i][0] != 0)
|
||||
printf("%d: %s\n", i, &mbs->nametab[i][0]);
|
||||
}
|
||||
for (i = 4; i < 10; i++)
|
||||
printf("%d: Harddisk %d\n", i, i - 4);
|
||||
printf("10: The first active partition\n");
|
||||
|
||||
if (mbs->defkey == SCAN_ENTER)
|
||||
item = 10;
|
||||
else
|
||||
item = mbs->defkey - SCAN_F1;
|
||||
|
||||
if (item < 0 || item > 10 || mbs->nametab[item][0] == 0)
|
||||
item = 10;
|
||||
|
||||
do {
|
||||
decimal("Default boot option", &item);
|
||||
} while (item < 0 || item > 10 ||
|
||||
(item <= 3 && mbs->nametab[item][0] == 0));
|
||||
|
||||
if (item == 10)
|
||||
mbs->defkey = SCAN_ENTER;
|
||||
else
|
||||
mbs->defkey = SCAN_F1 + item;
|
||||
|
||||
done:
|
||||
if (!yesno("Update the bootselector?"))
|
||||
bootsel_modified = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Prerequisite: the disklabel parameters and master boot record must
|
||||
* have been read (i.e. dos_* and mboot are meaningful).
|
||||
* Specification: modifies dos_cylinders, dos_heads, dos_sectors, and
|
||||
@ -780,13 +1091,11 @@ print_params()
|
||||
}
|
||||
|
||||
/* Not sh_flag */
|
||||
printf("parameters extracted from in-core disklabel are:\n");
|
||||
printf("cylinders=%d heads=%d sectors/track=%d (%d sectors/cylinder)\n\n",
|
||||
printf("NetBSD disklabel disk geometry:\n");
|
||||
printf("cylinders: %d heads: %d sectors/track: %d (%d sectors/cylinder)\n\n",
|
||||
cylinders, heads, sectors, cylindersectors);
|
||||
if (dos_sectors > 63 || dos_heads > 255)
|
||||
printf("Figures below won't work with BIOS for partitions not in cylinder 1\n");
|
||||
printf("parameters to be used for BIOS calculations are:\n");
|
||||
printf("cylinders=%d heads=%d sectors/track=%d (%d sectors/cylinder)\n\n",
|
||||
printf("BIOS disk geometry:\n");
|
||||
printf("cylinders: %d heads: %d sectors/track: %d (%d sectors/cylinder)\n\n",
|
||||
dos_cylinders, dos_heads, dos_sectors, dos_cylindersectors);
|
||||
}
|
||||
|
||||
@ -1022,7 +1331,7 @@ decimal(str, num)
|
||||
char *cp;
|
||||
|
||||
for (;; printf("%s is not a valid decimal number.\n", lbuf)) {
|
||||
printf("Supply a decimal value for \"%s\" [%d] ", str, *num);
|
||||
printf("%s: [%d] ", str, *num);
|
||||
|
||||
fgets(lbuf, LBUF, stdin);
|
||||
lbuf[strlen(lbuf)-1] = '\0';
|
||||
@ -1032,7 +1341,7 @@ decimal(str, num)
|
||||
if (*cp == '\0')
|
||||
return;
|
||||
|
||||
if (!isdigit(*cp))
|
||||
if (!isdigit(*cp) && *cp != '-')
|
||||
continue;
|
||||
acc = strtol(lbuf, &cp, 10);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mbr_bootsel.S,v 1.1 1999/04/15 22:31:23 fvdl Exp $ */
|
||||
/* $NetBSD: mbr_bootsel.S,v 1.2 1999/04/17 01:38:00 fvdl Exp $ */
|
||||
|
||||
|
||||
/*-
|
||||
@ -114,6 +114,7 @@
|
||||
*/
|
||||
#define call16(label) .byte 0xe8 ; .word label - . - 2
|
||||
#define jmp16(label) .byte 0xe9 ; .word label - . - 2
|
||||
#define jznear16(label) .byte 0x0f ; .byte 0x84 ; .word label - . - 2
|
||||
#define jmpfar(segval,addr) .byte 0xea ; .word addr ; .word segval
|
||||
|
||||
#define movb_mem_al(mem) .byte 0xa0 ; .word mem
|
||||
@ -152,6 +153,9 @@
|
||||
#define cmpb_imm_iregoff(imm,reg,off) \
|
||||
.byte 0x80 ; .byte 0x78 + reg ; .byte off ; .byte imm
|
||||
|
||||
#define cmpb_imm_ireg0_bx(imm,reg) \
|
||||
.byte 0x80 ; .byte 0x34 + reg ; .byte imm
|
||||
|
||||
#define cmpb_mem_reg(mem,reg) .byte 0x3a ; .byte 0x06 | (reg << 3) ; .word mem
|
||||
#define cmpw_imm_reg(imm,reg) .byte 0x81 ; .byte 0xf8 + reg ; .word imm
|
||||
|
||||
@ -231,7 +235,7 @@ ENTRY(start)
|
||||
bootsel:
|
||||
movb_mem_al(flags)
|
||||
testb $BFL_SELACTIVE,%al
|
||||
jz getactive
|
||||
jznear16(getactive)
|
||||
/*
|
||||
* The bootselector is active. Walk through the selector (name) table,
|
||||
* printing used entries.
|
||||
@ -319,15 +323,20 @@ default:
|
||||
jmp boot2
|
||||
5:
|
||||
/*
|
||||
* Check if the requested entry is actually active in the select table.
|
||||
* If not, just do nothing.
|
||||
* Check if the requested entry is actually active in the partition and
|
||||
* bootmenu table. If not, just do nothing.
|
||||
*/
|
||||
movw_imm_reg(parttab,SI)
|
||||
and_imm_ax(0xff)
|
||||
movl %eax,%ebx
|
||||
shll $4,%eax
|
||||
add %eax,%esi
|
||||
cmpb_imm_iregoff(0,SI_INDEX,4)
|
||||
je 4b
|
||||
movw_imm_reg(nametab,DI)
|
||||
imul $TABENTRYSIZE,%ebx
|
||||
cmpb_imm_ireg0_bx(0,DI_INDEX)
|
||||
je 4b
|
||||
jmp boot
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user