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
This commit is contained in:
parent
d647b74e54
commit
bc33ea1acc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112307
@ -48,31 +48,37 @@
|
|||||||
.Nm
|
.Nm
|
||||||
.Fl w
|
.Fl w
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Nm
|
.Nm
|
||||||
.Fl e
|
.Fl e
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Nm
|
.Nm
|
||||||
.Fl R
|
.Fl R
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
.Fl B
|
.Fl B
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Nm
|
.Nm
|
||||||
.Fl w B
|
.Fl w B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Nm
|
.Nm
|
||||||
.Fl R B
|
.Fl R B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
@ -167,7 +173,8 @@ To write a standard label, use the form
|
|||||||
.Nm
|
.Nm
|
||||||
.Fl w
|
.Fl w
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Pp
|
.Pp
|
||||||
The required arguments to
|
The required arguments to
|
||||||
@ -187,6 +194,13 @@ The
|
|||||||
.Ar packid
|
.Ar packid
|
||||||
must be quoted if it contains blanks.
|
must be quoted if it contains blanks.
|
||||||
.Pp
|
.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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
A side-effect of this is that any existing bootstrap code will be overwritten
|
||||||
and the disk rendered unbootable.
|
and the disk rendered unbootable.
|
||||||
See the boot options below for a method of
|
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
|
If
|
||||||
.Fl r
|
.Fl r
|
||||||
is not specified,
|
is not specified,
|
||||||
@ -212,7 +226,7 @@ In either case, the kernel's in-core label is replaced.
|
|||||||
.Pp
|
.Pp
|
||||||
For a virgin disk that is not known to
|
For a virgin disk that is not known to
|
||||||
.Xr disktab 5 ,
|
.Xr disktab 5 ,
|
||||||
.Ar disktype
|
.Ar type
|
||||||
can be specified as
|
can be specified as
|
||||||
.Cm auto .
|
.Cm auto .
|
||||||
In this case, the driver is requested to produce a virgin label for the
|
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
|
.Nm
|
||||||
.Fl e
|
.Fl e
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Pp
|
.Pp
|
||||||
This command reads the label from the in-core kernel copy, or directly from the
|
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
|
Existing bootstrap code is unchanged regardless of whether
|
||||||
.Fl r
|
.Fl r
|
||||||
was specified.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
.Nm
|
||||||
.Fl R
|
.Fl R
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
@ -317,6 +341,14 @@ clobbered if
|
|||||||
is specified, and will be unaffected otherwise.
|
is specified, and will be unaffected otherwise.
|
||||||
See the boot options below for a
|
See the boot options below for a
|
||||||
method of restoring the label and writing the bootstrap at the same time.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
.Nm
|
||||||
.Fl B
|
.Fl B
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Pp
|
.Pp
|
||||||
This form installs the bootstrap only.
|
This form installs the bootstrap only.
|
||||||
@ -357,11 +390,18 @@ disk.
|
|||||||
This command is typically run on a slice such as
|
This command is typically run on a slice such as
|
||||||
.Pa da0s1 .
|
.Pa da0s1 .
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl m
|
||||||
|
option should be specified if the label was
|
||||||
|
created for a different hardware architecture,
|
||||||
|
.Ar machine .
|
||||||
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
.Fl w B
|
.Fl w B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Pp
|
.Pp
|
||||||
This form corresponds to the
|
This form corresponds to the
|
||||||
@ -372,6 +412,14 @@ If run on a base disk, this command will create a
|
|||||||
.Dq dangerously-dedicated
|
.Dq dangerously-dedicated
|
||||||
label.
|
label.
|
||||||
This command is normally run on a slice rather than a base disk.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
.Fl R B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Pp
|
.Pp
|
||||||
This form corresponds to the
|
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
|
to specify the
|
||||||
.Fl r
|
.Fl r
|
||||||
option.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
is used, no data will be written to the device, and instead the
|
||||||
|
@ -64,11 +64,35 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define DKTYPENAMES
|
#define DKTYPENAMES
|
||||||
#define FSTYPENAMES
|
#define FSTYPENAMES
|
||||||
#include <sys/disklabel.h>
|
#include <sys/disklabel.h>
|
||||||
#ifdef PC98
|
|
||||||
#include <sys/diskpc98.h>
|
|
||||||
#else
|
|
||||||
#include <sys/diskmbr.h>
|
#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
|
#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
|
||||||
|
#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 <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -104,18 +128,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define BIG_NEWFS_FRAG 2048U
|
#define BIG_NEWFS_FRAG 2048U
|
||||||
#define BIG_NEWFS_CPG 64U
|
#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 *);
|
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 *);
|
void l_perror(const char *);
|
||||||
struct disklabel *readlabel(int);
|
struct disklabel *readlabel(int);
|
||||||
struct disklabel *makebootarea(char *, struct disklabel *, int);
|
struct disklabel *makebootarea(void *, struct disklabel *, int);
|
||||||
void display(FILE *, const struct disklabel *);
|
void display(FILE *, const struct disklabel *);
|
||||||
int edit(struct disklabel *, int);
|
int edit(struct disklabel *, int);
|
||||||
int editit(void);
|
int editit(void);
|
||||||
@ -137,7 +154,7 @@ char tmpfil[] = PATH_TMPFILE;
|
|||||||
|
|
||||||
char namebuf[BBSIZE], *np = namebuf;
|
char namebuf[BBSIZE], *np = namebuf;
|
||||||
struct disklabel lab;
|
struct disklabel lab;
|
||||||
char bootarea[BBSIZE];
|
int64_t bootarea[BBSIZE / 8];
|
||||||
char blank[] = "";
|
char blank[] = "";
|
||||||
char unknown[] = "unknown";
|
char unknown[] = "unknown";
|
||||||
|
|
||||||
@ -155,20 +172,36 @@ enum {
|
|||||||
UNSPEC, EDIT, READ, RESTORE, WRITE, WRITEBOOT
|
UNSPEC, EDIT, READ, RESTORE, WRITE, WRITEBOOT
|
||||||
} op = UNSPEC;
|
} 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 rflag;
|
||||||
int disable_write; /* set to disable writing to disk label */
|
int disable_write; /* set to disable writing to disk label */
|
||||||
|
|
||||||
#define OPTIONS "BRb:enrs:w"
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct disklabel *lp;
|
struct disklabel *lp;
|
||||||
FILE *t;
|
FILE *t;
|
||||||
int ch, f = 0, error = 0;
|
int ch, f = 0, error = 0, i;
|
||||||
char *name = 0;
|
char *name = 0;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
|
while ((ch = getopt(argc, argv, "Bb:em:nRrs:w")) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'B':
|
case 'B':
|
||||||
++installboot;
|
++installboot;
|
||||||
@ -176,6 +209,15 @@ main(int argc, char *argv[])
|
|||||||
case 'b':
|
case 'b':
|
||||||
xxboot = optarg;
|
xxboot = optarg;
|
||||||
break;
|
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':
|
case 'n':
|
||||||
disable_write = 1;
|
disable_write = 1;
|
||||||
break;
|
break;
|
||||||
@ -215,6 +257,30 @@ main(int argc, char *argv[])
|
|||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
usage();
|
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];
|
dkname = argv[0];
|
||||||
if (dkname[0] != '/') {
|
if (dkname[0] != '/') {
|
||||||
(void)sprintf(np, "%s%s%c", _PATH_DEV, dkname, 'a' + RAW_PART);
|
(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
|
int
|
||||||
writelabel(int f, const char *boot, struct disklabel *lp)
|
writelabel(int f, void *boot, struct disklabel *lp)
|
||||||
{
|
{
|
||||||
#ifdef __alpha__
|
uint64_t *p, sum;
|
||||||
u_long *p, sum;
|
|
||||||
int i;
|
int i;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (disable_write) {
|
if (disable_write) {
|
||||||
Warning("write to disk label supressed - label was as follows:");
|
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);
|
(void)lseek(f, (off_t)0, SEEK_SET);
|
||||||
|
|
||||||
#ifdef __alpha__
|
if (arch->arch == ARCH_ALPHA) {
|
||||||
/*
|
/*
|
||||||
* Generate the bootblock checksum for the SRM console.
|
* Generate the bootblock checksum for the SRM console.
|
||||||
*/
|
*/
|
||||||
for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
|
for (p = (uint64_t *)boot, i = 0, sum = 0; i < 63; i++)
|
||||||
sum += p[i];
|
sum += p[i];
|
||||||
p[63] = sum;
|
p[63] = sum;
|
||||||
#endif
|
}
|
||||||
if (ioctl(f, DIOCBSDBB, &boot) == 0)
|
if (ioctl(f, DIOCBSDBB, &boot) == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (write(f, boot, lp->d_bbsize) != (int)lp->d_bbsize) {
|
if (write(f, boot, lp->d_bbsize) != (int)lp->d_bbsize) {
|
||||||
@ -420,12 +484,14 @@ readlabel(int f)
|
|||||||
if (read(f, bootarea, BBSIZE) < BBSIZE)
|
if (read(f, bootarea, BBSIZE) < BBSIZE)
|
||||||
err(4, "%s", specname);
|
err(4, "%s", specname);
|
||||||
for (lp = (struct disklabel *)bootarea;
|
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))
|
lp = (struct disklabel *)((char *)lp + 16))
|
||||||
if (lp->d_magic == DISKMAGIC &&
|
if (lp->d_magic == DISKMAGIC &&
|
||||||
lp->d_magic2 == DISKMAGIC)
|
lp->d_magic2 == DISKMAGIC)
|
||||||
break;
|
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 ||
|
lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
|
||||||
dkcksum(lp) != 0)
|
dkcksum(lp) != 0)
|
||||||
errx(1,
|
errx(1,
|
||||||
@ -443,21 +509,17 @@ readlabel(int f)
|
|||||||
* Returns a pointer to the disklabel portion of the bootarea.
|
* Returns a pointer to the disklabel portion of the bootarea.
|
||||||
*/
|
*/
|
||||||
struct disklabel *
|
struct disklabel *
|
||||||
makebootarea(char *boot, struct disklabel *dp, int f)
|
makebootarea(void *boot, struct disklabel *dp, int f)
|
||||||
{
|
{
|
||||||
struct disklabel *lp;
|
struct disklabel *lp;
|
||||||
char *p;
|
char *p;
|
||||||
int b;
|
int b;
|
||||||
char *dkbasename;
|
char *dkbasename;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
#ifdef __alpha__
|
uint64_t *bootinfo;
|
||||||
u_long *bootinfo;
|
|
||||||
int n;
|
int n;
|
||||||
#endif
|
|
||||||
#ifdef __i386__
|
|
||||||
char *tmpbuf;
|
char *tmpbuf;
|
||||||
int i, found, dps;
|
int i, found, dps;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* XXX */
|
/* XXX */
|
||||||
if (dp->d_secsize == 0) {
|
if (dp->d_secsize == 0) {
|
||||||
@ -465,7 +527,8 @@ makebootarea(char *boot, struct disklabel *dp, int f)
|
|||||||
dp->d_bbsize = BBSIZE;
|
dp->d_bbsize = BBSIZE;
|
||||||
}
|
}
|
||||||
lp = (struct disklabel *)
|
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);
|
bzero((char *)lp, sizeof *lp);
|
||||||
/*
|
/*
|
||||||
* If we are not installing a boot program but we are installing a
|
* 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);
|
err(4, "%s", xxboot);
|
||||||
if (fstat(b, &sb) != 0)
|
if (fstat(b, &sb) != 0)
|
||||||
err(4, "%s", xxboot);
|
err(4, "%s", xxboot);
|
||||||
#ifdef __i386__
|
if (arch->arch == ARCH_I386) {
|
||||||
if (sb.st_size > BBSIZE)
|
if (sb.st_size > BBSIZE)
|
||||||
errx(4, "%s too large", xxboot);
|
errx(4, "%s too large", xxboot);
|
||||||
/*
|
/*
|
||||||
* XXX Botch alert.
|
* XXX Botch alert.
|
||||||
* The i386/PC98 has the so-called fdisk table embedded into the
|
* The i386/PC98 has the so-called fdisk table embedded into the
|
||||||
* primary bootstrap. We take care to not clobber it, but
|
* primary bootstrap. We take care to not clobber it, but
|
||||||
* only if it does already contain some data. (Otherwise,
|
* only if it does already contain some data. (Otherwise,
|
||||||
* the xxboot provides a template.)
|
* the xxboot provides a template.)
|
||||||
*/
|
*/
|
||||||
if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
|
if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
|
||||||
err(4, "%s", xxboot);
|
err(4, "%s", xxboot);
|
||||||
memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
|
memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
|
||||||
|
|
||||||
if (read(b, boot, BBSIZE) < 0)
|
if (read(b, boot, BBSIZE) < 0)
|
||||||
err(4, "%s", xxboot);
|
err(4, "%s", xxboot);
|
||||||
|
|
||||||
/* XXX: rely on some very precise overlaps in definitions */
|
/* XXX: rely on some very precise overlaps in definitions */
|
||||||
#ifdef PC98
|
dps = IS_PC98 ? sizeof(struct pc98_partition) :
|
||||||
dps = sizeof(struct pc98_partition);
|
sizeof(struct dos_partition);
|
||||||
#else
|
for (i = DOSPARTOFF, found = 0;
|
||||||
dps = sizeof(struct dos_partition);
|
!found && i < (int)(DOSPARTOFF + NDOSPART * dps);
|
||||||
#endif
|
i++)
|
||||||
for (i = DOSPARTOFF, found = 0;
|
found = tmpbuf[i] != 0;
|
||||||
!found && i < (int)(DOSPARTOFF + NDOSPART * dps);
|
if (found)
|
||||||
i++)
|
memcpy((void *)&((char *)boot)[DOSPARTOFF],
|
||||||
found = tmpbuf[i] != 0;
|
(void *)&tmpbuf[DOSPARTOFF],
|
||||||
if (found)
|
NDOSPART * dps);
|
||||||
memcpy((void *)&boot[DOSPARTOFF],
|
free(tmpbuf);
|
||||||
(void *)&tmpbuf[DOSPARTOFF],
|
}
|
||||||
NDOSPART * dps);
|
|
||||||
free(tmpbuf);
|
|
||||||
#endif /* __i386__ */
|
|
||||||
|
|
||||||
#ifdef __alpha__
|
if (arch->arch == ARCH_ALPHA) {
|
||||||
if (sb.st_size > BBSIZE - dp->d_secsize)
|
if (sb.st_size > BBSIZE - dp->d_secsize)
|
||||||
errx(4, "%s too large", xxboot);
|
errx(4, "%s too large", xxboot);
|
||||||
/*
|
/*
|
||||||
* On the alpha, the primary bootstrap starts at the
|
* On the alpha, the primary bootstrap starts at the
|
||||||
* second sector of the boot area. The first sector
|
* second sector of the boot area. The first sector
|
||||||
* contains the label and must be edited to contain the
|
* contains the label and must be edited to contain the
|
||||||
* size and location of the primary bootstrap.
|
* size and location of the primary bootstrap.
|
||||||
*/
|
*/
|
||||||
n = read(b, boot + dp->d_secsize, BBSIZE - dp->d_secsize);
|
n = read(b, (char *)boot + dp->d_secsize,
|
||||||
if (n < 0)
|
BBSIZE - dp->d_secsize);
|
||||||
err(4, "%s", xxboot);
|
if (n < 0)
|
||||||
bootinfo = (u_long *)(boot + 480);
|
err(4, "%s", xxboot);
|
||||||
bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
|
bootinfo = (uint64_t *)((char *)boot + 480);
|
||||||
bootinfo[1] = 1; /* start at sector 1 */
|
bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
|
||||||
bootinfo[2] = 0; /* flags (must be zero) */
|
bootinfo[1] = 1; /* start at sector 1 */
|
||||||
#endif /* __alpha__ */
|
bootinfo[2] = 0; /* flags (must be zero) */
|
||||||
|
}
|
||||||
|
|
||||||
(void)close(b);
|
(void)close(b);
|
||||||
/*
|
/*
|
||||||
@ -1495,20 +1556,22 @@ Warning(const char *fmt, ...)
|
|||||||
void
|
void
|
||||||
usage(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",
|
fprintf(stderr,
|
||||||
"\t\t(to read label)",
|
"%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",
|
||||||
" disklabel -w [-r] [-n] disk type [ packid ]",
|
"usage: disklabel [-r] disk",
|
||||||
"\t\t(to write label with existing boot program)",
|
"\t\t(to read label)",
|
||||||
" disklabel -e [-r] [-n] disk",
|
" disklabel -w [-nr] [-m machine] disk type [packid]",
|
||||||
"\t\t(to edit label)",
|
"\t\t(to write label with existing boot program)",
|
||||||
" disklabel -R [-r] [-n] disk protofile",
|
" disklabel -e [-nr] [-m machine] disk",
|
||||||
"\t\t(to restore label with existing boot program)",
|
"\t\t(to edit label)",
|
||||||
" disklabel -B [-n] [ -b bootprog ] disk [ type ]",
|
" disklabel -R [-nr] [-m machine] disk protofile",
|
||||||
"\t\t(to install boot program with existing on-disk label)",
|
"\t\t(to restore label with existing boot program)",
|
||||||
" disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
|
" disklabel -B [-b boot] [-m machine] disk",
|
||||||
"\t\t(to write label and install boot program)",
|
"\t\t(to install boot program with existing on-disk label)",
|
||||||
" disklabel -R -B [-n] [ -b bootprog ] disk protofile",
|
" 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)"
|
"\t\t(to restore label and install boot program)"
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -48,31 +48,37 @@
|
|||||||
.Nm
|
.Nm
|
||||||
.Fl w
|
.Fl w
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Nm
|
.Nm
|
||||||
.Fl e
|
.Fl e
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Nm
|
.Nm
|
||||||
.Fl R
|
.Fl R
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
.Fl B
|
.Fl B
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Nm
|
.Nm
|
||||||
.Fl w B
|
.Fl w B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Nm
|
.Nm
|
||||||
.Fl R B
|
.Fl R B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
@ -167,7 +173,8 @@ To write a standard label, use the form
|
|||||||
.Nm
|
.Nm
|
||||||
.Fl w
|
.Fl w
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Pp
|
.Pp
|
||||||
The required arguments to
|
The required arguments to
|
||||||
@ -187,6 +194,13 @@ The
|
|||||||
.Ar packid
|
.Ar packid
|
||||||
must be quoted if it contains blanks.
|
must be quoted if it contains blanks.
|
||||||
.Pp
|
.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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
A side-effect of this is that any existing bootstrap code will be overwritten
|
||||||
and the disk rendered unbootable.
|
and the disk rendered unbootable.
|
||||||
See the boot options below for a method of
|
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
|
If
|
||||||
.Fl r
|
.Fl r
|
||||||
is not specified,
|
is not specified,
|
||||||
@ -212,7 +226,7 @@ In either case, the kernel's in-core label is replaced.
|
|||||||
.Pp
|
.Pp
|
||||||
For a virgin disk that is not known to
|
For a virgin disk that is not known to
|
||||||
.Xr disktab 5 ,
|
.Xr disktab 5 ,
|
||||||
.Ar disktype
|
.Ar type
|
||||||
can be specified as
|
can be specified as
|
||||||
.Cm auto .
|
.Cm auto .
|
||||||
In this case, the driver is requested to produce a virgin label for the
|
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
|
.Nm
|
||||||
.Fl e
|
.Fl e
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Pp
|
.Pp
|
||||||
This command reads the label from the in-core kernel copy, or directly from the
|
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
|
Existing bootstrap code is unchanged regardless of whether
|
||||||
.Fl r
|
.Fl r
|
||||||
was specified.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
.Nm
|
||||||
.Fl R
|
.Fl R
|
||||||
.Op Fl nr
|
.Op Fl nr
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
@ -317,6 +341,14 @@ clobbered if
|
|||||||
is specified, and will be unaffected otherwise.
|
is specified, and will be unaffected otherwise.
|
||||||
See the boot options below for a
|
See the boot options below for a
|
||||||
method of restoring the label and writing the bootstrap at the same time.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
.Nm
|
||||||
.Fl B
|
.Fl B
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk
|
.Ar disk
|
||||||
.Pp
|
.Pp
|
||||||
This form installs the bootstrap only.
|
This form installs the bootstrap only.
|
||||||
@ -357,11 +390,18 @@ disk.
|
|||||||
This command is typically run on a slice such as
|
This command is typically run on a slice such as
|
||||||
.Pa da0s1 .
|
.Pa da0s1 .
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl m
|
||||||
|
option should be specified if the label was
|
||||||
|
created for a different hardware architecture,
|
||||||
|
.Ar machine .
|
||||||
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
.Fl w B
|
.Fl w B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
.Ar disk disktype Ns | Ns Cm auto
|
.Op Fl m Ar machine
|
||||||
|
.Ar disk type
|
||||||
.Op Ar packid
|
.Op Ar packid
|
||||||
.Pp
|
.Pp
|
||||||
This form corresponds to the
|
This form corresponds to the
|
||||||
@ -372,6 +412,14 @@ If run on a base disk, this command will create a
|
|||||||
.Dq dangerously-dedicated
|
.Dq dangerously-dedicated
|
||||||
label.
|
label.
|
||||||
This command is normally run on a slice rather than a base disk.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
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
|
.Fl R B
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl b Ar boot
|
.Op Fl b Ar boot
|
||||||
|
.Op Fl m Ar machine
|
||||||
.Ar disk protofile
|
.Ar disk protofile
|
||||||
.Pp
|
.Pp
|
||||||
This form corresponds to the
|
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
|
to specify the
|
||||||
.Fl r
|
.Fl r
|
||||||
option.
|
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
|
If
|
||||||
.Fl n
|
.Fl n
|
||||||
is used, no data will be written to the device, and instead the
|
is used, no data will be written to the device, and instead the
|
||||||
|
@ -64,11 +64,35 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define DKTYPENAMES
|
#define DKTYPENAMES
|
||||||
#define FSTYPENAMES
|
#define FSTYPENAMES
|
||||||
#include <sys/disklabel.h>
|
#include <sys/disklabel.h>
|
||||||
#ifdef PC98
|
|
||||||
#include <sys/diskpc98.h>
|
|
||||||
#else
|
|
||||||
#include <sys/diskmbr.h>
|
#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
|
#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
|
||||||
|
#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 <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -104,18 +128,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define BIG_NEWFS_FRAG 2048U
|
#define BIG_NEWFS_FRAG 2048U
|
||||||
#define BIG_NEWFS_CPG 64U
|
#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 *);
|
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 *);
|
void l_perror(const char *);
|
||||||
struct disklabel *readlabel(int);
|
struct disklabel *readlabel(int);
|
||||||
struct disklabel *makebootarea(char *, struct disklabel *, int);
|
struct disklabel *makebootarea(void *, struct disklabel *, int);
|
||||||
void display(FILE *, const struct disklabel *);
|
void display(FILE *, const struct disklabel *);
|
||||||
int edit(struct disklabel *, int);
|
int edit(struct disklabel *, int);
|
||||||
int editit(void);
|
int editit(void);
|
||||||
@ -137,7 +154,7 @@ char tmpfil[] = PATH_TMPFILE;
|
|||||||
|
|
||||||
char namebuf[BBSIZE], *np = namebuf;
|
char namebuf[BBSIZE], *np = namebuf;
|
||||||
struct disklabel lab;
|
struct disklabel lab;
|
||||||
char bootarea[BBSIZE];
|
int64_t bootarea[BBSIZE / 8];
|
||||||
char blank[] = "";
|
char blank[] = "";
|
||||||
char unknown[] = "unknown";
|
char unknown[] = "unknown";
|
||||||
|
|
||||||
@ -155,20 +172,36 @@ enum {
|
|||||||
UNSPEC, EDIT, READ, RESTORE, WRITE, WRITEBOOT
|
UNSPEC, EDIT, READ, RESTORE, WRITE, WRITEBOOT
|
||||||
} op = UNSPEC;
|
} 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 rflag;
|
||||||
int disable_write; /* set to disable writing to disk label */
|
int disable_write; /* set to disable writing to disk label */
|
||||||
|
|
||||||
#define OPTIONS "BRb:enrs:w"
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct disklabel *lp;
|
struct disklabel *lp;
|
||||||
FILE *t;
|
FILE *t;
|
||||||
int ch, f = 0, error = 0;
|
int ch, f = 0, error = 0, i;
|
||||||
char *name = 0;
|
char *name = 0;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
|
while ((ch = getopt(argc, argv, "Bb:em:nRrs:w")) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'B':
|
case 'B':
|
||||||
++installboot;
|
++installboot;
|
||||||
@ -176,6 +209,15 @@ main(int argc, char *argv[])
|
|||||||
case 'b':
|
case 'b':
|
||||||
xxboot = optarg;
|
xxboot = optarg;
|
||||||
break;
|
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':
|
case 'n':
|
||||||
disable_write = 1;
|
disable_write = 1;
|
||||||
break;
|
break;
|
||||||
@ -215,6 +257,30 @@ main(int argc, char *argv[])
|
|||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
usage();
|
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];
|
dkname = argv[0];
|
||||||
if (dkname[0] != '/') {
|
if (dkname[0] != '/') {
|
||||||
(void)sprintf(np, "%s%s%c", _PATH_DEV, dkname, 'a' + RAW_PART);
|
(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
|
int
|
||||||
writelabel(int f, const char *boot, struct disklabel *lp)
|
writelabel(int f, void *boot, struct disklabel *lp)
|
||||||
{
|
{
|
||||||
#ifdef __alpha__
|
uint64_t *p, sum;
|
||||||
u_long *p, sum;
|
|
||||||
int i;
|
int i;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (disable_write) {
|
if (disable_write) {
|
||||||
Warning("write to disk label supressed - label was as follows:");
|
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);
|
(void)lseek(f, (off_t)0, SEEK_SET);
|
||||||
|
|
||||||
#ifdef __alpha__
|
if (arch->arch == ARCH_ALPHA) {
|
||||||
/*
|
/*
|
||||||
* Generate the bootblock checksum for the SRM console.
|
* Generate the bootblock checksum for the SRM console.
|
||||||
*/
|
*/
|
||||||
for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
|
for (p = (uint64_t *)boot, i = 0, sum = 0; i < 63; i++)
|
||||||
sum += p[i];
|
sum += p[i];
|
||||||
p[63] = sum;
|
p[63] = sum;
|
||||||
#endif
|
}
|
||||||
if (ioctl(f, DIOCBSDBB, &boot) == 0)
|
if (ioctl(f, DIOCBSDBB, &boot) == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (write(f, boot, lp->d_bbsize) != (int)lp->d_bbsize) {
|
if (write(f, boot, lp->d_bbsize) != (int)lp->d_bbsize) {
|
||||||
@ -420,12 +484,14 @@ readlabel(int f)
|
|||||||
if (read(f, bootarea, BBSIZE) < BBSIZE)
|
if (read(f, bootarea, BBSIZE) < BBSIZE)
|
||||||
err(4, "%s", specname);
|
err(4, "%s", specname);
|
||||||
for (lp = (struct disklabel *)bootarea;
|
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))
|
lp = (struct disklabel *)((char *)lp + 16))
|
||||||
if (lp->d_magic == DISKMAGIC &&
|
if (lp->d_magic == DISKMAGIC &&
|
||||||
lp->d_magic2 == DISKMAGIC)
|
lp->d_magic2 == DISKMAGIC)
|
||||||
break;
|
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 ||
|
lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
|
||||||
dkcksum(lp) != 0)
|
dkcksum(lp) != 0)
|
||||||
errx(1,
|
errx(1,
|
||||||
@ -443,21 +509,17 @@ readlabel(int f)
|
|||||||
* Returns a pointer to the disklabel portion of the bootarea.
|
* Returns a pointer to the disklabel portion of the bootarea.
|
||||||
*/
|
*/
|
||||||
struct disklabel *
|
struct disklabel *
|
||||||
makebootarea(char *boot, struct disklabel *dp, int f)
|
makebootarea(void *boot, struct disklabel *dp, int f)
|
||||||
{
|
{
|
||||||
struct disklabel *lp;
|
struct disklabel *lp;
|
||||||
char *p;
|
char *p;
|
||||||
int b;
|
int b;
|
||||||
char *dkbasename;
|
char *dkbasename;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
#ifdef __alpha__
|
uint64_t *bootinfo;
|
||||||
u_long *bootinfo;
|
|
||||||
int n;
|
int n;
|
||||||
#endif
|
|
||||||
#ifdef __i386__
|
|
||||||
char *tmpbuf;
|
char *tmpbuf;
|
||||||
int i, found, dps;
|
int i, found, dps;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* XXX */
|
/* XXX */
|
||||||
if (dp->d_secsize == 0) {
|
if (dp->d_secsize == 0) {
|
||||||
@ -465,7 +527,8 @@ makebootarea(char *boot, struct disklabel *dp, int f)
|
|||||||
dp->d_bbsize = BBSIZE;
|
dp->d_bbsize = BBSIZE;
|
||||||
}
|
}
|
||||||
lp = (struct disklabel *)
|
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);
|
bzero((char *)lp, sizeof *lp);
|
||||||
/*
|
/*
|
||||||
* If we are not installing a boot program but we are installing a
|
* 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);
|
err(4, "%s", xxboot);
|
||||||
if (fstat(b, &sb) != 0)
|
if (fstat(b, &sb) != 0)
|
||||||
err(4, "%s", xxboot);
|
err(4, "%s", xxboot);
|
||||||
#ifdef __i386__
|
if (arch->arch == ARCH_I386) {
|
||||||
if (sb.st_size > BBSIZE)
|
if (sb.st_size > BBSIZE)
|
||||||
errx(4, "%s too large", xxboot);
|
errx(4, "%s too large", xxboot);
|
||||||
/*
|
/*
|
||||||
* XXX Botch alert.
|
* XXX Botch alert.
|
||||||
* The i386/PC98 has the so-called fdisk table embedded into the
|
* The i386/PC98 has the so-called fdisk table embedded into the
|
||||||
* primary bootstrap. We take care to not clobber it, but
|
* primary bootstrap. We take care to not clobber it, but
|
||||||
* only if it does already contain some data. (Otherwise,
|
* only if it does already contain some data. (Otherwise,
|
||||||
* the xxboot provides a template.)
|
* the xxboot provides a template.)
|
||||||
*/
|
*/
|
||||||
if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
|
if ((tmpbuf = (char *)malloc((int)dp->d_secsize)) == 0)
|
||||||
err(4, "%s", xxboot);
|
err(4, "%s", xxboot);
|
||||||
memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
|
memcpy((void *)tmpbuf, (void *)boot, (int)dp->d_secsize);
|
||||||
|
|
||||||
if (read(b, boot, BBSIZE) < 0)
|
if (read(b, boot, BBSIZE) < 0)
|
||||||
err(4, "%s", xxboot);
|
err(4, "%s", xxboot);
|
||||||
|
|
||||||
/* XXX: rely on some very precise overlaps in definitions */
|
/* XXX: rely on some very precise overlaps in definitions */
|
||||||
#ifdef PC98
|
dps = IS_PC98 ? sizeof(struct pc98_partition) :
|
||||||
dps = sizeof(struct pc98_partition);
|
sizeof(struct dos_partition);
|
||||||
#else
|
for (i = DOSPARTOFF, found = 0;
|
||||||
dps = sizeof(struct dos_partition);
|
!found && i < (int)(DOSPARTOFF + NDOSPART * dps);
|
||||||
#endif
|
i++)
|
||||||
for (i = DOSPARTOFF, found = 0;
|
found = tmpbuf[i] != 0;
|
||||||
!found && i < (int)(DOSPARTOFF + NDOSPART * dps);
|
if (found)
|
||||||
i++)
|
memcpy((void *)&((char *)boot)[DOSPARTOFF],
|
||||||
found = tmpbuf[i] != 0;
|
(void *)&tmpbuf[DOSPARTOFF],
|
||||||
if (found)
|
NDOSPART * dps);
|
||||||
memcpy((void *)&boot[DOSPARTOFF],
|
free(tmpbuf);
|
||||||
(void *)&tmpbuf[DOSPARTOFF],
|
}
|
||||||
NDOSPART * dps);
|
|
||||||
free(tmpbuf);
|
|
||||||
#endif /* __i386__ */
|
|
||||||
|
|
||||||
#ifdef __alpha__
|
if (arch->arch == ARCH_ALPHA) {
|
||||||
if (sb.st_size > BBSIZE - dp->d_secsize)
|
if (sb.st_size > BBSIZE - dp->d_secsize)
|
||||||
errx(4, "%s too large", xxboot);
|
errx(4, "%s too large", xxboot);
|
||||||
/*
|
/*
|
||||||
* On the alpha, the primary bootstrap starts at the
|
* On the alpha, the primary bootstrap starts at the
|
||||||
* second sector of the boot area. The first sector
|
* second sector of the boot area. The first sector
|
||||||
* contains the label and must be edited to contain the
|
* contains the label and must be edited to contain the
|
||||||
* size and location of the primary bootstrap.
|
* size and location of the primary bootstrap.
|
||||||
*/
|
*/
|
||||||
n = read(b, boot + dp->d_secsize, BBSIZE - dp->d_secsize);
|
n = read(b, (char *)boot + dp->d_secsize,
|
||||||
if (n < 0)
|
BBSIZE - dp->d_secsize);
|
||||||
err(4, "%s", xxboot);
|
if (n < 0)
|
||||||
bootinfo = (u_long *)(boot + 480);
|
err(4, "%s", xxboot);
|
||||||
bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
|
bootinfo = (uint64_t *)((char *)boot + 480);
|
||||||
bootinfo[1] = 1; /* start at sector 1 */
|
bootinfo[0] = (n + dp->d_secsize - 1) / dp->d_secsize;
|
||||||
bootinfo[2] = 0; /* flags (must be zero) */
|
bootinfo[1] = 1; /* start at sector 1 */
|
||||||
#endif /* __alpha__ */
|
bootinfo[2] = 0; /* flags (must be zero) */
|
||||||
|
}
|
||||||
|
|
||||||
(void)close(b);
|
(void)close(b);
|
||||||
/*
|
/*
|
||||||
@ -1495,20 +1556,22 @@ Warning(const char *fmt, ...)
|
|||||||
void
|
void
|
||||||
usage(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",
|
fprintf(stderr,
|
||||||
"\t\t(to read label)",
|
"%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",
|
||||||
" disklabel -w [-r] [-n] disk type [ packid ]",
|
"usage: disklabel [-r] disk",
|
||||||
"\t\t(to write label with existing boot program)",
|
"\t\t(to read label)",
|
||||||
" disklabel -e [-r] [-n] disk",
|
" disklabel -w [-nr] [-m machine] disk type [packid]",
|
||||||
"\t\t(to edit label)",
|
"\t\t(to write label with existing boot program)",
|
||||||
" disklabel -R [-r] [-n] disk protofile",
|
" disklabel -e [-nr] [-m machine] disk",
|
||||||
"\t\t(to restore label with existing boot program)",
|
"\t\t(to edit label)",
|
||||||
" disklabel -B [-n] [ -b bootprog ] disk [ type ]",
|
" disklabel -R [-nr] [-m machine] disk protofile",
|
||||||
"\t\t(to install boot program with existing on-disk label)",
|
"\t\t(to restore label with existing boot program)",
|
||||||
" disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
|
" disklabel -B [-b boot] [-m machine] disk",
|
||||||
"\t\t(to write label and install boot program)",
|
"\t\t(to install boot program with existing on-disk label)",
|
||||||
" disklabel -R -B [-n] [ -b bootprog ] disk protofile",
|
" 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)"
|
"\t\t(to restore label and install boot program)"
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user