[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