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