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