summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2003-03-16 00:11:49 +0000
committerru <ru@FreeBSD.org>2003-03-16 00:11:49 +0000
commit6284f56b71dc65af96ac046fbc03f4e4ac47710a (patch)
tree8875ede793bf369b59bb09c10624e253bcea5438
parentbfdf0845f229df32dd8ae23b653835a8a3bbb02e (diff)
downloadFreeBSD-src-6284f56b71dc65af96ac046fbc03f4e4ac47710a.zip
FreeBSD-src-6284f56b71dc65af96ac046fbc03f4e4ac47710a.tar.gz
Teach disklabel(8) about different hardware architectures.
This is aimed at creating floppies during cross-releases. For different endianness machines, a tool like bswapfs(8) is necessary to make the generated floppies readable on the target machine. While here, fixed unaligned access on Alphas. Tested on: i386, alpha
-rw-r--r--sbin/bsdlabel/bsdlabel.869
-rw-r--r--sbin/bsdlabel/bsdlabel.c265
-rw-r--r--sbin/disklabel/disklabel.869
-rw-r--r--sbin/disklabel/disklabel.c265
4 files changed, 454 insertions, 214 deletions
diff --git a/sbin/bsdlabel/bsdlabel.8 b/sbin/bsdlabel/bsdlabel.8
index 6a57d40..3ca49ff 100644
--- a/sbin/bsdlabel/bsdlabel.8
+++ b/sbin/bsdlabel/bsdlabel.8
@@ -48,31 +48,37 @@
.Nm
.Fl w
.Op Fl nr
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Nm
.Fl e
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk
.Nm
.Fl R
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk protofile
.Pp
.Nm
.Fl B
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk
.Nm
.Fl w B
.Op Fl n
.Op Fl b Ar boot
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Nm
.Fl R B
.Op Fl n
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk protofile
.Sh DESCRIPTION
The
@@ -167,7 +173,8 @@ To write a standard label, use the form
.Nm
.Fl w
.Op Fl nr
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Pp
The required arguments to
@@ -187,6 +194,13 @@ The
.Ar packid
must be quoted if it contains blanks.
.Pp
+If the
+.Fl m
+option is given, then label will be written so that
+it is understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -199,7 +213,7 @@ will be written directly.
A side-effect of this is that any existing bootstrap code will be overwritten
and the disk rendered unbootable.
See the boot options below for a method of
-writing the label and the bootstrap at the same time.
+writing the and the bootstrap at the same time.
If
.Fl r
is not specified,
@@ -212,7 +226,7 @@ In either case, the kernel's in-core label is replaced.
.Pp
For a virgin disk that is not known to
.Xr disktab 5 ,
-.Ar disktype
+.Ar type
can be specified as
.Cm auto .
In this case, the driver is requested to produce a virgin label for the
@@ -270,6 +284,7 @@ To edit an existing disk label, use the form
.Nm
.Fl e
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk
.Pp
This command reads the label from the in-core kernel copy, or directly from the
@@ -288,6 +303,14 @@ When the editor terminates, the label file is used to rewrite the disk label.
Existing bootstrap code is unchanged regardless of whether
.Fl r
was specified.
+.Pp
+If the
+.Fl m
+option is given, then the label will be written so that
+it is understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -300,6 +323,7 @@ To restore a disk label from a file, use the form
.Nm
.Fl R
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk protofile
.Pp
.Nm
@@ -317,6 +341,14 @@ clobbered if
is specified, and will be unaffected otherwise.
See the boot options below for a
method of restoring the label and writing the bootstrap at the same time.
+.Pp
+If the
+.Fl m
+option is given, then the label will be written so that
+it is understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -345,6 +377,7 @@ on the base disk should probably be updated; see
.Nm
.Fl B
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk
.Pp
This form installs the bootstrap only.
@@ -357,11 +390,18 @@ disk.
This command is typically run on a slice such as
.Pa da0s1 .
.Pp
+The
+.Fl m
+option should be specified if the label was
+created for a different hardware architecture,
+.Ar machine .
+.Pp
.Nm
.Fl w B
.Op Fl n
.Op Fl b Ar boot
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Pp
This form corresponds to the
@@ -372,6 +412,14 @@ If run on a base disk, this command will create a
.Dq dangerously-dedicated
label.
This command is normally run on a slice rather than a base disk.
+.Pp
+If the
+.Fl m
+option is given, then the label and bootstrap will be written so that
+they are understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -381,6 +429,7 @@ disk label that would have been written will be printed to standard output.
.Fl R B
.Op Fl n
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk protofile
.Pp
This form corresponds to the
@@ -396,6 +445,14 @@ The bootstrap commands always access the disk directly, so it is not necessary
to specify the
.Fl r
option.
+.Pp
+If the
+.Fl m
+option is given, then the label and bootstrap will be written so that
+they are understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c
index 88604d3..49ada3c 100644
--- a/sbin/bsdlabel/bsdlabel.c
+++ b/sbin/bsdlabel/bsdlabel.c
@@ -64,11 +64,35 @@ __FBSDID("$FreeBSD$");
#define DKTYPENAMES
#define FSTYPENAMES
#include <sys/disklabel.h>
-#ifdef PC98
+
+#include <sys/diskmbr.h>
+#if (DOSPARTOFF != 446 || NDOSPART != 4 || DOSPTYP_386BSD != 0xa5)
+#error <sys/diskmbr.h> has changed
+#else
+#define I386_DOSPARTOFF 446
+#define I386_NDOSPART 4
+#define I386_DOSPTYP_386BSD 0xa5
+#endif
+#undef DOSPARTOFF
+#undef NDOSPART
+#undef DOSPTYP_386BSD
+
#include <sys/diskpc98.h>
+#if (DOSPARTOFF != 0 || NDOSPART != 16 || DOSPTYP_386BSD != 0x94)
+#error <sys/diskpc98.h> has changed
#else
-#include <sys/diskmbr.h>
+#define PC98_DOSPARTOFF 0
+#define PC98_NDOSPART 16
+#define PC98_DOSPTYP_386BSD 0x94
#endif
+#undef DOSPARTOFF
+#undef NDOSPART
+#undef DOSPTYP_386BSD
+
+#define IS_PC98 (arch->mach == MACH_PC98)
+#define DOSPARTOFF (IS_PC98 ? PC98_DOSPARTOFF : I386_DOSPARTOFF)
+#define NDOSPART (IS_PC98 ? PC98_NDOSPART : I386_NDOSPART)
+#define DOSPTYP_386BSD (IS_PC98 ? PC98_DOSPTYP_386BSD : I386_DOSPTYP_386BSD)
#include <unistd.h>
#include <string.h>
@@ -104,18 +128,11 @@ __FBSDID("$FreeBSD$");
#define BIG_NEWFS_FRAG 2048U
#define BIG_NEWFS_CPG 64U
-#if defined(__i386__)
-#elif defined(__alpha__)
-#elif defined(__ia64__)
-#else
-#error I do not know about this architecture, and shall probably not be compiled for it.
-#endif
-
void makelabel(const char *, const char *, struct disklabel *);
-int writelabel(int, const char *, struct disklabel *);
+int writelabel(int, void *, struct disklabel *);
void l_perror(const char *);
struct disklabel *readlabel(int);
-struct disklabel *makebootarea(char *, struct disklabel *, int);
+struct disklabel *makebootarea(void *, struct disklabel *, int);
void display(FILE *, const struct disklabel *);
int edit(struct disklabel *, int);
int editit(void);
@@ -137,7 +154,7 @@ char tmpfil[] = PATH_TMPFILE;
char namebuf[BBSIZE], *np = namebuf;
struct disklabel lab;
-char bootarea[BBSIZE];
+int64_t bootarea[BBSIZE / 8];
char blank[] = "";
char unknown[] = "unknown";
@@ -155,20 +172,36 @@ enum {
UNSPEC, EDIT, READ, RESTORE, WRITE, WRITEBOOT
} op = UNSPEC;
+enum { ARCH_I386, ARCH_ALPHA, ARCH_IA64 };
+
+enum { MACH_I386, MACH_PC98 };
+
+struct {
+ const char *name;
+ int arch;
+ int mach;
+ off_t label_sector;
+ off_t label_offset;
+} arches[] = {
+ { "i386", ARCH_I386, MACH_I386, 1, 0 },
+ { "pc98", ARCH_I386, MACH_PC98, 1, 0 },
+ { "alpha", ARCH_ALPHA, ARCH_ALPHA, 0, 64 },
+ { "ia64", ARCH_IA64, ARCH_IA64, 1, 0 },
+}, *arch;
+#define NARCHES (int)(sizeof(arches) / sizeof(*arches))
+
int rflag;
int disable_write; /* set to disable writing to disk label */
-#define OPTIONS "BRb:enrs:w"
-
int
main(int argc, char *argv[])
{
struct disklabel *lp;
FILE *t;
- int ch, f = 0, error = 0;
+ int ch, f = 0, error = 0, i;
char *name = 0;
- while ((ch = getopt(argc, argv, OPTIONS)) != -1)
+ while ((ch = getopt(argc, argv, "Bb:em:nRrs:w")) != -1)
switch (ch) {
case 'B':
++installboot;
@@ -176,6 +209,15 @@ main(int argc, char *argv[])
case 'b':
xxboot = optarg;
break;
+ case 'm':
+ for (i = 0; i < NARCHES &&
+ strcmp(arches[i].name, optarg) != 0;
+ i++);
+ if (i == NARCHES)
+ errx(1, "%s: unknown architecture",
+ optarg);
+ arch = &arches[i];
+ break;
case 'n':
disable_write = 1;
break;
@@ -215,6 +257,30 @@ main(int argc, char *argv[])
if (argc < 1)
usage();
+ if (arch == NULL) {
+ for (i = 0; i < NARCHES; i++)
+ if (strcmp(arches[i].name,
+#if defined(__i386__)
+#ifdef PC98
+ "pc98"
+#else
+ "i386"
+#endif
+#elif defined(__alpha__)
+ "alpha"
+#elif defined(__ia64__)
+ "ia64"
+#else
+ "unknown"
+#endif
+ ) == 0) {
+ arch = &arches[i];
+ break;
+ }
+ if (i == NARCHES)
+ errx(1, "unsupported architecture");
+ }
+
dkname = argv[0];
if (dkname[0] != '/') {
(void)sprintf(np, "%s%s%c", _PATH_DEV, dkname, 'a' + RAW_PART);
@@ -320,12 +386,10 @@ makelabel(const char *type, const char *name, struct disklabel *lp)
}
int
-writelabel(int f, const char *boot, struct disklabel *lp)
+writelabel(int f, void *boot, struct disklabel *lp)
{
-#ifdef __alpha__
- u_long *p, sum;
+ uint64_t *p, sum;
int i;
-#endif
if (disable_write) {
Warning("write to disk label supressed - label was as follows:");
@@ -360,14 +424,14 @@ writelabel(int f, const char *boot, struct disklabel *lp)
}
(void)lseek(f, (off_t)0, SEEK_SET);
-#ifdef __alpha__
- /*
- * Generate the bootblock checksum for the SRM console.
- */
- for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
- sum += p[i];
- p[63] = sum;
-#endif
+ if (arch->arch == ARCH_ALPHA) {
+ /*
+ * Generate the bootblock checksum for the SRM console.
+ */
+ for (p = (uint64_t *)boot, i = 0, sum = 0; i < 63; i++)
+ sum += p[i];
+ p[63] = sum;
+ }
if (ioctl(f, DIOCBSDBB, &boot) == 0)
return (0);
if (write(f, boot, lp->d_bbsize) != (int)lp->d_bbsize) {
@@ -420,12 +484,14 @@ readlabel(int f)
if (read(f, bootarea, BBSIZE) < BBSIZE)
err(4, "%s", specname);
for (lp = (struct disklabel *)bootarea;
- lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp));
+ lp <= (struct disklabel *)
+ ((char *)bootarea + BBSIZE - sizeof(*lp));
lp = (struct disklabel *)((char *)lp + 16))
if (lp->d_magic == DISKMAGIC &&
lp->d_magic2 == DISKMAGIC)
break;
- if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) ||
+ if (lp > (struct disklabel *)
+ ((char *)bootarea + BBSIZE - sizeof(*lp)) ||
lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
dkcksum(lp) != 0)
errx(1,
@@ -443,21 +509,17 @@ readlabel(int f)
* Returns a pointer to the disklabel portion of the bootarea.
*/
struct disklabel *
-makebootarea(char *boot, struct disklabel *dp, int f)
+makebootarea(void *boot, struct disklabel *dp, int f)
{
struct disklabel *lp;
char *p;
int b;
char *dkbasename;
struct stat sb;
-#ifdef __alpha__
- u_long *bootinfo;
+ uint64_t *bootinfo;
int n;
-#endif
-#ifdef __i386__
char *tmpbuf;
int i, found, dps;
-#endif
/* XXX */
if (dp->d_secsize == 0) {
@@ -465,7 +527,8 @@ makebootarea(char *boot, struct disklabel *dp, int f)
dp->d_bbsize = BBSIZE;
}
lp = (struct disklabel *)
- (boot + (LABELSECTOR * dp->d_secsize) + LABELOFFSET);
+ ((char *)boot + (arch->label_sector * dp->d_secsize) +
+ arch->label_offset);
bzero((char *)lp, sizeof *lp);
/*
* If we are not installing a boot program but we are installing a
@@ -505,57 +568,55 @@ makebootarea(char *boot, struct disklabel *dp, int f)
err(4, "%s", xxboot);
if (fstat(b, &sb) != 0)
err(4, "%s", xxboot);
-#ifdef __i386__
- if (sb.st_size > BBSIZE)
- errx(4, "%s too large", xxboot);
- /*
- * XXX Botch alert.
- * The i386/PC98 has the so-called fdisk table embedded into the
- * primary bootstrap. We take care to not clobber it, but
- * only if it does already contain some data. (Otherwise,
- * the xxboot provides a template.)
- */
- if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
- err(4, "%s", xxboot);
- memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
-
- if (read(b, boot, BBSIZE) < 0)
- err(4, "%s", xxboot);
+ if (arch->arch == ARCH_I386) {
+ if (sb.st_size > BBSIZE)
+ errx(4, "%s too large", xxboot);
+ /*
+ * XXX Botch alert.
+ * The i386/PC98 has the so-called fdisk table embedded into the
+ * primary bootstrap. We take care to not clobber it, but
+ * only if it does already contain some data. (Otherwise,
+ * the xxboot provides a template.)
+ */
+ if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
+ err(4, "%s", xxboot);
+ memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
+
+ if (read(b, boot, BBSIZE) < 0)
+ err(4, "%s", xxboot);
+
+ /* XXX: rely on some very precise overlaps in definitions */
+ dps = IS_PC98 ? sizeof(struct pc98_partition) :
+ sizeof(struct dos_partition);
+ for (i = DOSPARTOFF, found = 0;
+ !found && i < (int)(DOSPARTOFF + NDOSPART * dps);
+ i++)
+ found = tmpbuf[i] != 0;
+ if (found)
+ memcpy((void *)&((char *)boot)[DOSPARTOFF],
+ (void *)&tmpbuf[DOSPARTOFF],
+ NDOSPART * dps);
+ free(tmpbuf);
+ }
- /* XXX: rely on some very precise overlaps in definitions */
-#ifdef PC98
- dps = sizeof(struct pc98_partition);
-#else
- dps = sizeof(struct dos_partition);
-#endif
- for (i = DOSPARTOFF, found = 0;
- !found && i < (int)(DOSPARTOFF + NDOSPART * dps);
- i++)
- found = tmpbuf[i] != 0;
- if (found)
- memcpy((void *)&boot[DOSPARTOFF],
- (void *)&tmpbuf[DOSPARTOFF],
- NDOSPART * dps);
- free(tmpbuf);
-#endif /* __i386__ */
-
-#ifdef __alpha__
- if (sb.st_size > BBSIZE - dp->d_secsize)
- errx(4, "%s too large", xxboot);
- /*
- * On the alpha, the primary bootstrap starts at the
- * second sector of the boot area. The first sector
- * contains the label and must be edited to contain the
- * size and location of the primary bootstrap.
- */
- n = read(b, boot + dp->d_secsize, BBSIZE - dp->d_secsize);
- if (n < 0)
- err(4, "%s", xxboot);
- bootinfo = (u_long *)(boot + 480);
- bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
- bootinfo[1] = 1; /* start at sector 1 */
- bootinfo[2] = 0; /* flags (must be zero) */
-#endif /* __alpha__ */
+ if (arch->arch == ARCH_ALPHA) {
+ if (sb.st_size > BBSIZE - dp->d_secsize)
+ errx(4, "%s too large", xxboot);
+ /*
+ * On the alpha, the primary bootstrap starts at the
+ * second sector of the boot area. The first sector
+ * contains the label and must be edited to contain the
+ * size and location of the primary bootstrap.
+ */
+ n = read(b, (char *)boot + dp->d_secsize,
+ BBSIZE - dp->d_secsize);
+ if (n < 0)
+ err(4, "%s", xxboot);
+ bootinfo = (uint64_t *)((char *)boot + 480);
+ bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
+ bootinfo[1] = 1; /* start at sector 1 */
+ bootinfo[2] = 0; /* flags (must be zero) */
+ }
(void)close(b);
/*
@@ -1495,20 +1556,22 @@ Warning(const char *fmt, ...)
void
usage(void)
{
- fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
- "usage: disklabel [-r] disk",
- "\t\t(to read label)",
- " disklabel -w [-r] [-n] disk type [ packid ]",
- "\t\t(to write label with existing boot program)",
- " disklabel -e [-r] [-n] disk",
- "\t\t(to edit label)",
- " disklabel -R [-r] [-n] disk protofile",
- "\t\t(to restore label with existing boot program)",
- " disklabel -B [-n] [ -b bootprog ] disk [ type ]",
- "\t\t(to install boot program with existing on-disk label)",
- " disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
- "\t\t(to write label and install boot program)",
- " disklabel -R -B [-n] [ -b bootprog ] disk protofile",
+
+ fprintf(stderr,
+ "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+ "usage: disklabel [-r] disk",
+ "\t\t(to read label)",
+ " disklabel -w [-nr] [-m machine] disk type [packid]",
+ "\t\t(to write label with existing boot program)",
+ " disklabel -e [-nr] [-m machine] disk",
+ "\t\t(to edit label)",
+ " disklabel -R [-nr] [-m machine] disk protofile",
+ "\t\t(to restore label with existing boot program)",
+ " disklabel -B [-b boot] [-m machine] disk",
+ "\t\t(to install boot program with existing on-disk label)",
+ " disklabel -w -B [-n] [-b boot] [-m machine] disk type [packid]",
+ "\t\t(to write label and install boot program)",
+ " disklabel -R -B [-n] [-b boot] [-m machine] disk protofile",
"\t\t(to restore label and install boot program)"
);
exit(1);
diff --git a/sbin/disklabel/disklabel.8 b/sbin/disklabel/disklabel.8
index 6a57d40..3ca49ff 100644
--- a/sbin/disklabel/disklabel.8
+++ b/sbin/disklabel/disklabel.8
@@ -48,31 +48,37 @@
.Nm
.Fl w
.Op Fl nr
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Nm
.Fl e
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk
.Nm
.Fl R
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk protofile
.Pp
.Nm
.Fl B
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk
.Nm
.Fl w B
.Op Fl n
.Op Fl b Ar boot
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Nm
.Fl R B
.Op Fl n
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk protofile
.Sh DESCRIPTION
The
@@ -167,7 +173,8 @@ To write a standard label, use the form
.Nm
.Fl w
.Op Fl nr
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Pp
The required arguments to
@@ -187,6 +194,13 @@ The
.Ar packid
must be quoted if it contains blanks.
.Pp
+If the
+.Fl m
+option is given, then label will be written so that
+it is understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -199,7 +213,7 @@ will be written directly.
A side-effect of this is that any existing bootstrap code will be overwritten
and the disk rendered unbootable.
See the boot options below for a method of
-writing the label and the bootstrap at the same time.
+writing the and the bootstrap at the same time.
If
.Fl r
is not specified,
@@ -212,7 +226,7 @@ In either case, the kernel's in-core label is replaced.
.Pp
For a virgin disk that is not known to
.Xr disktab 5 ,
-.Ar disktype
+.Ar type
can be specified as
.Cm auto .
In this case, the driver is requested to produce a virgin label for the
@@ -270,6 +284,7 @@ To edit an existing disk label, use the form
.Nm
.Fl e
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk
.Pp
This command reads the label from the in-core kernel copy, or directly from the
@@ -288,6 +303,14 @@ When the editor terminates, the label file is used to rewrite the disk label.
Existing bootstrap code is unchanged regardless of whether
.Fl r
was specified.
+.Pp
+If the
+.Fl m
+option is given, then the label will be written so that
+it is understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -300,6 +323,7 @@ To restore a disk label from a file, use the form
.Nm
.Fl R
.Op Fl nr
+.Op Fl m Ar machine
.Ar disk protofile
.Pp
.Nm
@@ -317,6 +341,14 @@ clobbered if
is specified, and will be unaffected otherwise.
See the boot options below for a
method of restoring the label and writing the bootstrap at the same time.
+.Pp
+If the
+.Fl m
+option is given, then the label will be written so that
+it is understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -345,6 +377,7 @@ on the base disk should probably be updated; see
.Nm
.Fl B
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk
.Pp
This form installs the bootstrap only.
@@ -357,11 +390,18 @@ disk.
This command is typically run on a slice such as
.Pa da0s1 .
.Pp
+The
+.Fl m
+option should be specified if the label was
+created for a different hardware architecture,
+.Ar machine .
+.Pp
.Nm
.Fl w B
.Op Fl n
.Op Fl b Ar boot
-.Ar disk disktype Ns | Ns Cm auto
+.Op Fl m Ar machine
+.Ar disk type
.Op Ar packid
.Pp
This form corresponds to the
@@ -372,6 +412,14 @@ If run on a base disk, this command will create a
.Dq dangerously-dedicated
label.
This command is normally run on a slice rather than a base disk.
+.Pp
+If the
+.Fl m
+option is given, then the label and bootstrap will be written so that
+they are understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
@@ -381,6 +429,7 @@ disk label that would have been written will be printed to standard output.
.Fl R B
.Op Fl n
.Op Fl b Ar boot
+.Op Fl m Ar machine
.Ar disk protofile
.Pp
This form corresponds to the
@@ -396,6 +445,14 @@ The bootstrap commands always access the disk directly, so it is not necessary
to specify the
.Fl r
option.
+.Pp
+If the
+.Fl m
+option is given, then the label and bootstrap will be written so that
+they are understood by the target
+.Ar machine ;
+defaults to the current hardware architecture.
+.Pp
If
.Fl n
is used, no data will be written to the device, and instead the
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c
index 88604d3..49ada3c 100644
--- a/sbin/disklabel/disklabel.c
+++ b/sbin/disklabel/disklabel.c
@@ -64,11 +64,35 @@ __FBSDID("$FreeBSD$");
#define DKTYPENAMES
#define FSTYPENAMES
#include <sys/disklabel.h>
-#ifdef PC98
+
+#include <sys/diskmbr.h>
+#if (DOSPARTOFF != 446 || NDOSPART != 4 || DOSPTYP_386BSD != 0xa5)
+#error <sys/diskmbr.h> has changed
+#else
+#define I386_DOSPARTOFF 446
+#define I386_NDOSPART 4
+#define I386_DOSPTYP_386BSD 0xa5
+#endif
+#undef DOSPARTOFF
+#undef NDOSPART
+#undef DOSPTYP_386BSD
+
#include <sys/diskpc98.h>
+#if (DOSPARTOFF != 0 || NDOSPART != 16 || DOSPTYP_386BSD != 0x94)
+#error <sys/diskpc98.h> has changed
#else
-#include <sys/diskmbr.h>
+#define PC98_DOSPARTOFF 0
+#define PC98_NDOSPART 16
+#define PC98_DOSPTYP_386BSD 0x94
#endif
+#undef DOSPARTOFF
+#undef NDOSPART
+#undef DOSPTYP_386BSD
+
+#define IS_PC98 (arch->mach == MACH_PC98)
+#define DOSPARTOFF (IS_PC98 ? PC98_DOSPARTOFF : I386_DOSPARTOFF)
+#define NDOSPART (IS_PC98 ? PC98_NDOSPART : I386_NDOSPART)
+#define DOSPTYP_386BSD (IS_PC98 ? PC98_DOSPTYP_386BSD : I386_DOSPTYP_386BSD)
#include <unistd.h>
#include <string.h>
@@ -104,18 +128,11 @@ __FBSDID("$FreeBSD$");
#define BIG_NEWFS_FRAG 2048U
#define BIG_NEWFS_CPG 64U
-#if defined(__i386__)
-#elif defined(__alpha__)
-#elif defined(__ia64__)
-#else
-#error I do not know about this architecture, and shall probably not be compiled for it.
-#endif
-
void makelabel(const char *, const char *, struct disklabel *);
-int writelabel(int, const char *, struct disklabel *);
+int writelabel(int, void *, struct disklabel *);
void l_perror(const char *);
struct disklabel *readlabel(int);
-struct disklabel *makebootarea(char *, struct disklabel *, int);
+struct disklabel *makebootarea(void *, struct disklabel *, int);
void display(FILE *, const struct disklabel *);
int edit(struct disklabel *, int);
int editit(void);
@@ -137,7 +154,7 @@ char tmpfil[] = PATH_TMPFILE;
char namebuf[BBSIZE], *np = namebuf;
struct disklabel lab;
-char bootarea[BBSIZE];
+int64_t bootarea[BBSIZE / 8];
char blank[] = "";
char unknown[] = "unknown";
@@ -155,20 +172,36 @@ enum {
UNSPEC, EDIT, READ, RESTORE, WRITE, WRITEBOOT
} op = UNSPEC;
+enum { ARCH_I386, ARCH_ALPHA, ARCH_IA64 };
+
+enum { MACH_I386, MACH_PC98 };
+
+struct {
+ const char *name;
+ int arch;
+ int mach;
+ off_t label_sector;
+ off_t label_offset;
+} arches[] = {
+ { "i386", ARCH_I386, MACH_I386, 1, 0 },
+ { "pc98", ARCH_I386, MACH_PC98, 1, 0 },
+ { "alpha", ARCH_ALPHA, ARCH_ALPHA, 0, 64 },
+ { "ia64", ARCH_IA64, ARCH_IA64, 1, 0 },
+}, *arch;
+#define NARCHES (int)(sizeof(arches) / sizeof(*arches))
+
int rflag;
int disable_write; /* set to disable writing to disk label */
-#define OPTIONS "BRb:enrs:w"
-
int
main(int argc, char *argv[])
{
struct disklabel *lp;
FILE *t;
- int ch, f = 0, error = 0;
+ int ch, f = 0, error = 0, i;
char *name = 0;
- while ((ch = getopt(argc, argv, OPTIONS)) != -1)
+ while ((ch = getopt(argc, argv, "Bb:em:nRrs:w")) != -1)
switch (ch) {
case 'B':
++installboot;
@@ -176,6 +209,15 @@ main(int argc, char *argv[])
case 'b':
xxboot = optarg;
break;
+ case 'm':
+ for (i = 0; i < NARCHES &&
+ strcmp(arches[i].name, optarg) != 0;
+ i++);
+ if (i == NARCHES)
+ errx(1, "%s: unknown architecture",
+ optarg);
+ arch = &arches[i];
+ break;
case 'n':
disable_write = 1;
break;
@@ -215,6 +257,30 @@ main(int argc, char *argv[])
if (argc < 1)
usage();
+ if (arch == NULL) {
+ for (i = 0; i < NARCHES; i++)
+ if (strcmp(arches[i].name,
+#if defined(__i386__)
+#ifdef PC98
+ "pc98"
+#else
+ "i386"
+#endif
+#elif defined(__alpha__)
+ "alpha"
+#elif defined(__ia64__)
+ "ia64"
+#else
+ "unknown"
+#endif
+ ) == 0) {
+ arch = &arches[i];
+ break;
+ }
+ if (i == NARCHES)
+ errx(1, "unsupported architecture");
+ }
+
dkname = argv[0];
if (dkname[0] != '/') {
(void)sprintf(np, "%s%s%c", _PATH_DEV, dkname, 'a' + RAW_PART);
@@ -320,12 +386,10 @@ makelabel(const char *type, const char *name, struct disklabel *lp)
}
int
-writelabel(int f, const char *boot, struct disklabel *lp)
+writelabel(int f, void *boot, struct disklabel *lp)
{
-#ifdef __alpha__
- u_long *p, sum;
+ uint64_t *p, sum;
int i;
-#endif
if (disable_write) {
Warning("write to disk label supressed - label was as follows:");
@@ -360,14 +424,14 @@ writelabel(int f, const char *boot, struct disklabel *lp)
}
(void)lseek(f, (off_t)0, SEEK_SET);
-#ifdef __alpha__
- /*
- * Generate the bootblock checksum for the SRM console.
- */
- for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
- sum += p[i];
- p[63] = sum;
-#endif
+ if (arch->arch == ARCH_ALPHA) {
+ /*
+ * Generate the bootblock checksum for the SRM console.
+ */
+ for (p = (uint64_t *)boot, i = 0, sum = 0; i < 63; i++)
+ sum += p[i];
+ p[63] = sum;
+ }
if (ioctl(f, DIOCBSDBB, &boot) == 0)
return (0);
if (write(f, boot, lp->d_bbsize) != (int)lp->d_bbsize) {
@@ -420,12 +484,14 @@ readlabel(int f)
if (read(f, bootarea, BBSIZE) < BBSIZE)
err(4, "%s", specname);
for (lp = (struct disklabel *)bootarea;
- lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp));
+ lp <= (struct disklabel *)
+ ((char *)bootarea + BBSIZE - sizeof(*lp));
lp = (struct disklabel *)((char *)lp + 16))
if (lp->d_magic == DISKMAGIC &&
lp->d_magic2 == DISKMAGIC)
break;
- if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) ||
+ if (lp > (struct disklabel *)
+ ((char *)bootarea + BBSIZE - sizeof(*lp)) ||
lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
dkcksum(lp) != 0)
errx(1,
@@ -443,21 +509,17 @@ readlabel(int f)
* Returns a pointer to the disklabel portion of the bootarea.
*/
struct disklabel *
-makebootarea(char *boot, struct disklabel *dp, int f)
+makebootarea(void *boot, struct disklabel *dp, int f)
{
struct disklabel *lp;
char *p;
int b;
char *dkbasename;
struct stat sb;
-#ifdef __alpha__
- u_long *bootinfo;
+ uint64_t *bootinfo;
int n;
-#endif
-#ifdef __i386__
char *tmpbuf;
int i, found, dps;
-#endif
/* XXX */
if (dp->d_secsize == 0) {
@@ -465,7 +527,8 @@ makebootarea(char *boot, struct disklabel *dp, int f)
dp->d_bbsize = BBSIZE;
}
lp = (struct disklabel *)
- (boot + (LABELSECTOR * dp->d_secsize) + LABELOFFSET);
+ ((char *)boot + (arch->label_sector * dp->d_secsize) +
+ arch->label_offset);
bzero((char *)lp, sizeof *lp);
/*
* If we are not installing a boot program but we are installing a
@@ -505,57 +568,55 @@ makebootarea(char *boot, struct disklabel *dp, int f)
err(4, "%s", xxboot);
if (fstat(b, &sb) != 0)
err(4, "%s", xxboot);
-#ifdef __i386__
- if (sb.st_size > BBSIZE)
- errx(4, "%s too large", xxboot);
- /*
- * XXX Botch alert.
- * The i386/PC98 has the so-called fdisk table embedded into the
- * primary bootstrap. We take care to not clobber it, but
- * only if it does already contain some data. (Otherwise,
- * the xxboot provides a template.)
- */
- if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
- err(4, "%s", xxboot);
- memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
-
- if (read(b, boot, BBSIZE) < 0)
- err(4, "%s", xxboot);
+ if (arch->arch == ARCH_I386) {
+ if (sb.st_size > BBSIZE)
+ errx(4, "%s too large", xxboot);
+ /*
+ * XXX Botch alert.
+ * The i386/PC98 has the so-called fdisk table embedded into the
+ * primary bootstrap. We take care to not clobber it, but
+ * only if it does already contain some data. (Otherwise,
+ * the xxboot provides a template.)
+ */
+ if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
+ err(4, "%s", xxboot);
+ memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
+
+ if (read(b, boot, BBSIZE) < 0)
+ err(4, "%s", xxboot);
+
+ /* XXX: rely on some very precise overlaps in definitions */
+ dps = IS_PC98 ? sizeof(struct pc98_partition) :
+ sizeof(struct dos_partition);
+ for (i = DOSPARTOFF, found = 0;
+ !found && i < (int)(DOSPARTOFF + NDOSPART * dps);
+ i++)
+ found = tmpbuf[i] != 0;
+ if (found)
+ memcpy((void *)&((char *)boot)[DOSPARTOFF],
+ (void *)&tmpbuf[DOSPARTOFF],
+ NDOSPART * dps);
+ free(tmpbuf);
+ }
- /* XXX: rely on some very precise overlaps in definitions */
-#ifdef PC98
- dps = sizeof(struct pc98_partition);
-#else
- dps = sizeof(struct dos_partition);
-#endif
- for (i = DOSPARTOFF, found = 0;
- !found && i < (int)(DOSPARTOFF + NDOSPART * dps);
- i++)
- found = tmpbuf[i] != 0;
- if (found)
- memcpy((void *)&boot[DOSPARTOFF],
- (void *)&tmpbuf[DOSPARTOFF],
- NDOSPART * dps);
- free(tmpbuf);
-#endif /* __i386__ */
-
-#ifdef __alpha__
- if (sb.st_size > BBSIZE - dp->d_secsize)
- errx(4, "%s too large", xxboot);
- /*
- * On the alpha, the primary bootstrap starts at the
- * second sector of the boot area. The first sector
- * contains the label and must be edited to contain the
- * size and location of the primary bootstrap.
- */
- n = read(b, boot + dp->d_secsize, BBSIZE - dp->d_secsize);
- if (n < 0)
- err(4, "%s", xxboot);
- bootinfo = (u_long *)(boot + 480);
- bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
- bootinfo[1] = 1; /* start at sector 1 */
- bootinfo[2] = 0; /* flags (must be zero) */
-#endif /* __alpha__ */
+ if (arch->arch == ARCH_ALPHA) {
+ if (sb.st_size > BBSIZE - dp->d_secsize)
+ errx(4, "%s too large", xxboot);
+ /*
+ * On the alpha, the primary bootstrap starts at the
+ * second sector of the boot area. The first sector
+ * contains the label and must be edited to contain the
+ * size and location of the primary bootstrap.
+ */
+ n = read(b, (char *)boot + dp->d_secsize,
+ BBSIZE - dp->d_secsize);
+ if (n < 0)
+ err(4, "%s", xxboot);
+ bootinfo = (uint64_t *)((char *)boot + 480);
+ bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
+ bootinfo[1] = 1; /* start at sector 1 */
+ bootinfo[2] = 0; /* flags (must be zero) */
+ }
(void)close(b);
/*
@@ -1495,20 +1556,22 @@ Warning(const char *fmt, ...)
void
usage(void)
{
- fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
- "usage: disklabel [-r] disk",
- "\t\t(to read label)",
- " disklabel -w [-r] [-n] disk type [ packid ]",
- "\t\t(to write label with existing boot program)",
- " disklabel -e [-r] [-n] disk",
- "\t\t(to edit label)",
- " disklabel -R [-r] [-n] disk protofile",
- "\t\t(to restore label with existing boot program)",
- " disklabel -B [-n] [ -b bootprog ] disk [ type ]",
- "\t\t(to install boot program with existing on-disk label)",
- " disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
- "\t\t(to write label and install boot program)",
- " disklabel -R -B [-n] [ -b bootprog ] disk protofile",
+
+ fprintf(stderr,
+ "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+ "usage: disklabel [-r] disk",
+ "\t\t(to read label)",
+ " disklabel -w [-nr] [-m machine] disk type [packid]",
+ "\t\t(to write label with existing boot program)",
+ " disklabel -e [-nr] [-m machine] disk",
+ "\t\t(to edit label)",
+ " disklabel -R [-nr] [-m machine] disk protofile",
+ "\t\t(to restore label with existing boot program)",
+ " disklabel -B [-b boot] [-m machine] disk",
+ "\t\t(to install boot program with existing on-disk label)",
+ " disklabel -w -B [-n] [-b boot] [-m machine] disk type [packid]",
+ "\t\t(to write label and install boot program)",
+ " disklabel -R -B [-n] [-b boot] [-m machine] disk protofile",
"\t\t(to restore label and install boot program)"
);
exit(1);
OpenPOWER on IntegriCloud