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