Fixes and new features:

o Merge the -I switch from i386 verison to initialize the partition table
  to use the maximum amount possible for a single FreeBSD table.
o Improve warning when the geom method fails (which I think it
  always will until geom_pc98 is updated to respond to this ctl message)
o when writing out the boot sector, we have to write out a minimum of
  1024 bytes or the sector size.  This is different than the i386 case where
  we need to write out a minimum of 512 bytes (which is also the minimum
  sector size).  We already handle this difference on reading, but didn't
  in writing, so attempting to write a new partition table would fail.
o Add MID to the -s output, since pc98 users are likely interested in
  both of these parameters.

# I can now initialize disks on my pc98 machine either by -I or by
# manually entering the parameters.  I don't know if fdisk -B works or not,
# since I'm not willing to risk my only working boot disk to test it..
This commit is contained in:
imp 2006-02-26 07:37:10 +00:00
parent a8acef0bfb
commit 7dec5978c1
2 changed files with 62 additions and 12 deletions

View File

@ -9,7 +9,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.\" !PC98 .Op Fl BIaistu .\" !PC98 .Op Fl BIaistu
.Op Fl Bastu .Op Fl BIastu
.Op Fl b Ar bootcode .Op Fl b Ar bootcode
.Op Fl 1234 .Op Fl 1234
.Op Ar disk .Op Ar disk
@ -67,6 +67,12 @@ Ignored
if if
.Fl f .Fl f
is given. is given.
.It Fl I
Initialize the partition table. One
.Fx
slice covering the entire disk will be created.
Some space at the start of the disk will reserved for the IPL program
and the pc98 partition table itself.
.It Fl f Ar configfile .It Fl f Ar configfile
Set partition values using the file Set partition values using the file
.Ar configfile . .Ar configfile .

View File

@ -103,6 +103,7 @@ typedef struct cmd {
} CMD; } CMD;
static int B_flag = 0; /* replace boot code */ static int B_flag = 0; /* replace boot code */
static int I_flag = 0; /* Inizialize disk to defaults */
static int a_flag = 0; /* set active partition */ static int a_flag = 0; /* set active partition */
static int i_flag = 0; /* replace partition data */ static int i_flag = 0; /* replace partition data */
static int u_flag = 0; /* update partition data */ static int u_flag = 0; /* update partition data */
@ -170,6 +171,7 @@ static int decimal(const char *str, int *num, int deflt);
static const char *get_type(int type); static const char *get_type(int type);
static void usage(void); static void usage(void);
static int string(const char *str, char **ans); static int string(const char *str, char **ans);
static void reset_boot(void);
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
@ -179,11 +181,14 @@ main(int argc, char *argv[])
int partition = -1; int partition = -1;
struct pc98_partition *partp; struct pc98_partition *partp;
while ((c = getopt(argc, argv, "Ba:f:istuv12345678")) != -1) while ((c = getopt(argc, argv, "BIa:f:istuv12345678")) != -1)
switch (c) { switch (c) {
case 'B': case 'B':
B_flag = 1; B_flag = 1;
break; break;
case 'I':
I_flag = 1;
break;
case 'a': case 'a':
a_flag = 1; a_flag = 1;
break; break;
@ -249,21 +254,45 @@ main(int argc, char *argv[])
err(1, "read_s0"); err(1, "read_s0");
printf("%s: %d cyl %d hd %d sec\n", disk, dos_cyls, dos_heads, printf("%s: %d cyl %d hd %d sec\n", disk, dos_cyls, dos_heads,
dos_sectors); dos_sectors);
printf("Part %11s %11s SID\n", "Start", "Size"); printf("Part %11s %11s %4s %4s\n", "Start", "Size", "MID",
"SID");
for (i = 0; i < NDOSPART; i++) { for (i = 0; i < NDOSPART; i++) {
partp = ((struct pc98_partition *) &mboot.parts) + i; partp = ((struct pc98_partition *) &mboot.parts) + i;
if (partp->dp_sid == 0) if (partp->dp_sid == 0)
continue; continue;
printf("%4d: %11u %11u 0x%02x\n", i + 1, printf("%4d: %11u %11u 0x%02x 0x%02x\n", i + 1,
partp->dp_scyl * cylsecs, partp->dp_scyl * cylsecs,
(partp->dp_ecyl - partp->dp_scyl + 1) * cylsecs, (partp->dp_ecyl - partp->dp_scyl + 1) * cylsecs,
partp->dp_sid); partp->dp_mid, partp->dp_sid);
} }
exit(0); exit(0);
} }
printf("******* Working on device %s *******\n",disk); printf("******* Working on device %s *******\n",disk);
if (I_flag) {
read_s0();
reset_boot();
partp = (struct pc98_partition *) (&mboot.parts[0]);
partp->dp_mid = DOSMID_386BSD;
partp->dp_sid = DOSSID_386BSD;
/* Start c/h/s. */
partp->dp_scyl = partp->dp_ipl_cyl = 1;
partp->dp_shd = partp->dp_ipl_head = 1;
partp->dp_ssect = partp->dp_ipl_sct = 0;
/* End c/h/s. */
partp->dp_ecyl = dos_cyls - 1;
partp->dp_ehd = dos_cylsecs / dos_sectors;
partp->dp_esect = dos_sectors;
if (v_flag)
print_s0(-1);
if (!t_flag)
write_s0();
exit(0);
}
if (f_flag) { if (f_flag) {
if (v_flag) if (v_flag)
print_s0(-1); print_s0(-1);
@ -315,7 +344,7 @@ static void
usage() usage()
{ {
fprintf(stderr, "%s%s", fprintf(stderr, "%s%s",
"usage: fdisk [-Baistu] [-12345678] [disk]\n", "usage: fdisk [-BIaistu] [-12345678] [disk]\n",
" fdisk -f configfile [-itv] [disk]\n"); " fdisk -f configfile [-itv] [disk]\n");
exit(1); exit(1);
} }
@ -571,7 +600,7 @@ open_disk(int flag)
} }
if ( !(st.st_mode & S_IFCHR) ) if ( !(st.st_mode & S_IFCHR) )
warnx("device %s is not character special", disk); warnx("device %s is not character special", disk);
rwmode = a_flag || B_flag || flag ? O_RDWR : O_RDONLY; rwmode = I_flag || a_flag || B_flag || flag ? O_RDWR : O_RDONLY;
fd = open(disk, rwmode); fd = open(disk, rwmode);
if (fd == -1 && errno == EPERM && rwmode == O_RDWR) if (fd == -1 && errno == EPERM && rwmode == O_RDWR)
fd = open(disk, O_RDONLY); fd = open(disk, O_RDONLY);
@ -604,8 +633,9 @@ write_disk(off_t sector, void *buf)
struct gctl_req *grq; struct gctl_req *grq;
const char *q; const char *q;
char fbuf[BUFSIZ]; char fbuf[BUFSIZ];
int i, fdw; int i, fdw, sz;
sz = secsize > MIN_SEC_SIZE ? secsize : MIN_SEC_SIZE * 2;
grq = gctl_get_handle(); grq = gctl_get_handle();
gctl_ro_param(grq, "verb", -1, "write PC98"); gctl_ro_param(grq, "verb", -1, "write PC98");
gctl_ro_param(grq, "class", -1, "PC98"); gctl_ro_param(grq, "class", -1, "PC98");
@ -615,17 +645,18 @@ write_disk(off_t sector, void *buf)
else else
q++; q++;
gctl_ro_param(grq, "geom", -1, q); gctl_ro_param(grq, "geom", -1, q);
gctl_ro_param(grq, "data", secsize, buf); gctl_ro_param(grq, "data", sz, buf);
q = gctl_issue(grq); q = gctl_issue(grq);
if (q == NULL) { if (q == NULL) {
gctl_free(grq); gctl_free(grq);
return(0); return(0);
} }
warnx("%s", q); warnx("Geom problem: %s", q);
gctl_free(grq); gctl_free(grq);
error = pwrite(fd, buf, secsize, (sector * 512)); warnx("Warning: Partitioning via geom failed, trying raw write");
if (error == secsize) error = pwrite(fd, buf, sz, sector * 512);
if (error == sz)
return (0); return (0);
for (i = 0; i < NDOSPART; i++) { for (i = 0; i < NDOSPART; i++) {
@ -859,3 +890,16 @@ get_rootdisk(void)
return s; return s;
} }
static void
reset_boot(void)
{
int i;
struct pc98_partition *partp;
init_boot();
for (i = 1; i <= NDOSPART; i++) {
partp = ((struct pc98_partition *) &mboot.parts) + i - 1;
bzero((char *)partp, sizeof (struct pc98_partition));
}
}