[Midnightbsd-cvs] src [11226] trunk/sbin/fdisk_pc98: sync with freebsd
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sun Jul 1 17:08:47 EDT 2018
Revision: 11226
http://svnweb.midnightbsd.org/src/?rev=11226
Author: laffer1
Date: 2018-07-01 17:08:46 -0400 (Sun, 01 Jul 2018)
Log Message:
-----------
sync with freebsd
Added Paths:
-----------
trunk/sbin/fdisk_pc98/
trunk/sbin/fdisk_pc98/Makefile
trunk/sbin/fdisk_pc98/fdisk.8
trunk/sbin/fdisk_pc98/fdisk.c
Added: trunk/sbin/fdisk_pc98/Makefile
===================================================================
--- trunk/sbin/fdisk_pc98/Makefile (rev 0)
+++ trunk/sbin/fdisk_pc98/Makefile 2018-07-01 21:08:46 UTC (rev 11226)
@@ -0,0 +1,14 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/sbin/fdisk_pc98/Makefile 274008 2014-11-03 05:35:45Z nyan $
+
+PROG= fdisk
+SRCS= fdisk.c geom_pc98_enc.c
+WARNS?= 4
+MAN= fdisk.8
+
+.PATH: ${.CURDIR}/../../sys/geom
+
+DPADD+= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF}
+LDADD+= -lgeom -lbsdxml -lsbuf
+
+.include <bsd.prog.mk>
Property changes on: trunk/sbin/fdisk_pc98/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sbin/fdisk_pc98/fdisk.8
===================================================================
--- trunk/sbin/fdisk_pc98/fdisk.8 (rev 0)
+++ trunk/sbin/fdisk_pc98/fdisk.8 2018-07-01 21:08:46 UTC (rev 11226)
@@ -0,0 +1,487 @@
+.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/sbin/fdisk_pc98/fdisk.8 307438 2016-10-16 23:44:02Z sevan $
+.\"
+.Dd October 5, 2016
+.Dt FDISK 8
+.Os
+.Sh NAME
+.Nm fdisk
+.Nd NEC PC-98x1 slice table maintenance utility
+.Sh SYNOPSIS
+.Nm
+.Op Fl BIaistuv
+.Op Fl 12345678
+.Op Ar disk
+.Nm
+.Fl f Ar configfile
+.Op Fl itv
+.Op Ar disk
+.Sh PROLOGUE
+In order for the BIOS to boot the kernel,
+certain conventions must be adhered to.
+Sector 0 of the disk must contain boot code,
+a slice table,
+and a magic number.
+BIOS slices can be used to break the disk up into several pieces.
+The BIOS brings in sector 0 and verifies the magic number.
+The sector
+0 boot code then searches the slice table to determine which
+slice is marked
+.Dq active .
+This boot code then brings in the bootstrap from the
+active slice and, if marked bootable, runs it.
+Under
+.Tn DOS ,
+you can have one or more slices with one active.
+The
+.Tn DOS
+.Nm
+utility can be used to divide space on the disk into slices and set one
+active.
+.Sh DESCRIPTION
+The
+.Fx
+utility,
+.Nm ,
+serves a similar purpose to the
+.Tn DOS
+utility.
+The first form is used to
+display slice information or to interactively edit the slice
+table.
+The second is used to write a slice table using a
+.Ar configfile ,
+and is designed to be used by other scripts/programs.
+.Pp
+Options are:
+.Bl -tag -width indent
+.It Fl a
+Change the active slice only.
+Ignored if
+.Fl f
+is given.
+.It Fl B
+Reinitialize the boot code contained in sector 0 of the disk.
+Ignored if
+.Fl f
+is given.
+.It Fl f Ar configfile
+Set slice values using the file
+.Ar configfile .
+The
+.Ar configfile
+always modifies existing slices, unless
+.Fl i
+is also given, in which case all existing slices are deleted (marked
+as
+.Dq unused )
+before the
+.Ar configfile
+is read.
+The
+.Ar configfile
+can be
+.Sq Fl ,
+in which case standard input is read.
+See
+.Sx CONFIGURATION FILE ,
+below, for file syntax.
+.Pp
+.Em WARNING :
+when
+.Fl f
+is used, you are not asked if you really want to write the slices
+table (as you are in the interactive mode).
+Use with caution!
+.It Fl i
+Initialize sector 0 of the disk.
+This implies
+.Fl u ,
+unless
+.Fl f
+is given.
+.It Fl I
+Initialize sector 0 slice table
+for one
+.Fx
+slice covering the entire disk.
+Some space at the start of the disk will reserved for the IPL program
+and the pc98 slice table itself.
+.It Fl s
+Print summary information and exit.
+.It Fl t
+Test mode; do not write slice values.
+Generally used with the
+.Fl f
+option to see what would be written to the slice table.
+Implies
+.Fl v .
+.It Fl u
+Update (edit) the disk's sector 0 slice table.
+Ignored if
+.Fl f
+is given.
+.It Fl v
+Be verbose.
+Slices that are unused are suppressed unless this flag is specified.
+When
+.Fl f
+is used,
+.Nm
+prints out the slice table that is written to the disk.
+.It Fl 12345678
+Operate on a single slice table entry only.
+Ignored if
+.Fl f
+is given.
+.El
+.Pp
+The final disk name can be provided as a
+.Dq bare
+disk name only, e.g.\&
+.Pa da0 ,
+or as a full pathname.
+If omitted,
+.Nm
+tries to figure out the default disk device name from the
+mounted root device.
+.Pp
+When called with no arguments, it prints the sector 0 slice table.
+An example follows:
+.Bd -literal
+ ******* Working on device /dev/da0 *******
+ parameters extracted from in-core disklabel are:
+ cylinders=33075 heads=8 sectors/track=32 (256 blks/cyl)
+
+ parameters to be used for BIOS calculations are:
+ cylinders=33075 heads=8 sectors/track=32 (256 blks/cyl)
+
+ Media sector size is 512
+ Warning: BIOS sector numbering starts with sector 1
+ Information from DOS bootblock is:
+ The data for partition 1 is:
+ sysmid 148,(FreeBSD/NetBSD/386BSD)
+ start 256, size 2490112 (1215 Meg), sid 196
+ beg: cyl 1/ sector 0/ head 0;
+ end: cyl 9727/ sector 0/ head 0
+ system Name FreeBSD(98)
+ The data for partition 2 is:
+ sysmid 148,(FreeBSD/NetBSD/386BSD)
+ start 2490368, size 5505024 (2688 Meg), sid 196
+ beg: cyl 9728/ sector 0/ head 0;
+ end: cyl 31231/ sector 0/ head 0
+ system Name FreeBSD(98)
+ The data for partition 3 is:
+ <UNUSED>
+ The data for partition 4 is:
+ <UNUSED>
+ The data for partition 5 is:
+ <UNUSED>
+ The data for partition 6 is:
+ <UNUSED>
+ The data for partition 7 is:
+ <UNUSED>
+ The data for partition 8 is:
+ <UNUSED>
+ The data for partition 9 is:
+ <UNUSED>
+ The data for partition 10 is:
+ <UNUSED>
+ The data for partition 11 is:
+ <UNUSED>
+ The data for partition 12 is:
+ <UNUSED>
+ The data for partition 13 is:
+ <UNUSED>
+ The data for partition 14 is:
+ <UNUSED>
+ The data for partition 15 is:
+ <UNUSED>
+ The data for partition 16 is:
+ <UNUSED>
+.Ed
+.Pp
+The disk is divided into three slices that happen to fill the disk.
+The second slice overlaps the end of the first.
+(Used for debugging purposes.)
+.Bl -tag -width ".Em cyl , sector No and Em head"
+.It Em sysmid
+is used to label the slice.
+.Fx
+reserves the
+magic number 148 decimal (94 in hex).
+.It Xo
+.Em start
+and
+.Em size
+.Xc
+fields provide the start address
+and size of a slice in sectors.
+.It Xo
+.Em cyl , sector
+and
+.Em head
+.Xc
+fields are used to specify the beginning and end addresses of the slice.
+.It Em "system Name"
+is the name of the slice.
+.El
+.Pp
+.Em Note :
+these numbers are calculated using BIOS's understanding of the disk geometry
+and saved in the bootblock.
+.Pp
+The
+.Fl i
+and
+.Fl u
+flags are used to indicate that the slice data is to be updated.
+Unless the
+.Fl f
+option is also given,
+.Nm
+will enter a conversational mode.
+In this mode, no changes will be written to disk unless you explicitly tell
+.Nm
+to.
+.Pp
+The
+.Nm
+utility will display each slice and ask whether you want to edit it.
+If you say yes,
+.Nm
+will step through each field, show you the old value,
+and ask you for a new one.
+When you are done with the slice,
+.Nm
+will display it and ask you whether it is correct.
+It will then proceed to the next entry.
+.Pp
+Getting the
+.Em cyl , sector ,
+and
+.Em head
+fields correct is tricky, so by default,
+they will be calculated for you;
+you can specify them if you choose to though.
+.Pp
+After all the slices are processed,
+you are given the option to change the
+.Dq active
+slice.
+Finally, when all the new data for sector 0 has been accumulated,
+you are asked to confirm whether you really want to rewrite it.
+.Pp
+The difference between the
+.Fl u
+and
+.Fl i
+flags is that
+the
+.Fl u
+flag edits (updates) the existing slice parameters
+while the
+.Fl i
+flag is used to
+.Dq initialize
+them (old values will be ignored);
+it will setup the last BIOS slice to use the whole disk for
+.Fx ;
+and make it active.
+.Sh NOTES
+The automatic calculation of starting cylinder etc.\& uses
+a set of figures that represent what the BIOS thinks the
+geometry of the drive is.
+These figures are taken from the in-core disklabel by default,
+but
+.Nm
+initially gives you an opportunity to change them.
+This allows you to create a bootblock that can work with drives
+that use geometry translation under the BIOS.
+.Pp
+If you hand craft your disk layout,
+please make sure that the
+.Fx
+slice starts on a cylinder boundary.
+.Pp
+Editing an existing slice will most likely result in the loss of
+all data in that slice.
+.Pp
+You should run
+.Nm
+interactively once or twice to see how it works.
+This is completely safe as long as you answer the last question
+in the negative.
+There are subtleties that
+.Nm
+detects that are not fully explained in this manual page.
+.Sh CONFIGURATION FILE
+When the
+.Fl f
+option is given, a disk's slice table can be written using values
+from a
+.Ar configfile .
+The syntax of this file is very simple;
+each line is either a comment or a specification, as follows:
+.Bl -tag -width indent
+.It Ic # Ar comment ...
+Lines beginning with a
+.Ic #
+are comments and are ignored.
+.It Ic g Ar spec1 spec2 spec3
+Set the BIOS geometry used in slice calculations.
+There must be
+three values specified, with a letter preceding each number:
+.Bl -tag -width indent
+.It Cm c Ns Ar num
+Set the number of cylinders to
+.Ar num .
+.It Cm h Ns Ar num
+Set the number of heads to
+.Ar num .
+.It Cm s Ns Ar num
+Set the number of sectors/track to
+.Ar num .
+.El
+.Pp
+These specs can occur in any order, as the leading letter determines
+which value is which; however, all three must be specified.
+.Pp
+This line must occur before any lines that specify slice
+information.
+.Pp
+It is an error if the following is not true:
+.Bd -literal -offset indent
+1 <= number of cylinders
+1 <= number of heads <= 256
+1 <= number of sectors/track < 64
+.Ed
+.Pp
+The number of cylinders should be less than or equal to 1024, but this
+is not enforced, although a warning will be printed.
+Note that bootable
+.Fx
+slices (the
+.Dq Pa /
+file system) must lie completely within the
+first 1024 cylinders; if this is not true, booting may fail.
+Non-bootable slices do not have this restriction.
+.Pp
+Example (all of these are equivalent), for a disk with 1019 cylinders,
+39 heads, and 63 sectors:
+.Bd -literal -offset indent
+g c1019 h39 s63
+g h39 c1019 s63
+g s63 h39 c1019
+.Ed
+.It Ic p Ar slice type start length
+Set the slice given by
+.Ar slice
+(1-8) to type
+.Ar type ,
+starting at sector
+.Ar start
+for
+.Ar length
+sectors.
+.Pp
+Only those slices explicitly mentioned by these lines are modified;
+any slice not referenced by a
+.Ic p
+line will not be modified.
+However, if an invalid slice table is present, or the
+.Fl i
+option is specified, all existing slice entries will be cleared
+(marked as unused), and these
+.Ic p
+lines will have to be used to
+explicitly set slice information.
+If multiple slices need to be
+set, multiple
+.Ic p
+lines must be specified; one for each slice.
+.Pp
+These slice lines must occur after any geometry specification lines,
+if one is present.
+.Pp
+The
+.Ar type
+is 165 for
+.Fx
+slices.
+Specifying a slice type of zero is
+the same as clearing the slice and marking it as unused; however,
+dummy values (such as
+.Dq 0 )
+must still be specified for
+.Ar start
+and
+.Ar length .
+.Pp
+Note: the start offset will be rounded upwards to a head boundary if
+necessary, and the end offset will be rounded downwards to a cylinder
+boundary if necessary.
+.Pp
+Example: to clear slice 4 and mark it as unused:
+.Pp
+.Dl "p 4 0 0 0"
+.Pp
+Example: to set slice 1 to a
+.Fx
+slice, starting at sector 1
+for 2503871 sectors (note: these numbers will be rounded upwards and
+downwards to correspond to head and cylinder boundaries):
+.Pp
+.Dl "p 1 165 1 2503871"
+.It Ic a Ar slice
+Make
+.Ar slice
+the active slice.
+Can occur anywhere in the config file, but only
+one must be present.
+.Pp
+Example: to make slice 1 the active slice:
+.Pp
+.Dl "a 1"
+.El
+.Sh SEE ALSO
+.Xr boot98cfg 8 ,
+.Xr bsdlabel 8 ,
+.Xr gpart 8 ,
+.Xr newfs 8
+.Sh HISTORY
+A version of
+.Nm
+first appeared in the Mach Operating System.
+It was subsequently ported to
+.Bx 386 .
+.Sh AUTHORS
+.An -nosplit
+.Nm
+for Mach Operating System was written by
+.An Robert Baron Aq Mt rvb at cs.cmu.edu .
+It was ported to
+.Bx 386
+by
+.An Julian Elischer Aq Mt julian at tfs.com .
+.Sh BUGS
+The default boot code will not necessarily handle all slice types
+correctly, in particular those introduced since
+.Tn MS-DOS
+6.x.
+.Pp
+The entire utility should be made more user-friendly.
+.Pp
+Most users new to
+.Fx
+do not understand the difference between
+.Dq slice
+and
+.Dq partition ,
+causing difficulty to adjust.
+.Pp
+You cannot use this command to completely dedicate a disk to
+.Fx .
+The
+.Xr bsdlabel 8
+command must be used for this.
Property changes on: trunk/sbin/fdisk_pc98/fdisk.8
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sbin/fdisk_pc98/fdisk.c
===================================================================
--- trunk/sbin/fdisk_pc98/fdisk.c (rev 0)
+++ trunk/sbin/fdisk_pc98/fdisk.c 2018-07-01 21:08:46 UTC (rev 11226)
@@ -0,0 +1,919 @@
+/* $MidnightBSD$ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution at CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sbin/fdisk_pc98/fdisk.c 254015 2013-08-07 00:00:48Z marcel $");
+
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/diskpc98.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <err.h>
+#include <errno.h>
+#include <libgeom.h>
+#include <paths.h>
+#include <regex.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int iotest;
+
+#define LBUF 100
+static char lbuf[LBUF];
+
+/*
+ *
+ * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992
+ *
+ * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University
+ * Copyright (c) 1989 Robert. V. Baron
+ * Created.
+ */
+
+#define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp
+#define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); }
+
+#define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs)
+
+#define MAX_SEC_SIZE 2048 /* maximum section size that is supported */
+#define MIN_SEC_SIZE 512 /* the sector size to start sensing at */
+static int secsize = 0; /* the sensed sector size */
+
+static char *disk;
+
+static int cyls, sectors, heads, cylsecs, disksecs;
+
+struct mboot {
+ unsigned char padding[2]; /* force the longs to be long aligned */
+ unsigned char bootinst[510];
+ unsigned short int signature;
+ struct pc98_partition parts[8];
+ unsigned char large_sector_overflow[MAX_SEC_SIZE-MIN_SEC_SIZE];
+};
+
+static struct mboot mboot;
+static int fd;
+
+static uint dos_cyls;
+static uint dos_heads;
+static uint dos_sectors;
+static uint dos_cylsecs;
+
+#define MAX_ARGS 10
+
+typedef struct cmd {
+ char cmd;
+ int n_args;
+ struct arg {
+ char argtype;
+ int arg_val;
+ } args[MAX_ARGS];
+} CMD;
+
+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 i_flag = 0; /* replace partition data */
+static int u_flag = 0; /* update partition data */
+static int s_flag = 0; /* Print a summary and exit */
+static int t_flag = 0; /* test only */
+static char *f_flag = NULL; /* Read config info from file */
+static int v_flag = 0; /* Be verbose */
+
+static struct part_type
+{
+ unsigned char type;
+ const char *name;
+} part_types[] = {
+ {0x00, "unused"}
+ ,{0x01, "Primary DOS with 12 bit FAT"}
+ ,{0x11, "MSDOS"}
+ ,{0x20, "MSDOS"}
+ ,{0x21, "MSDOS"}
+ ,{0x22, "MSDOS"}
+ ,{0x23, "MSDOS"}
+ ,{0x02, "XENIX / file system"}
+ ,{0x03, "XENIX /usr file system"}
+ ,{0x04, "PC-UX"}
+ ,{0x05, "Extended DOS"}
+ ,{0x06, "Primary 'big' DOS (> 32MB)"}
+ ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"}
+ ,{0x08, "AIX file system"}
+ ,{0x09, "AIX boot partition or Coherent"}
+ ,{0x0A, "OS/2 Boot Manager or OPUS"}
+ ,{0x10, "OPUS"}
+ ,{0x14, "FreeBSD/NetBSD/386BSD"}
+ ,{0x94, "FreeBSD/NetBSD/386BSD"}
+ ,{0x40, "VENIX 286"}
+ ,{0x50, "DM"}
+ ,{0x51, "DM"}
+ ,{0x52, "CP/M or Microport SysV/AT"}
+ ,{0x56, "GB"}
+ ,{0x61, "Speed"}
+ ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"}
+ ,{0x64, "Novell Netware 2.xx"}
+ ,{0x65, "Novell Netware 3.xx"}
+ ,{0x75, "PCIX"}
+ ,{0x40, "Minix"}
+};
+
+static void print_s0(int which);
+static void print_part(int i);
+static void init_sector0(unsigned long start);
+static void init_boot(void);
+static void change_part(int i, int force);
+static void print_params(void);
+static void change_active(int which);
+static void change_code(void);
+static void get_params_to_use(void);
+static char *get_rootdisk(void);
+static void dos(u_int32_t start, u_int32_t size, struct pc98_partition *partp);
+static int open_disk(int flag);
+static ssize_t read_disk(off_t sector, void *buf);
+static int write_disk(off_t sector, void *buf);
+static int get_params(void);
+static int read_s0(void);
+static int write_s0(void);
+static int ok(const char *str);
+static int decimal(const char *str, int *num, int deflt);
+static const char *get_type(int type);
+static void usage(void);
+static int string(const char *str, char **ans);
+static void reset_boot(void);
+
+int
+main(int argc, char *argv[])
+{
+ struct stat sb;
+ int c, i;
+ int partition = -1;
+ struct pc98_partition *partp;
+
+ while ((c = getopt(argc, argv, "BIa:f:istuv12345678")) != -1)
+ switch (c) {
+ case 'B':
+ B_flag = 1;
+ break;
+ case 'I':
+ I_flag = 1;
+ break;
+ case 'a':
+ a_flag = 1;
+ break;
+ case 'f':
+ f_flag = optarg;
+ break;
+ case 'i':
+ i_flag = 1;
+ break;
+ case 's':
+ s_flag = 1;
+ break;
+ case 't':
+ t_flag = 1;
+ break;
+ case 'u':
+ u_flag = 1;
+ break;
+ case 'v':
+ v_flag = 1;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ partition = c - '0';
+ break;
+ default:
+ usage();
+ }
+ if (f_flag || i_flag)
+ u_flag = 1;
+ if (t_flag)
+ v_flag = 1;
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0) {
+ disk = get_rootdisk();
+ } else {
+ if (stat(argv[0], &sb) == 0) {
+ /* OK, full pathname given */
+ disk = argv[0];
+ } else if (errno == ENOENT && argv[0][0] != '/') {
+ /* Try prepending "/dev" */
+ asprintf(&disk, "%s%s", _PATH_DEV, argv[0]);
+ if (disk == NULL)
+ errx(1, "out of memory");
+ } else {
+ /* other stat error, let it fail below */
+ disk = argv[0];
+ }
+ }
+ if (open_disk(u_flag) < 0)
+ err(1, "cannot open disk %s", disk);
+
+ if (s_flag) {
+ if (read_s0())
+ err(1, "read_s0");
+ printf("%s: %d cyl %d hd %d sec\n", disk, dos_cyls, dos_heads,
+ dos_sectors);
+ printf("Part %11s %11s %4s %4s %-16s\n", "Start", "Size", "MID",
+ "SID", "Name");
+ for (i = 0; i < PC98_NPARTS; i++) {
+ partp = ((struct pc98_partition *) &mboot.parts) + i;
+ if (partp->dp_sid == 0)
+ continue;
+ printf("%4d: %11u %11u 0x%02x 0x%02x %-16.16s\n", i + 1,
+ partp->dp_scyl * cylsecs,
+ (partp->dp_ecyl - partp->dp_scyl + 1) * cylsecs,
+ partp->dp_mid, partp->dp_sid, partp->dp_name);
+ }
+ exit(0);
+ }
+
+ 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;
+ strncpy(partp->dp_name, "FreeBSD", sizeof(partp->dp_name));
+ /* 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 (v_flag)
+ print_s0(-1);
+ if (!t_flag)
+ write_s0();
+ } else {
+ if(u_flag)
+ get_params_to_use();
+ else
+ print_params();
+
+ if (read_s0())
+ init_sector0(dos_sectors);
+
+ printf("Media sector size is %d\n", secsize);
+ printf("Warning: BIOS sector numbering starts with sector 1\n");
+ printf("Information from DOS bootblock is:\n");
+ if (partition == -1)
+ for (i = 1; i <= PC98_NPARTS; i++)
+ change_part(i, v_flag);
+ else
+ change_part(partition, 1);
+
+ if (u_flag || a_flag)
+ change_active(partition);
+
+ if (B_flag)
+ change_code();
+
+ if (u_flag || a_flag || B_flag) {
+ if (!t_flag) {
+ printf("\nWe haven't changed the partition table yet. ");
+ printf("This is your last chance.\n");
+ }
+ print_s0(-1);
+ if (!t_flag) {
+ if (ok("Should we write new partition table?"))
+ write_s0();
+ } else {
+ printf("\n-t flag specified -- partition table not written.\n");
+ }
+ }
+ }
+
+ exit(0);
+}
+
+static void
+usage()
+{
+ fprintf(stderr, "%s%s",
+ "usage: fdisk [-BIaistu] [-12345678] [disk]\n",
+ " fdisk -f configfile [-itv] [disk]\n");
+ exit(1);
+}
+
+static struct pc98_partition mtpart;
+
+static int
+part_unused(int i)
+{
+ struct pc98_partition *partp;
+
+ partp = ((struct pc98_partition *) &mboot.parts) + i - 1;
+ return (bcmp(partp, &mtpart, sizeof (struct pc98_partition)) == 0);
+}
+
+static void
+print_s0(int which)
+{
+ int i;
+
+ print_params();
+ printf("Information from DOS bootblock is:\n");
+ if (which == -1) {
+ for (i = 1; i <= PC98_NPARTS; i++)
+ if (v_flag || !part_unused(i)) {
+ printf("%d: ", i);
+ print_part(i);
+ }
+ }
+ else
+ print_part(which);
+}
+
+static void
+print_part(int i)
+{
+ struct pc98_partition *partp;
+ u_int64_t part_sz, part_mb;
+
+ if (part_unused(i)) {
+ printf("<UNUSED>\n");
+ return;
+ }
+ /*
+ * Be careful not to overflow.
+ */
+ partp = ((struct pc98_partition *) &mboot.parts) + i - 1;
+ part_sz = (partp->dp_ecyl - partp->dp_scyl + 1) * cylsecs;
+ part_mb = part_sz * secsize;
+ part_mb /= (1024 * 1024);
+ printf("sysmid %d (%#04x),(%s)\n", partp->dp_mid, partp->dp_mid,
+ get_type(partp->dp_mid));
+ printf(" start %lu, size %lu (%ju Meg), sid %d\n",
+ (u_long)(partp->dp_scyl * cylsecs), (u_long)part_sz,
+ (uintmax_t)part_mb, partp->dp_sid);
+ printf("\tbeg: cyl %d/ head %d/ sector %d;\n\tend: cyl %d/ head %d/ sector %d\n"
+ ,partp->dp_scyl
+ ,partp->dp_shd
+ ,partp->dp_ssect
+ ,partp->dp_ecyl
+ ,partp->dp_ehd
+ ,partp->dp_esect);
+ printf ("\tsystem Name %.16s\n", partp->dp_name);
+}
+
+
+static void
+init_boot(void)
+{
+
+ mboot.signature = PC98_MAGIC;
+}
+
+
+static void
+init_sector0(unsigned long start)
+{
+ struct pc98_partition *partp =
+ (struct pc98_partition *)(&mboot.parts[0]);
+
+ init_boot();
+
+ partp->dp_mid = DOSMID_386BSD;
+ partp->dp_sid = DOSSID_386BSD;
+
+ dos(start, disksecs - start, partp);
+}
+
+static void
+change_part(int i, int force)
+{
+ struct pc98_partition *partp =
+ ((struct pc98_partition *) &mboot.parts) + i - 1;
+
+ if (!force && part_unused(i))
+ return;
+
+ printf("The data for partition %d is:\n", i);
+ print_part(i);
+
+ if (u_flag && ok("Do you want to change it?")) {
+ int tmp;
+
+ if (i_flag) {
+ bzero((char *)partp, sizeof (struct pc98_partition));
+ if (i == 1) {
+ init_sector0(1);
+ printf("\nThe static data for the slice 1 has been reinitialized to:\n");
+ print_part(i);
+ }
+ }
+ do {
+ int x_start = partp->dp_scyl * cylsecs ;
+ int x_size = (partp->dp_ecyl - partp->dp_scyl + 1) * cylsecs;
+ Decimal("sysmid", partp->dp_mid, tmp);
+ Decimal("syssid", partp->dp_sid, tmp);
+ String ("system name", partp->dp_name, 16);
+ Decimal("start", x_start, tmp);
+ Decimal("size", x_size, tmp);
+
+ if (ok("Explicitly specify beg/end address ?"))
+ {
+ int tsec,tcyl,thd;
+ tcyl = partp->dp_scyl;
+ thd = partp->dp_shd;
+ tsec = partp->dp_ssect;
+ Decimal("beginning cylinder", tcyl, tmp);
+ Decimal("beginning head", thd, tmp);
+ Decimal("beginning sector", tsec, tmp);
+ partp->dp_scyl = tcyl;
+ partp->dp_ssect = tsec;
+ partp->dp_shd = thd;
+ partp->dp_ipl_cyl = partp->dp_scyl;
+ partp->dp_ipl_sct = partp->dp_ssect;
+ partp->dp_ipl_head = partp->dp_shd;
+
+ tcyl = partp->dp_ecyl;
+ thd = partp->dp_ehd;
+ tsec = partp->dp_esect;
+ Decimal("ending cylinder", tcyl, tmp);
+ Decimal("ending head", thd, tmp);
+ Decimal("ending sector", tsec, tmp);
+ partp->dp_ecyl = tcyl;
+ partp->dp_esect = tsec;
+ partp->dp_ehd = thd;
+ } else
+ dos(x_start, x_size, partp);
+
+ print_part(i);
+ } while (!ok("Are we happy with this entry?"));
+ }
+}
+
+static void
+print_params()
+{
+ printf("parameters extracted from in-core disklabel are:\n");
+ printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n"
+ ,cyls,heads,sectors,cylsecs);
+ if (dos_cyls > 65535 || dos_heads > 255 || dos_sectors > 255)
+ printf("Figures below won't work with BIOS for partitions not in cyl 1\n");
+ printf("parameters to be used for BIOS calculations are:\n");
+ printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n"
+ ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs);
+}
+
+static void
+change_active(int which)
+{
+ struct pc98_partition *partp = &mboot.parts[0];
+ int active, i, new, tmp;
+
+ active = -1;
+ for (i = 0; i < PC98_NPARTS; i++) {
+ if ((partp[i].dp_sid & PC98_SID_ACTIVE) == 0)
+ continue;
+ printf("Partition %d is marked active\n", i + 1);
+ if (active == -1)
+ active = i + 1;
+ }
+ if (a_flag && which != -1)
+ active = which;
+ else if (active == -1)
+ active = 1;
+
+ if (!ok("Do you want to change the active partition?"))
+ return;
+setactive:
+ do {
+ new = active;
+ Decimal("active partition", new, tmp);
+ if (new < 1 || new > 8) {
+ printf("Active partition number must be in range 1-8."
+ " Try again.\n");
+ goto setactive;
+ }
+ active = new;
+ } while (!ok("Are you happy with this choice"));
+ if (active > 0 && active <= 8)
+ partp[active-1].dp_sid |= PC98_SID_ACTIVE;
+}
+
+static void
+change_code()
+{
+ if (ok("Do you want to change the boot code?"))
+ init_boot();
+}
+
+void
+get_params_to_use()
+{
+ int tmp;
+ print_params();
+ if (ok("Do you want to change our idea of what BIOS thinks ?"))
+ {
+ do
+ {
+ Decimal("BIOS's idea of #cylinders", dos_cyls, tmp);
+ Decimal("BIOS's idea of #heads", dos_heads, tmp);
+ Decimal("BIOS's idea of #sectors", dos_sectors, tmp);
+ dos_cylsecs = dos_heads * dos_sectors;
+ print_params();
+ }
+ while(!ok("Are you happy with this choice"));
+ }
+}
+
+
+/***********************************************\
+* Change real numbers into strange dos numbers *
+\***********************************************/
+static void
+dos(u_int32_t start, u_int32_t size, struct pc98_partition *partp)
+{
+ u_int32_t end;
+
+ if (partp->dp_mid == 0 && partp->dp_sid == 0 &&
+ start == 0 && size == 0) {
+ memcpy(partp, &mtpart, sizeof(*partp));
+ return;
+ }
+
+ /* Start c/h/s. */
+ partp->dp_scyl = partp->dp_ipl_cyl = start / dos_cylsecs;
+ partp->dp_shd = partp->dp_ipl_head = start % dos_cylsecs / dos_sectors;
+ partp->dp_ssect = partp->dp_ipl_sct = start % dos_sectors;
+
+ /* End c/h/s. */
+ end = start + size - cylsecs;
+ partp->dp_ecyl = end / dos_cylsecs;
+ partp->dp_ehd = end % dos_cylsecs / dos_sectors;
+ partp->dp_esect = end % dos_sectors;
+}
+
+static int
+open_disk(int flag)
+{
+ struct stat st;
+ int rwmode;
+
+ if (stat(disk, &st) == -1) {
+ if (errno == ENOENT)
+ return -2;
+ warnx("can't get file status of %s", disk);
+ return -1;
+ }
+ if ( !(st.st_mode & S_IFCHR) )
+ warnx("device %s is not character special", disk);
+ rwmode = I_flag || a_flag || B_flag || flag ? O_RDWR : O_RDONLY;
+ fd = open(disk, rwmode);
+ if (fd == -1 && errno == EPERM && rwmode == O_RDWR)
+ fd = open(disk, O_RDONLY);
+ if (fd == -1 && errno == ENXIO)
+ return -2;
+ if (fd == -1) {
+ warnx("can't open device %s", disk);
+ return -1;
+ }
+ if (get_params() == -1) {
+ warnx("can't get disk parameters on %s", disk);
+ return -1;
+ }
+ return fd;
+}
+
+static ssize_t
+read_disk(off_t sector, void *buf)
+{
+
+ lseek(fd, (sector * 512), 0);
+ return read(fd, buf,
+ secsize > MIN_SEC_SIZE ? secsize : MIN_SEC_SIZE * 2);
+}
+
+static int
+write_disk(off_t sector, void *buf)
+{
+ int error;
+ struct gctl_req *grq;
+ const char *q;
+ char fbuf[BUFSIZ];
+ int i, fdw, sz;
+
+ sz = secsize > MIN_SEC_SIZE ? secsize : MIN_SEC_SIZE * 2;
+ grq = gctl_get_handle();
+ gctl_ro_param(grq, "verb", -1, "write PC98");
+ gctl_ro_param(grq, "class", -1, "PC98");
+ q = strrchr(disk, '/');
+ if (q == NULL)
+ q = disk;
+ else
+ q++;
+ gctl_ro_param(grq, "geom", -1, q);
+ gctl_ro_param(grq, "data", sz, buf);
+ q = gctl_issue(grq);
+ if (q == NULL) {
+ gctl_free(grq);
+ return(0);
+ }
+ warnx("Geom problem: %s", q);
+ gctl_free(grq);
+
+ warnx("Warning: Partitioning via geom failed, trying raw write");
+ error = pwrite(fd, buf, sz, sector * 512);
+ if (error == sz)
+ return (0);
+
+ for (i = 0; i < PC98_NPARTS; i++) {
+ sprintf(fbuf, "%ss%d", disk, i + 1);
+ fdw = open(fbuf, O_RDWR, 0);
+ if (fdw < 0)
+ continue;
+ error = ioctl(fdw, DIOCSPC98, buf);
+ close(fdw);
+ if (error == 0)
+ return (0);
+ }
+ warnx("Failed to write sector zero");
+ return(EINVAL);
+}
+
+static int
+get_params()
+{
+ int error;
+ u_int u;
+ off_t o;
+
+ error = ioctl(fd, DIOCGFWSECTORS, &u);
+ if (error == 0)
+ sectors = dos_sectors = u;
+ else
+ sectors = dos_sectors = 17;
+
+ error = ioctl(fd, DIOCGFWHEADS, &u);
+ if (error == 0)
+ heads = dos_heads = u;
+ else
+ heads = dos_heads = 8;
+
+ dos_cylsecs = cylsecs = heads * sectors;
+ disksecs = cyls * heads * sectors;
+
+ error = ioctl(fd, DIOCGSECTORSIZE, &u);
+ if (error != 0 || u == 0)
+ u = 512;
+ secsize = u;
+
+ error = ioctl(fd, DIOCGMEDIASIZE, &o);
+ if (error == 0) {
+ disksecs = o / u;
+ cyls = dos_cyls = o / (u * dos_heads * dos_sectors);
+ }
+
+ return (disksecs);
+}
+
+
+static int
+read_s0()
+{
+
+ if (read_disk(0, (char *) mboot.bootinst) == -1) {
+ warnx("can't read fdisk partition table");
+ return -1;
+ }
+ if (mboot.signature != PC98_MAGIC) {
+ warnx("invalid fdisk partition table found");
+ /* So should we initialize things */
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+write_s0()
+{
+
+ if (iotest) {
+ print_s0(-1);
+ return 0;
+ }
+
+ /*
+ * write enable label sector before write (if necessary),
+ * disable after writing.
+ * needed if the disklabel protected area also protects
+ * sector 0. (e.g. empty disk)
+ */
+ if (write_disk(0, (char *) mboot.bootinst) == -1) {
+ warn("can't write fdisk partition table");
+ return -1;
+ }
+
+ return(0);
+}
+
+
+static int
+ok(const char *str)
+{
+ printf("%s [n] ", str);
+ fflush(stdout);
+ if (fgets(lbuf, LBUF, stdin) == NULL)
+ exit(1);
+ lbuf[strlen(lbuf)-1] = 0;
+
+ if (*lbuf &&
+ (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") ||
+ !strcmp(lbuf, "y") || !strcmp(lbuf, "Y")))
+ return 1;
+ else
+ return 0;
+}
+
+static int
+decimal(const char *str, int *num, int deflt)
+{
+ int acc = 0, c;
+ char *cp;
+
+ while (1) {
+ printf("Supply a decimal value for \"%s\" [%d] ", str, deflt);
+ fflush(stdout);
+ if (fgets(lbuf, LBUF, stdin) == NULL)
+ exit(1);
+ lbuf[strlen(lbuf)-1] = 0;
+
+ if (!*lbuf)
+ return 0;
+
+ cp = lbuf;
+ while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
+ if (!c)
+ return 0;
+ while ((c = *cp++)) {
+ if (c <= '9' && c >= '0')
+ acc = acc * 10 + c - '0';
+ else
+ break;
+ }
+ if (c == ' ' || c == '\t')
+ while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
+ if (!c) {
+ *num = acc;
+ return 1;
+ } else
+ printf("%s is an invalid decimal number. Try again.\n",
+ lbuf);
+ }
+
+}
+
+static int
+string(const char *str, char **ans)
+{
+ int i, c;
+ char *cp = lbuf;
+
+ while (1) {
+ printf("Supply a string value for \"%s\" [%s] ", str, *ans);
+ fgets(lbuf, LBUF, stdin);
+ lbuf[strlen(lbuf)-1] = 0;
+
+ if (!*lbuf)
+ return 0;
+
+ while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
+ if (c == '"') {
+ c = *++cp;
+ *ans = cp;
+ while ((c = *cp) && c != '"') cp++;
+ } else {
+ *ans = cp;
+ while ((c = *cp) && c != ' ' && c != '\t') cp++;
+ }
+
+ for (i = strlen(*ans); i < 16; i++)
+ (*ans)[i] = ' ';
+ (*ans)[16] = 0;
+
+ return 1;
+ }
+}
+
+static const char *
+get_type(int type)
+{
+ int numentries = (sizeof(part_types)/sizeof(struct part_type));
+ int counter = 0;
+ struct part_type *ptr = part_types;
+
+
+ while(counter < numentries) {
+ if(ptr->type == (type & 0x7f))
+ return(ptr->name);
+ ptr++;
+ counter++;
+ }
+ return("unknown");
+}
+
+/*
+ * Try figuring out the root device's canonical disk name.
+ * The following choices are considered:
+ * /dev/ad0s1a => /dev/ad0
+ * /dev/da0a => /dev/da0
+ * /dev/vinum/root => /dev/vinum/root
+ */
+static char *
+get_rootdisk(void)
+{
+ struct statfs rootfs;
+ regex_t re;
+#define NMATCHES 2
+ regmatch_t rm[NMATCHES];
+ char *s;
+ int rv;
+
+ if (statfs("/", &rootfs) == -1)
+ err(1, "statfs(\"/\")");
+
+ if ((rv = regcomp(&re, "^(/dev/[a-z]+[0-9]+)([sp][0-9]+)?[a-h]?$",
+ REG_EXTENDED)) != 0)
+ errx(1, "regcomp() failed (%d)", rv);
+ if ((rv = regexec(&re, rootfs.f_mntfromname, NMATCHES, rm, 0)) != 0)
+ errx(1,
+"mounted root fs resource doesn't match expectations (regexec returned %d)",
+ rv);
+ if ((s = malloc(rm[1].rm_eo - rm[1].rm_so + 1)) == NULL)
+ errx(1, "out of memory");
+ memcpy(s, rootfs.f_mntfromname + rm[1].rm_so,
+ rm[1].rm_eo - rm[1].rm_so);
+ s[rm[1].rm_eo - rm[1].rm_so] = 0;
+
+ return s;
+}
+
+static void
+reset_boot(void)
+{
+ int i;
+ struct pc98_partition *partp;
+
+ init_boot();
+ for (i = 1; i <= PC98_NPARTS; i++) {
+ partp = ((struct pc98_partition *) &mboot.parts) + i - 1;
+ bzero((char *)partp, sizeof (struct pc98_partition));
+ }
+}
Property changes on: trunk/sbin/fdisk_pc98/fdisk.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
More information about the Midnightbsd-cvs
mailing list