Home | History | Annotate | Line # | Download | only in inst
inst.c revision 1.1
      1  1.1  thorpej /*	$NetBSD: inst.c,v 1.1 1997/02/04 03:52:57 thorpej Exp $	*/
      2  1.1  thorpej 
      3  1.1  thorpej /*
      4  1.1  thorpej  * Copyright (c) 1995, 1996 Jason R. Thorpe.
      5  1.1  thorpej  * All rights reserved.
      6  1.1  thorpej  *
      7  1.1  thorpej  * Redistribution and use in source and binary forms, with or without
      8  1.1  thorpej  * modification, are permitted provided that the following conditions
      9  1.1  thorpej  * are met:
     10  1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     11  1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     12  1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     15  1.1  thorpej  * 3. All advertising materials mentioning features or use of this software
     16  1.1  thorpej  *    must display the following acknowledgement:
     17  1.1  thorpej  *	This product includes software developed for the NetBSD Project
     18  1.1  thorpej  *	by Jason R. Thorpe.
     19  1.1  thorpej  * 4. The name of the author may not be used to endorse or promote products
     20  1.1  thorpej  *    derived from this software without specific prior written permission.
     21  1.1  thorpej  *
     22  1.1  thorpej  * Portions of this program are inspired by (and have borrowed code from)
     23  1.1  thorpej  * the `editlabel' program that accompanies NetBSD/vax, which carries
     24  1.1  thorpej  * the following notice:
     25  1.1  thorpej  *
     26  1.1  thorpej  * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
     27  1.1  thorpej  * All rights reserved.
     28  1.1  thorpej  *
     29  1.1  thorpej  * Redistribution and use in source and binary forms, with or without
     30  1.1  thorpej  * modification, are permitted provided that the following conditions
     31  1.1  thorpej  * are met:
     32  1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     33  1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     34  1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     35  1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     36  1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     37  1.1  thorpej  * 3. All advertising materials mentioning features or use of this software
     38  1.1  thorpej  *    must display the following acknowledgement:
     39  1.1  thorpej  *	This product includes software developed at Ludd, University of
     40  1.1  thorpej  *	Lule}, Sweden and its contributors.
     41  1.1  thorpej  * 4. The name of the author may not be used to endorse or promote products
     42  1.1  thorpej  *    derived from this software without specific prior written permission
     43  1.1  thorpej  *
     44  1.1  thorpej  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     45  1.1  thorpej  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     46  1.1  thorpej  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     47  1.1  thorpej  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     48  1.1  thorpej  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     49  1.1  thorpej  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     50  1.1  thorpej  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     51  1.1  thorpej  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     52  1.1  thorpej  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     53  1.1  thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     54  1.1  thorpej  * SUCH DAMAGE.
     55  1.1  thorpej  */
     56  1.1  thorpej 
     57  1.1  thorpej #define DKTYPENAMES
     58  1.1  thorpej 
     59  1.1  thorpej #include <sys/param.h>
     60  1.1  thorpej #include <sys/reboot.h>
     61  1.1  thorpej #include <sys/disklabel.h>
     62  1.1  thorpej #include <a.out.h>
     63  1.1  thorpej 
     64  1.1  thorpej #include <lib/libsa/stand.h>
     65  1.1  thorpej 
     66  1.1  thorpej #include <hp300/stand/common/samachdep.h>
     67  1.1  thorpej 
     68  1.1  thorpej char line[100];
     69  1.1  thorpej 
     70  1.1  thorpej extern	u_int opendev;
     71  1.1  thorpej extern	char *lowram;
     72  1.1  thorpej extern	int noconsole;
     73  1.1  thorpej extern	int netio_ask;
     74  1.1  thorpej 
     75  1.1  thorpej char	*kernel_name = "/netbsd";
     76  1.1  thorpej 
     77  1.1  thorpej void	dsklabel __P((void));
     78  1.1  thorpej void	miniroot __P((void));
     79  1.1  thorpej void	bootmini __P((void));
     80  1.1  thorpej void	resetsys __P((void));
     81  1.1  thorpej void	gethelp __P((void));
     82  1.1  thorpej int	opendisk __P((char *, char *, int, char, int *));
     83  1.1  thorpej void	disklabel_edit __P((struct disklabel *));
     84  1.1  thorpej void	disklabel_show __P((struct disklabel *));
     85  1.1  thorpej int	disklabel_write __P((char *, int, struct open_file *));
     86  1.1  thorpej int	a2int __P((char *));
     87  1.1  thorpej 
     88  1.1  thorpej struct	inst_command {
     89  1.1  thorpej 	char	*ic_cmd;		/* command name */
     90  1.1  thorpej 	char	*ic_desc;		/* command description */
     91  1.1  thorpej 	void	(*ic_func) __P((void));	/* handling function */
     92  1.1  thorpej } inst_commands[] = {
     93  1.1  thorpej 	{ "disklabel",	"place partition map on disk",	dsklabel },
     94  1.1  thorpej 	{ "miniroot",	"place miniroot on disk",	miniroot },
     95  1.1  thorpej 	{ "boot",	"boot from miniroot",		bootmini },
     96  1.1  thorpej 	{ "reset",	"reset the system",		resetsys },
     97  1.1  thorpej 	{ "help",	"display command list",		gethelp },
     98  1.1  thorpej };
     99  1.1  thorpej #define NCMDS	(sizeof(inst_commands) / sizeof(inst_commands[0]))
    100  1.1  thorpej 
    101  1.1  thorpej main()
    102  1.1  thorpej {
    103  1.1  thorpej 	int i, currname = 0;
    104  1.1  thorpej 
    105  1.1  thorpej 	/*
    106  1.1  thorpej 	 * We want netopen() to ask for IP address, etc, rather
    107  1.1  thorpej 	 * that using bootparams.
    108  1.1  thorpej 	 */
    109  1.1  thorpej 	netio_ask = 1;
    110  1.1  thorpej 
    111  1.1  thorpej 	printf("\n");
    112  1.1  thorpej 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
    113  1.1  thorpej 	printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
    114  1.1  thorpej 	printf(">> HP 9000/%s CPU\n", getmachineid());
    115  1.1  thorpej 	gethelp();
    116  1.1  thorpej 
    117  1.1  thorpej 	for (;;) {
    118  1.1  thorpej 		printf("sys_inst> ");
    119  1.1  thorpej 		bzero(line, sizeof(line));
    120  1.1  thorpej 		gets(line);
    121  1.1  thorpej 		if (line[0] == '\n' || line[0] == '\0')
    122  1.1  thorpej 			continue;
    123  1.1  thorpej 
    124  1.1  thorpej 		for (i = 0; i < NCMDS; ++i)
    125  1.1  thorpej 			if (strcmp(line, inst_commands[i].ic_cmd) == 0) {
    126  1.1  thorpej 				(*inst_commands[i].ic_func)();
    127  1.1  thorpej 				break;
    128  1.1  thorpej 			}
    129  1.1  thorpej 
    130  1.1  thorpej 
    131  1.1  thorpej 		if (i == NCMDS)
    132  1.1  thorpej 			printf("unknown command: %s\n", line);
    133  1.1  thorpej 	}
    134  1.1  thorpej }
    135  1.1  thorpej 
    136  1.1  thorpej void
    137  1.1  thorpej gethelp()
    138  1.1  thorpej {
    139  1.1  thorpej 	int i;
    140  1.1  thorpej 
    141  1.1  thorpej 	printf(">> Available commands:\n");
    142  1.1  thorpej 	for (i = 0; i < NCMDS; ++i)
    143  1.1  thorpej 		printf(">>     %s - %s\n", inst_commands[i].ic_cmd,
    144  1.1  thorpej 		    inst_commands[i].ic_desc);
    145  1.1  thorpej }
    146  1.1  thorpej 
    147  1.1  thorpej /*
    148  1.1  thorpej  * Do all the steps necessary to place a disklabel on a disk.
    149  1.1  thorpej  * Note, this assumes 512 byte sectors.
    150  1.1  thorpej  */
    151  1.1  thorpej void
    152  1.1  thorpej dsklabel()
    153  1.1  thorpej {
    154  1.1  thorpej 	struct disklabel *lp;
    155  1.1  thorpej 	struct open_file *disk_ofp;
    156  1.1  thorpej 	int dfd, error;
    157  1.1  thorpej 	size_t xfersize;
    158  1.1  thorpej 	char block[DEV_BSIZE], diskname[64];
    159  1.1  thorpej 	extern struct open_file files[];
    160  1.1  thorpej 
    161  1.1  thorpej 	printf("
    162  1.1  thorpej You will be asked several questions about your disk, most of which
    163  1.1  thorpej require prior knowledge of the disk's geometry.  There is no easy way
    164  1.1  thorpej for the system to provide this information for you.  If you do not have
    165  1.1  thorpej this information, please consult your disk's manual or another
    166  1.1  thorpej informative source.\n\n");
    167  1.1  thorpej 
    168  1.1  thorpej 	/* Error message printed by opendisk() */
    169  1.1  thorpej 	if (opendisk("Disk to label?", diskname, sizeof(diskname),
    170  1.1  thorpej 	    ('a' + RAW_PART), &dfd))
    171  1.1  thorpej 		return;
    172  1.1  thorpej 
    173  1.1  thorpej 	disk_ofp = &files[dfd];
    174  1.1  thorpej 
    175  1.1  thorpej 	bzero(block, sizeof(block));
    176  1.1  thorpej 	if (error = (*disk_ofp->f_dev->dv_strategy)(disk_ofp->f_devdata,
    177  1.1  thorpej 	    F_READ, LABELSECTOR, sizeof(block), block, &xfersize)) {
    178  1.1  thorpej 		printf("cannot read disk %s, errno = %d\n", diskname, error);
    179  1.1  thorpej 		return;
    180  1.1  thorpej 	}
    181  1.1  thorpej 
    182  1.1  thorpej 	printf("Sucessfully read %d bytes from %s\n", xfersize, diskname);
    183  1.1  thorpej 
    184  1.1  thorpej 	lp = (struct disklabel *)((void *)(&block[LABELOFFSET]));
    185  1.1  thorpej 
    186  1.1  thorpej  disklabel_loop:
    187  1.1  thorpej 	bzero(line, sizeof(line));
    188  1.1  thorpej 	printf("(z)ap, (e)dit, (s)how, (w)rite, (d)one > ");
    189  1.1  thorpej 	gets(line);
    190  1.1  thorpej 	if (line[0] == '\n' || line[0] == '\0')
    191  1.1  thorpej 		goto disklabel_loop;
    192  1.1  thorpej 
    193  1.1  thorpej 	switch (line[0]) {
    194  1.1  thorpej 	case 'z':
    195  1.1  thorpej 	case 'Z': {
    196  1.1  thorpej 		char zap[DEV_BSIZE];
    197  1.1  thorpej 		bzero(zap, sizeof(zap));
    198  1.1  thorpej 		(void)(*disk_ofp->f_dev->dv_strategy)(disk_ofp->f_devdata,
    199  1.1  thorpej 		    F_WRITE, LABELSECTOR, sizeof(zap), zap, &xfersize);
    200  1.1  thorpej 		}
    201  1.1  thorpej 		goto out;
    202  1.1  thorpej 		/* NOTREACHED */
    203  1.1  thorpej 
    204  1.1  thorpej 	case 'e':
    205  1.1  thorpej 	case 'E':
    206  1.1  thorpej 		disklabel_edit(lp);
    207  1.1  thorpej 		break;
    208  1.1  thorpej 
    209  1.1  thorpej 	case 's':
    210  1.1  thorpej 	case 'S':
    211  1.1  thorpej 		disklabel_show(lp);
    212  1.1  thorpej 		break;
    213  1.1  thorpej 
    214  1.1  thorpej 	case 'w':
    215  1.1  thorpej 	case 'W':
    216  1.1  thorpej 		/*
    217  1.1  thorpej 		 * Error message will be displayed by disklabel_write()
    218  1.1  thorpej 		 */
    219  1.1  thorpej 		if (disklabel_write(block, sizeof(block), disk_ofp))
    220  1.1  thorpej 			goto out;
    221  1.1  thorpej 		else
    222  1.1  thorpej 			printf("Sucessfully wrote label to %s\n", diskname);
    223  1.1  thorpej 		break;
    224  1.1  thorpej 
    225  1.1  thorpej 	case 'd':
    226  1.1  thorpej 	case 'D':
    227  1.1  thorpej 		goto out;
    228  1.1  thorpej 		/* NOTREACHED */
    229  1.1  thorpej 
    230  1.1  thorpej 	default:
    231  1.1  thorpej 		printf("unkown command: %s\n", line);
    232  1.1  thorpej 	}
    233  1.1  thorpej 
    234  1.1  thorpej 	goto disklabel_loop;
    235  1.1  thorpej 	/* NOTREACHED */
    236  1.1  thorpej 
    237  1.1  thorpej  out:
    238  1.1  thorpej 	/*
    239  1.1  thorpej 	 * Close disk.  Marks disk `not alive' so that partition
    240  1.1  thorpej 	 * information will be reloaded upon next open.
    241  1.1  thorpej 	 */
    242  1.1  thorpej 	(void)close(dfd);
    243  1.1  thorpej }
    244  1.1  thorpej 
    245  1.1  thorpej #define GETNUM(out, num)						\
    246  1.1  thorpej 	printf((out), (num));						\
    247  1.1  thorpej 	bzero(line, sizeof(line));					\
    248  1.1  thorpej 	gets(line);							\
    249  1.1  thorpej 	if (line[0])							\
    250  1.1  thorpej 		(num) = atoi(line);
    251  1.1  thorpej 
    252  1.1  thorpej #define GETNUM2(out, num1, num2)					\
    253  1.1  thorpej 	printf((out), (num1), (num2));					\
    254  1.1  thorpej 	bzero(line, sizeof(line));					\
    255  1.1  thorpej 	gets(line);							\
    256  1.1  thorpej 	if (line[0])							\
    257  1.1  thorpej 		(num2) = atoi(line);
    258  1.1  thorpej 
    259  1.1  thorpej #define GETSTR(out, str)						\
    260  1.1  thorpej 	printf((out), (str));						\
    261  1.1  thorpej 	bzero(line, sizeof(line));					\
    262  1.1  thorpej 	gets(line);							\
    263  1.1  thorpej 	if (line[0])							\
    264  1.1  thorpej 		strcpy((str), line);
    265  1.1  thorpej 
    266  1.1  thorpej #define FLAGS(out, flag)						\
    267  1.1  thorpej 	printf((out), lp->d_flags & (flag) ? 'y' : 'n');		\
    268  1.1  thorpej 	bzero(line, sizeof(line));					\
    269  1.1  thorpej 	gets(line);							\
    270  1.1  thorpej 	if (line[0] == 'y' || line[0] == 'Y')				\
    271  1.1  thorpej 		lp->d_flags |= (flag);					\
    272  1.1  thorpej 	else								\
    273  1.1  thorpej 		lp->d_flags &= ~(flag);
    274  1.1  thorpej 
    275  1.1  thorpej void
    276  1.1  thorpej disklabel_edit(lp)
    277  1.1  thorpej 	struct disklabel *lp;
    278  1.1  thorpej {
    279  1.1  thorpej 	int i;
    280  1.1  thorpej 
    281  1.1  thorpej 	printf("Select disk type.  Valid types:\n");
    282  1.1  thorpej 	for (i = 0; i < DKMAXTYPES; i++)
    283  1.1  thorpej 		printf("%d     %s\n", i, dktypenames[i]);
    284  1.1  thorpej 	printf("\n");
    285  1.1  thorpej 
    286  1.1  thorpej 	GETNUM("Disk type (number)? [%d] ", lp->d_type);
    287  1.1  thorpej 	GETSTR("Disk model name? [%s] ", lp->d_typename);
    288  1.1  thorpej 	GETSTR("Disk pack name? [%s] ", lp->d_packname);
    289  1.1  thorpej 	FLAGS("Bad sectoring? [%c] ", D_BADSECT);
    290  1.1  thorpej 	FLAGS("Ecc? [%c] ", D_ECC);
    291  1.1  thorpej 	FLAGS("Removable? [%c] ", D_REMOVABLE);
    292  1.1  thorpej 
    293  1.1  thorpej 	printf("\n");
    294  1.1  thorpej 
    295  1.1  thorpej 	GETNUM("Interleave? [%d] ", lp->d_interleave);
    296  1.1  thorpej 	GETNUM("Rpm? [%d] ", lp->d_rpm);
    297  1.1  thorpej 	GETNUM("Trackskew? [%d] ", lp->d_trackskew);
    298  1.1  thorpej 	GETNUM("Cylinderskew? [%d] ", lp->d_cylskew);
    299  1.1  thorpej 	GETNUM("Headswitch? [%d] ", lp->d_headswitch);
    300  1.1  thorpej 	GETNUM("Track-to-track? [%d] ", lp->d_trkseek);
    301  1.1  thorpej 	GETNUM("Drivedata 0? [%d] ", lp->d_drivedata[0]);
    302  1.1  thorpej 	GETNUM("Drivedata 1? [%d] ", lp->d_drivedata[1]);
    303  1.1  thorpej 	GETNUM("Drivedata 2? [%d] ", lp->d_drivedata[2]);
    304  1.1  thorpej 	GETNUM("Drivedata 3? [%d] ", lp->d_drivedata[3]);
    305  1.1  thorpej 	GETNUM("Drivedata 4? [%d] ", lp->d_drivedata[4]);
    306  1.1  thorpej 
    307  1.1  thorpej 	printf("\n");
    308  1.1  thorpej 
    309  1.1  thorpej 	GETNUM("Bytes/sector? [%d] ", lp->d_secsize);
    310  1.1  thorpej 	GETNUM("Sectors/track? [%d] ", lp->d_nsectors);
    311  1.1  thorpej 	GETNUM("Tracks/cylinder? [%d] ", lp->d_ntracks);
    312  1.1  thorpej 	GETNUM("Sectors/cylinder? [%d] ", lp->d_secpercyl);
    313  1.1  thorpej 	GETNUM("Cylinders? [%d] ", lp->d_ncylinders);
    314  1.1  thorpej 
    315  1.1  thorpej 	printf("
    316  1.1  thorpej Enter partition table.  Note, sizes and offsets are in sectors.\n\n");
    317  1.1  thorpej 
    318  1.1  thorpej 	lp->d_npartitions = MAXPARTITIONS;
    319  1.1  thorpej 	for (i = 0; i < lp->d_npartitions; ++i) {
    320  1.1  thorpej 		GETNUM2("%c partition: offset? [%d] ", ('a' + i),
    321  1.1  thorpej 		    lp->d_partitions[i].p_offset);
    322  1.1  thorpej 		GETNUM("             size? [%d] ", lp->d_partitions[i].p_size);
    323  1.1  thorpej 	}
    324  1.1  thorpej 
    325  1.1  thorpej 	/* Perform magic. */
    326  1.1  thorpej 	lp->d_magic = lp->d_magic2 = DISKMAGIC;
    327  1.1  thorpej 
    328  1.1  thorpej 	/* Calculate disklabel checksum. */
    329  1.1  thorpej 	lp->d_checksum = 0;
    330  1.1  thorpej 	lp->d_checksum = dkcksum(lp);
    331  1.1  thorpej }
    332  1.1  thorpej 
    333  1.1  thorpej void
    334  1.1  thorpej disklabel_show(lp)
    335  1.1  thorpej 	struct disklabel *lp;
    336  1.1  thorpej {
    337  1.1  thorpej 	int i, npart;
    338  1.1  thorpej 	struct partition *pp;
    339  1.1  thorpej 
    340  1.1  thorpej 	/*
    341  1.1  thorpej 	 * Check for valid disklabel.
    342  1.1  thorpej 	 */
    343  1.1  thorpej 	if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
    344  1.1  thorpej 		printf("No disklabel to show.\n");
    345  1.1  thorpej 		return;
    346  1.1  thorpej 	}
    347  1.1  thorpej 
    348  1.1  thorpej 	if (lp->d_npartitions > MAXPARTITIONS || dkcksum(lp) != 0) {
    349  1.1  thorpej 		printf("Corrupted disklabel.\n");
    350  1.1  thorpej 		return;
    351  1.1  thorpej 	}
    352  1.1  thorpej 
    353  1.1  thorpej 	printf("\ndisk type %d (%s), %s: %s%s%s\n", lp->d_type,
    354  1.1  thorpej 	    lp->d_type < DKMAXTYPES ? dktypenames[lp->d_type] :
    355  1.1  thorpej 	    dktypenames[0], lp->d_typename,
    356  1.1  thorpej 	    (lp->d_flags & D_REMOVABLE) ? " removable" : "",
    357  1.1  thorpej 	    (lp->d_flags & D_ECC) ? " ecc" : "",
    358  1.1  thorpej 	    (lp->d_flags & D_BADSECT) ? " badsect" : "");
    359  1.1  thorpej 
    360  1.1  thorpej 	printf("interleave %d, rpm %d, trackskew %d, cylinderskew %d\n",
    361  1.1  thorpej 	    lp->d_interleave, lp->d_rpm, lp->d_trackskew, lp->d_cylskew);
    362  1.1  thorpej 
    363  1.1  thorpej 	printf("headswitch %d, track-to-track %d, drivedata: %d %d %d %d %d\n",
    364  1.1  thorpej 	    lp->d_headswitch, lp->d_trkseek, lp->d_drivedata[0],
    365  1.1  thorpej 	    lp->d_drivedata[1], lp->d_drivedata[2], lp->d_drivedata[3],
    366  1.1  thorpej 	    lp->d_drivedata[4]);
    367  1.1  thorpej 
    368  1.1  thorpej 	printf("\nbytes/sector: %d\n", lp->d_secsize);
    369  1.1  thorpej 	printf("sectors/track: %d\n", lp->d_nsectors);
    370  1.1  thorpej 	printf("tracks/cylinder: %d\n", lp->d_ntracks);
    371  1.1  thorpej 	printf("sectors/cylinder: %d\n", lp->d_secpercyl);
    372  1.1  thorpej 	printf("cylinders: %d\n", lp->d_ncylinders);
    373  1.1  thorpej 
    374  1.1  thorpej 	printf("\n%d partitions:\n", lp->d_npartitions);
    375  1.1  thorpej 	printf("     size   offset\n");
    376  1.1  thorpej 	pp = lp->d_partitions;
    377  1.1  thorpej 	for (i = 0; i < lp->d_npartitions; i++) {
    378  1.1  thorpej 		printf("%c:   %d,    %d\n", 97 + i, lp->d_partitions[i].p_size,
    379  1.1  thorpej 		    lp->d_partitions[i].p_offset);
    380  1.1  thorpej 	}
    381  1.1  thorpej 	printf("\n");
    382  1.1  thorpej }
    383  1.1  thorpej 
    384  1.1  thorpej int
    385  1.1  thorpej disklabel_write(block, len, ofp)
    386  1.1  thorpej 	char *block;
    387  1.1  thorpej 	int len;
    388  1.1  thorpej 	struct open_file *ofp;
    389  1.1  thorpej {
    390  1.1  thorpej 	int error = 0;
    391  1.1  thorpej 	size_t xfersize;
    392  1.1  thorpej 
    393  1.1  thorpej 	if (error = (*ofp->f_dev->dv_strategy)(ofp->f_devdata, F_WRITE,
    394  1.1  thorpej 	    LABELSECTOR, len, block, &xfersize))
    395  1.1  thorpej 		printf("cannot write disklabel, errno = %d\n", error);
    396  1.1  thorpej 
    397  1.1  thorpej 	return (error);
    398  1.1  thorpej }
    399  1.1  thorpej 
    400  1.1  thorpej int
    401  1.1  thorpej opendisk(question, diskname, len, partition, fdp)
    402  1.1  thorpej 	char *question, *diskname;
    403  1.1  thorpej 	int len;
    404  1.1  thorpej 	char partition;
    405  1.1  thorpej 	int *fdp;
    406  1.1  thorpej {
    407  1.1  thorpej 	char fulldiskname[64], *filename;
    408  1.1  thorpej 	int i, error = 0;
    409  1.1  thorpej 
    410  1.1  thorpej  getdiskname:
    411  1.1  thorpej 	printf("%s ", question);
    412  1.1  thorpej 	bzero(diskname, len);
    413  1.1  thorpej 	bzero(fulldiskname, sizeof(fulldiskname));
    414  1.1  thorpej 	gets(diskname);
    415  1.1  thorpej 	if (diskname[0] == '\n' || diskname[0] == '\0')
    416  1.1  thorpej 		goto getdiskname;
    417  1.1  thorpej 
    418  1.1  thorpej 	/*
    419  1.1  thorpej 	 * devopen() is picky.  Make sure it gets the sort of string it
    420  1.1  thorpej 	 * wants.
    421  1.1  thorpej 	 */
    422  1.1  thorpej 	bcopy(diskname, fulldiskname,
    423  1.1  thorpej 	    len < sizeof(fulldiskname) ? len : sizeof(fulldiskname));
    424  1.1  thorpej 	for (i = 0; fulldiskname[i + 1] != '\0'; ++i)
    425  1.1  thorpej 		/* Nothing. */ ;
    426  1.1  thorpej 	if (fulldiskname[i] < '0' || fulldiskname[i] > '9') {
    427  1.1  thorpej 		printf("invalid disk name %s\n", diskname);
    428  1.1  thorpej 		goto getdiskname;
    429  1.1  thorpej 	}
    430  1.1  thorpej 	fulldiskname[++i] = partition; fulldiskname[++i] = ':';
    431  1.1  thorpej 
    432  1.1  thorpej 	/*
    433  1.1  thorpej 	 * We always open for writing.
    434  1.1  thorpej 	 */
    435  1.1  thorpej 	if ((*fdp = open(fulldiskname, 1)) < 0) {
    436  1.1  thorpej 		printf("cannot open %s\n", diskname);
    437  1.1  thorpej 		return (1);
    438  1.1  thorpej 	}
    439  1.1  thorpej 
    440  1.1  thorpej 	return (0);
    441  1.1  thorpej }
    442  1.1  thorpej 
    443  1.1  thorpej /*
    444  1.1  thorpej  * Copy a miniroot image from an NFS server or tape to the `b' partition
    445  1.1  thorpej  * of the specified disk.  Note, this assumes 512 byte sectors.
    446  1.1  thorpej  */
    447  1.1  thorpej void
    448  1.1  thorpej miniroot()
    449  1.1  thorpej {
    450  1.1  thorpej 	int sfd, dfd, i, nblks;
    451  1.1  thorpej 	char diskname[64], minirootname[128];
    452  1.1  thorpej 	char block[DEV_BSIZE];
    453  1.1  thorpej 	char tapename[64];
    454  1.1  thorpej 	int fileno;
    455  1.1  thorpej 	struct stat st;
    456  1.1  thorpej 	size_t xfersize;
    457  1.1  thorpej 	struct open_file *disk_ofp;
    458  1.1  thorpej 	extern struct open_file files[];
    459  1.1  thorpej 
    460  1.1  thorpej 	/* Error message printed by opendisk() */
    461  1.1  thorpej 	if (opendisk("Disk for miniroot?", diskname, sizeof(diskname),
    462  1.1  thorpej 	    'b', &dfd))
    463  1.1  thorpej 		return;
    464  1.1  thorpej 
    465  1.1  thorpej 	disk_ofp = &files[dfd];
    466  1.1  thorpej 
    467  1.1  thorpej  getsource:
    468  1.1  thorpej 	printf("Source? (N)FS, (t)ape, (d)one > ");
    469  1.1  thorpej 	bzero(line, sizeof(line));
    470  1.1  thorpej 	gets(line);
    471  1.1  thorpej 	if (line[0] == '\0')
    472  1.1  thorpej 		goto getsource;
    473  1.1  thorpej 
    474  1.1  thorpej 	switch (line[0]) {
    475  1.1  thorpej 	case 'n':
    476  1.1  thorpej 	case 'N':
    477  1.1  thorpej  name_of_nfs_miniroot:
    478  1.1  thorpej 		printf("Name of miniroot file? ");
    479  1.1  thorpej 		bzero(line, sizeof(line));
    480  1.1  thorpej 		bzero(minirootname, sizeof(minirootname));
    481  1.1  thorpej 		gets(line);
    482  1.1  thorpej 		if (line[0] == '\0')
    483  1.1  thorpej 			goto name_of_nfs_miniroot;
    484  1.1  thorpej 		(void)strcat(minirootname, "le0a:");
    485  1.1  thorpej 		(void)strcat(minirootname, line);
    486  1.1  thorpej 		if ((sfd = open(minirootname, 0)) < 0) {
    487  1.1  thorpej 			printf("can't open %s\n", line);
    488  1.1  thorpej 			return;
    489  1.1  thorpej 		}
    490  1.1  thorpej 
    491  1.1  thorpej 		/*
    492  1.1  thorpej 		 * Find out how big the miniroot is.  Make sure it's
    493  1.1  thorpej 		 * an even number of blocks...
    494  1.1  thorpej 		 */
    495  1.1  thorpej 		if (fstat(sfd, &st) < 0) {
    496  1.1  thorpej 			printf("can't stat %s\n", line);
    497  1.1  thorpej 			goto done;
    498  1.1  thorpej 		}
    499  1.1  thorpej 		if (st.st_size % DEV_BSIZE) {
    500  1.1  thorpej 			printf("Miniroot size must be an even multiple of %d\n",
    501  1.1  thorpej 			    DEV_BSIZE);
    502  1.1  thorpej 			return;
    503  1.1  thorpej 		}
    504  1.1  thorpej 		nblks = (int)(st.st_size / sizeof(block));
    505  1.1  thorpej 
    506  1.1  thorpej 		printf("Copying %d blocks from %s to %s...", nblks, line,
    507  1.1  thorpej 		    diskname);
    508  1.1  thorpej 		break;
    509  1.1  thorpej 
    510  1.1  thorpej 	case 't':
    511  1.1  thorpej 	case 'T':
    512  1.1  thorpej  name_of_tape_miniroot:
    513  1.1  thorpej 		printf("Which tape device? ");
    514  1.1  thorpej 		bzero(line, sizeof(line));
    515  1.1  thorpej 		bzero(minirootname, sizeof(minirootname));
    516  1.1  thorpej 		bzero(tapename, sizeof(tapename));
    517  1.1  thorpej 		gets(line);
    518  1.1  thorpej 		if (line[0] == '\0')
    519  1.1  thorpej 			goto name_of_tape_miniroot;
    520  1.1  thorpej 		strcat(minirootname, line);
    521  1.1  thorpej 		strcat(tapename, line);
    522  1.1  thorpej 
    523  1.1  thorpej 		printf("File number (first == 1)? ");
    524  1.1  thorpej 		bzero(line, sizeof(line));
    525  1.1  thorpej 		gets(line);
    526  1.1  thorpej 		fileno = a2int(line);
    527  1.1  thorpej 		if (fileno < 1 || fileno > 8) {
    528  1.1  thorpej 			printf("Invalid file number: %s\n", line);
    529  1.1  thorpej 			goto getsource;
    530  1.1  thorpej 		}
    531  1.1  thorpej 		for (i = 0; i < sizeof(minirootname); ++i) {
    532  1.1  thorpej 			if (minirootname[i] == '\0')
    533  1.1  thorpej 				break;
    534  1.1  thorpej 		}
    535  1.1  thorpej 		if (i == sizeof(minirootname) ||
    536  1.1  thorpej 		    (sizeof(minirootname) - i) < 8) {
    537  1.1  thorpej 			printf("Invalid device name: %s\n", tapename);
    538  1.1  thorpej 			goto getsource;
    539  1.1  thorpej 		}
    540  1.1  thorpej 		minirootname[i++] = 'a' + (fileno - 1);
    541  1.1  thorpej 		minirootname[i++] = ':';
    542  1.1  thorpej 		strcat(minirootname, "XXX");	/* lameness in open() */
    543  1.1  thorpej 
    544  1.1  thorpej 		printf("Copy how many %d byte blocks? ", DEV_BSIZE);
    545  1.1  thorpej 		bzero(line, sizeof(line));
    546  1.1  thorpej 		gets(line);
    547  1.1  thorpej 		nblks = a2int(line);
    548  1.1  thorpej 		if (nblks < 0) {
    549  1.1  thorpej 			printf("Invalid block count: %s\n", line);
    550  1.1  thorpej 			goto getsource;
    551  1.1  thorpej 		} else if (nblks == 0) {
    552  1.1  thorpej 			printf("Zero blocks?  Ok, aborting.\n");
    553  1.1  thorpej 			return;
    554  1.1  thorpej 		}
    555  1.1  thorpej 
    556  1.1  thorpej 		if ((sfd = open(minirootname, 0)) < 0) {
    557  1.1  thorpej 			printf("can't open %s file %c\n", tapename, fileno);
    558  1.1  thorpej 			return;
    559  1.1  thorpej 		}
    560  1.1  thorpej 
    561  1.1  thorpej 		printf("Copying %s file %c to %s...", tapename, fileno,
    562  1.1  thorpej 		    diskname);
    563  1.1  thorpej 		break;
    564  1.1  thorpej 
    565  1.1  thorpej 	case 'd':
    566  1.1  thorpej 	case 'D':
    567  1.1  thorpej 		return;
    568  1.1  thorpej 
    569  1.1  thorpej 	default:
    570  1.1  thorpej 		printf("Unknown source: %s\n", line);
    571  1.1  thorpej 		goto getsource;
    572  1.1  thorpej 	}
    573  1.1  thorpej 
    574  1.1  thorpej 	/*
    575  1.1  thorpej 	 * Copy loop...
    576  1.1  thorpej 	 * This is fairly slow... if someone wants to speed it
    577  1.1  thorpej 	 * up, they'll get no complaints from me.
    578  1.1  thorpej 	 */
    579  1.1  thorpej 	for (i = 0; i < nblks; ++i) {
    580  1.1  thorpej 		if (read(sfd, block, sizeof(block)) != sizeof(block)) {
    581  1.1  thorpej 			printf("Short read, errno = %d\n", errno);
    582  1.1  thorpej 			goto done;
    583  1.1  thorpej 		}
    584  1.1  thorpej 		if ((*disk_ofp->f_dev->dv_strategy)(disk_ofp->f_devdata,
    585  1.1  thorpej 		    F_WRITE, i, sizeof(block), block, &xfersize) ||
    586  1.1  thorpej 		    xfersize != sizeof(block)) {
    587  1.1  thorpej 			printf("Bad write at block %d, errno = %d\n",
    588  1.1  thorpej 			    i, errno);
    589  1.1  thorpej 			goto done;
    590  1.1  thorpej 		}
    591  1.1  thorpej 	}
    592  1.1  thorpej 	printf("done\n");
    593  1.1  thorpej 
    594  1.1  thorpej 	printf("Successfully copied miniroot image.\n");
    595  1.1  thorpej 
    596  1.1  thorpej  done:
    597  1.1  thorpej 	close(sfd);
    598  1.1  thorpej 	close(dfd);
    599  1.1  thorpej }
    600  1.1  thorpej 
    601  1.1  thorpej /*
    602  1.1  thorpej  * Boot the kernel from the miniroot image into single-user.
    603  1.1  thorpej  */
    604  1.1  thorpej void
    605  1.1  thorpej bootmini()
    606  1.1  thorpej {
    607  1.1  thorpej 	char diskname[64], bootname[64];
    608  1.1  thorpej 	int i;
    609  1.1  thorpej 
    610  1.1  thorpej  getdiskname:
    611  1.1  thorpej 	printf("Disk to boot from? ");
    612  1.1  thorpej 	bzero(diskname, sizeof(diskname));
    613  1.1  thorpej 	bzero(bootname, sizeof(bootname));
    614  1.1  thorpej 	gets(diskname);
    615  1.1  thorpej 	if (diskname[0] == '\n' || diskname[0] == '\0')
    616  1.1  thorpej 		goto getdiskname;
    617  1.1  thorpej 
    618  1.1  thorpej 	/*
    619  1.1  thorpej 	 * devopen() is picky.  Make sure it gets the sort of string it
    620  1.1  thorpej 	 * wants.
    621  1.1  thorpej 	 */
    622  1.1  thorpej 	(void)strcat(bootname, diskname);
    623  1.1  thorpej 	for (i = 0; bootname[i + 1] != '\0'; ++i)
    624  1.1  thorpej 		/* Nothing. */ ;
    625  1.1  thorpej 	if (bootname[i] < '0' || bootname[i] > '9') {
    626  1.1  thorpej 		printf("invalid disk name %s\n", diskname);
    627  1.1  thorpej 		goto getdiskname;
    628  1.1  thorpej 	}
    629  1.1  thorpej 	bootname[++i] = 'b'; bootname[++i] = ':';
    630  1.1  thorpej 	(void)strcat(bootname, kernel_name);
    631  1.1  thorpej 
    632  1.1  thorpej 	howto = RB_SINGLE;	/* _Always_ */
    633  1.1  thorpej 
    634  1.1  thorpej 	printf("booting: %s -s\n", bootname);
    635  1.1  thorpej 	exec(bootname, lowram, howto);
    636  1.1  thorpej 	printf("boot: %s\n", strerror(errno));
    637  1.1  thorpej }
    638  1.1  thorpej 
    639  1.1  thorpej /*
    640  1.1  thorpej  * Reset the system.
    641  1.1  thorpej  */
    642  1.1  thorpej void
    643  1.1  thorpej resetsys()
    644  1.1  thorpej {
    645  1.1  thorpej 
    646  1.1  thorpej 	call_req_reboot();
    647  1.1  thorpej 	printf("panic: can't reboot, halting\n");
    648  1.1  thorpej 	asm("stop #0x2700");
    649  1.1  thorpej }
    650  1.1  thorpej 
    651  1.1  thorpej /*
    652  1.1  thorpej  * XXX Should have a generic atoi for libkern/libsa.
    653  1.1  thorpej  */
    654  1.1  thorpej int
    655  1.1  thorpej a2int(cp)
    656  1.1  thorpej 	char *cp;
    657  1.1  thorpej {
    658  1.1  thorpej 	int i = 0;
    659  1.1  thorpej 
    660  1.1  thorpej 	if (*cp == '\0')
    661  1.1  thorpej 		return (-1);
    662  1.1  thorpej 
    663  1.1  thorpej 	while (*cp != '\0')
    664  1.1  thorpej 		i = i * 10 + *cp++ - '0';
    665  1.1  thorpej 	return (i);
    666  1.1  thorpej }
    667