install.md revision 1.20 1 #!/bin/sh
2 #
3 # $NetBSD: install.md,v 1.20 2020/12/05 18:52:06 tsutsui Exp $
4 #
5 # Copyright (c) 1996 The NetBSD Foundation, Inc.
6 # All rights reserved.
7 #
8 # This code is derived from software contributed to The NetBSD Foundation
9 # by Jason R. Thorpe.
10 #
11 # Redistribution and use in source and binary forms, with or without
12 # modification, are permitted provided that the following conditions
13 # are met:
14 # 1. Redistributions of source code must retain the above copyright
15 # notice, this list of conditions and the following disclaimer.
16 # 2. Redistributions in binary form must reproduce the above copyright
17 # notice, this list of conditions and the following disclaimer in the
18 # documentation and/or other materials provided with the distribution.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 # POSSIBILITY OF SUCH DAMAGE.
31 #
32
33 #
34 # machine dependent section of installation/upgrade script
35 #
36
37 # Machine-dependent install sets
38 MDSETS="kern-GENERIC xbase xcomp xetc xfont xserver"
39
40 md_set_term() {
41 if [ ! -z "$TERM" ]; then
42 return
43 fi
44 echo -n "Specify terminal type [vt100]: "
45 getresp "vt100"
46 TERM="$resp"
47 export TERM
48 # XXX call tset?
49 }
50
51 md_makerootwritable() {
52 # Was: do_mfs_mount "/tmp" "2048"
53 # /tmp is the mount point
54 # 2048 is the size in DEV_BIZE blocks
55
56 umount /tmp > /dev/null 2>&1
57 if ! mount_mfs -s 2048 swap /tmp ; then
58 cat << \__mfs_failed_1
59
60 FATAL ERROR: Can't mount the memory filesystem.
61
62 __mfs_failed_1
63 exit
64 fi
65
66 # Bleh. Give mount_mfs a chance to DTRT.
67 sleep 2
68 }
69
70 md_get_diskdevs() {
71 # return available disk devices
72 mi_filter_dmesg | awk -F : '/^rd[0-9]*:./ { print $1; }' | sort -u
73 mi_filter_dmesg | awk -F : '/^sd[0-9]*:.*sectors/ { print $1; }' | sort -u
74 }
75
76 md_get_cddevs() {
77 # return available CD-ROM devices
78 mi_filter_dmesg | awk -F : '/^cd[0-9]*:/ { print $1; }' | sort -u
79 }
80
81 md_get_ifdevs() {
82 # return available network interfaces
83 mi_filter_dmesg | awk -F : '/^le[0-9]*:/ { print $1; }' | sort -u
84 }
85
86 md_get_partition_range() {
87 # return an expression describing the valid partition id's
88 echo '[a-h]'
89 }
90
91 md_installboot() {
92 # $1 is the root disk
93
94 echo -n "Installing boot block..."
95 /usr/sbin/installboot -v /dev/r${1}c /usr/mdec/uboot.lif
96 echo "done."
97 }
98
99 grep_check_q () {
100 pattern=$1; shift
101 awk 'BEGIN{ es=1; } /'"$pattern"'/{ es=0; } END{ exit es; }' "$@"
102 }
103
104 plain_grep () {
105 pattern=$1; shift
106 awk "/$pattern/"'{ print; }' "$@"
107 }
108
109 md_checkfordisklabel() {
110 # $1 is the disk to check
111
112 disklabel -r $1 > /dev/null 2> /tmp/checkfordisklabel
113 if grep_check_q "no disk label" /tmp/checkfordisklabel; then
114 rval="1"
115 elif grep_check_q "disk label corrupted" /tmp/checkfordisklabel; then
116 rval="2"
117 else
118 rval="0"
119 fi
120
121 rm -f /tmp/checkfordisklabel
122 }
123
124 hp300_init_label_scsi_disk() {
125 # $1 is the disk to label
126
127 # Name the disks we install in the temporary fstab.
128 if [ -z "${_disk_instance}" ]; then
129 _disk_instance="0"
130 else
131 _disk_instance=$(expr $_disk_instance + 1)
132 fi
133 _cur_disk_name="install-disk-${_disk_instance}"
134
135 # Get geometry information from the user.
136 more << \__scsi_label_1
137
138 You will need to provide some information about your disk's geometry.
139 Geometry info for SCSI disks was printed at boot time. If that information
140 is not available, use the information provided in your disk's manual.
141 Please note that the geometry printed at boot time is preferred.
142
143 IMPORTANT NOTE: due to a limitation in the disklabel(8) program, the
144 number of cylinders on the disk will be increased by 1 so that the initial
145 label can be placed on disk for editing. When the disklabel editor appears,
146 make absolutely certain you subtract 1 from the total number of cylinders,
147 and adjust the size of partition 'c' such that:
148
149 size = (sectors per track) * (tracks per cyl) * (total cylinders)
150
151 Note that the disklabel editor will be run twice; once to set the size of
152 partition 'c' and correct the geometry, and again so that you may correctly
153 edit the partition map. This is to work around the afore mentioned
154 limitation in disklabel(8). Apologies offered in advance.
155
156 __scsi_label_1
157
158 # Give the opportunity to review the boot messages.
159 echo -n "Review boot messages now? [y] "
160 getresp "y"
161 case "$resp" in
162 y*|Y*)
163 (echo ""; dmesg; echo "") | more
164 ;;
165
166 *)
167 ;;
168 esac
169
170 echo ""
171 echo -n "Number of bytes per disk sector? [512] "
172 getresp "512"
173 _secsize="$resp"
174
175 resp="" # force one iteration
176 while [ -z "${resp}" ]; do
177 echo -n "Number of cylinders? "
178 getresp ""
179 done
180 _cylinders="$resp"
181 _fudge_cyl=$(expr $_cylinders + 1)
182
183 resp="" # force one iteration
184 while [ -z "${resp}" ]; do
185 echo -n "Number of tracks (heads)? "
186 getresp ""
187 done
188 _tracks_per_cyl="$resp"
189
190 resp="" # force one iteration
191 while [ -z "${resp}" ]; do
192 echo -n "Number of disk sectors (blocks)? "
193 getresp ""
194 done
195 _nsectors="$resp"
196
197 # Calculate some values we need.
198 _sec_per_cyl=$(expr $_nsectors / $_cylinders)
199 _sec_per_track=$(expr $_sec_per_cyl / $_tracks_per_cyl)
200 _new_c_size=$(expr $_sec_per_track \* $_tracks_per_cyl \* $_cylinders)
201
202 # Emit a disktab entry, suitable for getting started.
203 # What we have is a 'c' partition with the total number of
204 # blocks, and an 'a' partition with 1 sector; just large enough
205 # to open. Don't ask.
206 echo "" >> /etc/disktab
207 echo "# Created by install" >> /etc/disktab
208 echo "${_cur_disk_name}:\\" >> /etc/disktab
209 echo -n " :ty=winchester:ns#${_sec_per_track}:" >> /etc/disktab
210 echo "nt#${_tracks_per_cyl}:nc#${_fudge_cyl}:\\" >> /etc/disktab
211 echo " :pa#1:\\" >> /etc/disktab
212 echo " :pc#${_nsectors}:" >> /etc/disktab
213
214 # Ok, here's what we need to do. First of all, we install
215 # this initial label by opening the 'c' partition of the disk
216 # and using the '-r' flag for disklabel(8). However, because
217 # of limitations in disklabel(8), we've had to fudge the number
218 # of cylinders up 1 so that disklabel(8) doesn't complain about
219 # 'c' running past the end of the disk, which can be quite
220 # common even with OEM HP drives! So, we've given ourselves
221 # an 'a' partition, which is the minimum needed to open the disk
222 # so that we can perform the DIOCWDLABEL ioctl. So, once the
223 # initial label is installed, we open the 'a' partition so that
224 # we can fix up the number of cylinders and make the size of
225 # 'c' come out to (ncyl * ntracks_per_cyl * nsec_per_track).
226 # After that's done, we re-open 'c' and let the user actually
227 # edit the partition table. It's horrible, I know. Bleh.
228
229 disklabel -W ${1}
230 if ! disklabel -w -r ${1} ${_cur_disk_name}; then
231 echo ""
232 echo "ERROR: can't bootstrap disklabel!"
233 rval="1"
234 return
235 fi
236
237 echo ""
238 echo "The disklabel editor will now start. During this phase, you"
239 echo "must reset the 'cylinders' value to ${_cylinders}, and adjust"
240 echo "the size of partition 'c' to ${_new_c_size}. Do not modify"
241 echo "the partition map at this time. You will have the opportunity"
242 echo "to do so in a moment."
243 echo ""
244 echo -n "Press <return> to continue. "
245 getresp ""
246
247 disklabel -W ${1}
248 if ! disklabel -e /dev/r${1}a; then
249 echo ""
250 echo "ERROR: can't fixup geometry!"
251 rval="1"
252 return
253 fi
254
255 cat << \__explain_motives_2
256
257 Now that you have corrected the geometry of your disk, you may edit the
258 partition map. Don't forget to fill in the fsize (frag size), bsize
259 (filesystem block size), and cpg (cylinders per group) values. If you
260 are unsure what these should be, use:
261
262 fsize: 1024
263 bsize: 4096
264 cpg: 16
265
266 __explain_motives_2
267 echo -n "Press <return> to continue. "
268 getresp ""
269
270 rval="0"
271 return
272 }
273
274 hp300_init_label_hpib_disk() {
275 # $1 is the disk to label
276
277 # We look though the boot messages attempting to find
278 # the model number for the provided disk.
279 _hpib_disktype=""
280 if dmesg | grep_check_q "${1}: "; then
281 _hpib_disktype=HP$(dmesg | plain_grep "${1}: " | sort -u | \
282 awk '{print $2}')
283 fi
284 if [ -z "${_hpib_disktype}" ]; then
285 echo ""
286 echo "ERROR: $1 doesn't appear to exist?!"
287 rval="1"
288 return
289 fi
290
291 # Peer through /etc/disktab to see if the disk has a "default"
292 # layout. If it doesn't, we have to treat it like a SCSI disk;
293 # i.e. prompt for geometry, and create a default to place
294 # on the disk.
295 if ! grep_check_q "${_hpib_disktype}[:|]" /etc/disktab; then
296 echo ""
297 echo "WARNING: can't find defaults for $1 ($_hpib_disktype)"
298 echo ""
299 hp300_init_label_scsi_disk $1
300 return
301 fi
302
303 # We've found the defaults. Now use them to place an initial
304 # disklabel on the disk.
305 # XXX What kind of ugliness to we have to deal with to get around
306 # XXX stupidity on the part of disklabel semantics?
307 disklabel -W ${1}
308 if ! disklabel -r -w ${1} $_hpib_disktype; then
309 # Error message displayed by disklabel(8)
310 echo ""
311 echo "ERROR: can't install default label!"
312 echo ""
313 echo -n "Try a different method? [y] "
314 getresp "y"
315 case "$resp" in
316 y*|Y*)
317 hp300_init_label_scsi_disk $1
318 return
319 ;;
320
321 *)
322 rval="1"
323 return
324 ;;
325 esac
326 fi
327
328 rval="0"
329 return
330 }
331
332 md_labeldisk() {
333 # $1 is the disk to label
334
335 # Check to see if there is a disklabel present on the device.
336 # If so, we can just edit it. If not, we must first install
337 # a default label.
338 md_checkfordisklabel $1
339 case "$rval" in
340 0)
341 # Go ahead and just edit the disklabel.
342 disklabel -W $1
343 disklabel -e $1
344 ;;
345
346 *)
347 echo -n "No disklabel present, installing a default for type: "
348 case "$1" in
349 rd*)
350 echo "HP-IB"
351 hp300_init_label_hpib_disk $1
352 ;;
353
354 sd*)
355 echo "SCSI"
356 hp300_init_label_scsi_disk $1
357 ;;
358
359 *)
360 # Shouldn't happen, but...
361 echo "unknown?! Giving up."
362 return;
363 ;;
364 esac
365
366 # Check to see if installing the default was
367 # successful. If so, go ahead and pop into the
368 # disklabel editor.
369 if [ "${rval}" != "0" ]; then
370 echo "Sorry, can't label this disk."
371 echo ""
372 return;
373 fi
374
375 # We have some defaults installed. Pop into
376 # the disklabel editor.
377 disklabel -W $1
378 if ! disklabel -e $1; then
379 echo ""
380 echo "ERROR: couldn't set partition map for $1"
381 echo ""
382 fi
383 esac
384 }
385
386 md_prep_disklabel() {
387 # $1 is the root disk
388
389 # Make sure there's a disklabel there. If there isn't, puke after
390 # disklabel prints the error message.
391 md_checkfordisklabel $1
392 case "$resp" in
393 1)
394 cat << \__md_prep_disklabel_1
395
396 FATAL ERROR: There is no disklabel present on the root disk! You must
397 label the disk with SYS_INST before continuing.
398
399 __md_prep_disklabel_1
400 exit
401 ;;
402
403 2)
404 cat << \__md_prep_disklabel_2
405
406 FATAL ERROR: The disklabel on the root disk is corrupted! You must
407 re-label the disk with SYS_INST before continuing.
408
409 __md_prep_disklabel_2
410 exit
411 ;;
412
413 *)
414 ;;
415 esac
416
417 # Give the user the opportinuty to edit the root disklabel.
418 cat << \__md_prep_disklabel_3
419
420 You have already placed a disklabel onto the target root disk.
421 However, due to the limitations of the standalone program used
422 you may want to edit that label to change partition type information.
423 You will be given the opporunity to do that now. Note that you may
424 not change the size or location of any presently open partition.
425
426 __md_prep_disklabel_3
427 echo -n "Do you wish to edit the root disklabel? [y] "
428 getresp "y"
429 case "$resp" in
430 y*|Y*)
431 disklabel -W $1
432 disklabel -e $1
433 ;;
434
435 *)
436 ;;
437 esac
438
439 cat << \__md_prep_disklabel_4
440
441 You will now be given the opportunity to place disklabels on any additional
442 disks on your system.
443 __md_prep_disklabel_4
444
445 _DKDEVS=$(rmel ${ROOTDISK} ${_DKDEVS})
446 resp="not-done" # force at least one iteration
447 while [ "$resp" != "done" ]; do
448 labelmoredisks
449 done
450 }
451
452 md_copy_kernel() {
453 if [ ! -f /mnt/netbsd ]; then
454 echo -n "No kernel set extracted. Copying miniroot kernel..."
455 cp -p /netbsd /mnt/netbsd
456 echo "done."
457
458 cat << __md_copy_kernel_1
459
460 The INSTALL kernel from the miniroot has been copied to your root disk.
461 It has minimal facilities enabled. The first thing you should do after
462 installation is install an appropriate kernel for your machine (such as
463 the GENERIC kernel).
464
465 __md_copy_kernel_1
466 echo -n "Press <return> to continue. "
467 getresp ""
468 fi
469 }
470
471 # Note, while they might not seem machine-dependent, the
472 # welcome banner and the punt message may contain information
473 # and/or instructions specific to the type of machine.
474
475 md_welcome_banner() {
476 (
477 echo ""
478 echo "Welcome to the NetBSD/${MACHINE} ${RELEASE} installation program."
479 cat << \__welcome_banner_1
480
481 This program is designed to help you install NetBSD on your system in a
482 simple and rational way. You'll be asked several questions, and it would
483 probably be useful to have your disk's hardware manual, the installation
484 notes, and a calculator handy.
485
486 In particular, you will need to know some reasonably detailed
487 information about your disk's geometry. This program can determine
488 some limited information about certain specific types of HP-IB disks.
489 If you have SCSI disks, however, prior knowledge of disk geometry
490 is absolutely essential. The kernel will attempt to display geometry
491 information for SCSI disks during boot, if possible. If you did not
492 make it note of it before, you may wish to reboot and jot down your
493 disk's geometry before proceeding.
494
495 As with anything which modifies your hard disk's contents, this
496 program can cause SIGNIFICANT data loss, and you are advised
497 to make sure your hard drive is backed up before beginning the
498 installation process.
499
500 Default answers are displyed in brackets after the questions.
501 You can hit Control-C at any time to quit, but if you do so at a
502 prompt, you may have to hit return. Also, quitting in the middle of
503 installation may leave your system in an inconsistent state.
504
505 __welcome_banner_1
506 ) | more
507 }
508
509 md_not_going_to_install() {
510 cat << \__not_going_to_install_1
511
512 OK, then. Enter 'halt' at the prompt to halt the machine. Once the
513 machine has halted, power-cycle the system to load new boot code.
514
515 __not_going_to_install_1
516 }
517
518 md_congrats() {
519 cat << \__congratulations_1
520
521 CONGRATULATIONS! You have successfully installed NetBSD! To boot the
522 installed system, enter halt at the command prompt. Once the system has
523 halted, power-cycle the machine in order to load new boot code. Make sure
524 you boot from the root disk.
525
526 __congratulations_1
527 }
528
529 md_native_fstype() {
530 # Nothing to do.
531 }
532
533 md_native_fsopts() {
534 # Nothing to do.
535 }
536