Update boot0cfg to handle the new boot0:

- Allow for boot0 to be more than one sector long.  However, ensure that it
  its length is a multiple of the sector length.
- Change the signatures used to determine a valid boot0 as some of the
  signature code changed.
- Use the old signature to detect version 1.0 of boot0, otherwise read the
  version number from boot0 itself.
This commit is contained in:
jhb 2000-07-12 18:15:06 +00:00
parent c9f5ee0479
commit f965e9b866

View File

@ -44,6 +44,7 @@ static const char rcsid[] =
#define MBRSIZE 512 /* master boot record size */
#define OFF_VERSION 0x1b0 /* offset: version number */
#define OFF_DRIVE 0x1ba /* offset: setdrv drive */
#define OFF_FLAGS 0x1bb /* offset: option flags */
#define OFF_TICKS 0x1bc /* offset: clock ticks */
@ -72,6 +73,7 @@ static const char fmt0[] = "# flag start chs type"
static const char fmt1[] = "%d 0x%02x %4u:%3u:%2u 0x%02x"
" %4u:%3u:%2u %10u %10u\n";
static int boot0version(const u_int8_t *);
static int boot0bs(const u_int8_t *);
static void stropt(const char *, int *, int *);
static char *mkrdev(const char *);
@ -85,7 +87,11 @@ int
main(int argc, char *argv[])
{
u_int8_t buf[MBRSIZE];
u_int8_t *boot0 = buf;
int version;
int boot0_size = sizeof(buf);
struct dos_partition part[4];
struct stat sb;
const char *bpath, *fpath, *disk;
ssize_t n;
int B_flag, v_flag, o_flag;
@ -155,32 +161,36 @@ main(int argc, char *argv[])
}
memcpy(part, buf + OFF_PTBL, sizeof(part));
if (B_flag) {
if ((fd1 = open(bpath, O_RDONLY)) == -1 ||
(n = read(fd1, buf, MBRSIZE)) == -1 || close(fd1))
if ((fd1 = open(bpath, O_RDONLY)) == -1 ||
fstat(fd1, &sb) == -1)
err(1, "%s", bpath);
if (n != MBRSIZE)
if ((boot0 = malloc(boot0_size = sb.st_size)) == NULL)
errx(1, "%s: unable to allocate read buffer", bpath);
if ((n = read(fd1, boot0, boot0_size)) == -1 || close(fd1))
err(1, "%s", bpath);
if (n != boot0_size)
errx(1, "%s: short read", bpath);
if (!boot0bs(buf))
if (!boot0bs(boot0))
errx(1, "%s: unknown or incompatible boot code", bpath);
memcpy(buf + OFF_PTBL, part, sizeof(part));
memcpy(boot0 + OFF_PTBL, part, sizeof(part));
}
if (d_arg != -1)
buf[OFF_DRIVE] = d_arg;
boot0[OFF_DRIVE] = d_arg;
if (m_arg != -1) {
buf[OFF_FLAGS] &= 0xf0;
buf[OFF_FLAGS] |= m_arg;
boot0[OFF_FLAGS] &= 0xf0;
boot0[OFF_FLAGS] |= m_arg;
}
if (o_flag) {
buf[OFF_FLAGS] &= o_and;
buf[OFF_FLAGS] |= o_or;
boot0[OFF_FLAGS] &= o_and;
boot0[OFF_FLAGS] |= o_or;
}
if (t_arg != -1)
mk2(buf + OFF_TICKS, t_arg);
mk2(boot0 + OFF_TICKS, t_arg);
if (up) {
if (lseek(fd, 0, SEEK_SET) == -1 ||
(n = write(fd, buf, MBRSIZE)) == -1 || close(fd))
(n = write(fd, boot0, boot0_size)) == -1 || close(fd))
err(1, "%s", disk);
if (n != MBRSIZE)
if (n != boot0_size)
errx(1, "%s: short write", disk);
}
if (v_flag) {
@ -201,20 +211,39 @@ main(int argc, char *argv[])
part[i].dp_size);
}
printf("\n");
printf("drive=0x%x mask=0x%x options=", buf[OFF_DRIVE],
buf[OFF_FLAGS] & 0xf);
version = boot0version(boot0);
printf("version=%d.%d drive=0x%x mask=0x%x ticks=%u\noptions=",
version >> 8, version & 0xff, boot0[OFF_DRIVE],
boot0[OFF_FLAGS] & 0xf, cv2(boot0 + OFF_TICKS));
for (i = 0; i < nopt; i++) {
if (i)
printf(",");
if (!(buf[OFF_FLAGS] & 1 << (7 - i)) ^ opttbl[i].def)
if (!(boot0[OFF_FLAGS] & 1 << (7 - i)) ^ opttbl[i].def)
printf("no");
printf("%s", opttbl[i].tok);
}
printf(" ticks=%u\n", cv2(buf + OFF_TICKS));
printf("\n");
}
return 0;
}
/*
* Return the boot0 version with the minor revision in the low byte, and
* the major revision in the next higher byte.
*/
static int
boot0version(const u_int8_t *bs)
{
static u_int8_t idold[] = {0xfe, 0x45, 0xf2, 0xe9, 0x00, 0x8a};
/* Check for old version, and return 0x100 if found. */
if (memcmp(bs + 0x1c, idold, sizeof(idold)) == 0)
return 0x100;
/* We have a newer boot0, so extract the version number and return it. */
return *(int *)(bs + OFF_VERSION) & 0xffff;
}
/*
* Decide if we have valid boot0 boot code by looking for
* characteristic byte sequences at fixed offsets.
@ -222,21 +251,24 @@ main(int argc, char *argv[])
static int
boot0bs(const u_int8_t *bs)
{
static u_int8_t id0[] = {0xfe, 0x45, 0xf2, 0xe9, 0x00, 0x8a};
static u_int8_t id0[] = {0xfc, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8,
0x8e, 0xd0, 0xbc, 0x00, 0x7c };
static u_int8_t id1[] = {'D', 'r', 'i', 'v', 'e', ' '};
static struct {
unsigned off;
unsigned len;
u_int8_t *key;
} ident[2] = {
{0x1c, sizeof(id0), id0},
{0x0, sizeof(id0), id0},
{0x1b2, sizeof(id1), id1}
};
int i;
for (i = 0; i < sizeof(ident) / sizeof(ident[0]); i++)
if (memcmp(bs + ident[i].off, ident[i].key, ident[i].len))
if (memcmp(bs + ident[i].off, ident[i].key, ident[i].len)) {
printf("bah, failed id%d\n", i);
return 0;
}
return 1;
};