diff options
author | jhb <jhb@FreeBSD.org> | 2000-07-12 18:15:06 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-07-12 18:15:06 +0000 |
commit | f965e9b8667ffdffde50c7c3a79573e2e493addc (patch) | |
tree | 2eaab744c0290a7c08ae103a23d077f2d0fb00be | |
parent | c9f5ee047975f546fd2889e98436b16beb80f99f (diff) | |
download | FreeBSD-src-f965e9b8667ffdffde50c7c3a79573e2e493addc.zip FreeBSD-src-f965e9b8667ffdffde50c7c3a79573e2e493addc.tar.gz |
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.
-rw-r--r-- | usr.sbin/boot0cfg/boot0cfg.c | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/usr.sbin/boot0cfg/boot0cfg.c b/usr.sbin/boot0cfg/boot0cfg.c index e755ef9..1da2692 100644 --- a/usr.sbin/boot0cfg/boot0cfg.c +++ b/usr.sbin/boot0cfg/boot0cfg.c @@ -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,42 +211,64 @@ 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. */ 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; }; |