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