1#	$OpenBSD: install.md,v 1.50 2024/05/12 19:47:14 kn Exp $
2#
3#
4# Copyright (c) 1996 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# This code is derived from software contributed to The NetBSD Foundation
8# by Jason R. Thorpe.
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions
12# are met:
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18#
19# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29# POSSIBILITY OF SUCH DAMAGE.
30#
31#
32# machine dependent section of installation/upgrade script.
33#
34
35MDBOOTSR=y
36NCPU=$(sysctl -n hw.ncpufound)
37COMPATIBLE=$(sysctl -n machdep.compatible)
38MOUNT_ARGS_msdos="-o-l"
39KEEP_EFI_SYS=false
40
41md_installboot() {
42	local _disk=$1 _reason=$2 _rerun=false _chunks _bootdisk _mdec _plat
43
44	case ${COMPATIBLE} in
45	apple,*)		_plat=apple
46				[[ $_reason == apple-boot ]] && _rerun=true;;
47	raspberrypi,*)		_plat=rpi;;
48	esac
49
50	if ! installboot -r /mnt $_disk; then
51		echo "\nFailed to install bootblocks."
52		echo "You will not be able to boot OpenBSD from $_disk."
53		exit
54	fi
55
56	$_rerun && return
57
58	# Apply some final tweaks on selected platforms
59	_mdec=/usr/mdec/$_plat
60
61	case $_plat in
62	apple)
63		(cd /etc/firmware; for _dir in apple{,-bwfm}; do
64			[[ -d $_dir ]] && pax -rw $_dir /mnt/etc/firmware
65		done)
66		;;
67	rpi)
68		_chunks=$(get_softraid_chunks)
69		for _bootdisk in ${_chunks:-$_disk}; do
70			mount ${MOUNT_ARGS_msdos} /dev/${_bootdisk}i /mnt/mnt
71			cp $_mdec/{bootcode.bin,start*.elf,fixup*.dat,*.dtb} /mnt/mnt/
72			cp $_mdec/u-boot.bin /mnt/mnt/
73			mkdir -p /mnt/mnt/overlays
74			cp $_mdec/disable-bt.dtbo /mnt/mnt/overlays
75			if [[ ! -f /mnt/mnt/config.txt ]]; then
76				cat > /mnt/mnt/config.txt<<-__EOT
77					arm_64bit=1
78					enable_uart=1
79					dtoverlay=disable-bt
80					kernel=u-boot.bin
81				__EOT
82			fi
83		done
84		umount /mnt/mnt
85		;;
86	esac
87}
88
89md_fw() {
90	md_installboot "$@"
91}
92
93md_prep_fdisk() {
94	local _disk=$1 _d _type=MBR
95
96	local bootparttype="C"
97	local bootsectorstart="32768"
98	local bootsectorsize="32768"
99	local bootfstype="msdos"
100
101	case ${COMPATIBLE} in
102	openbsd,acpi)		bootsectorsize=532480;;
103	esac
104
105	while :; do
106		_d=whole
107		if disk_has $_disk gpt; then
108			_type=GPT
109			fdisk $_disk
110		elif disk_has $_disk mbr; then
111			fdisk $_disk
112		else
113			echo "MBR has invalid signature; not showing it."
114		fi
115		ask "Use (W)hole disk or (E)dit the ${_type}?" $_d
116		case $resp in
117		[wW]*)
118			echo -n "Creating a ${bootfstype} partition and an OpenBSD partition for rest of $_disk..."
119			if disk_has $_disk gpt apfsisc; then
120				# On Apple hardware, the existing EFI Sys
121				# partition contains boot firmware and MUST NOT
122				# be recreated.
123				KEEP_EFI_SYS=true
124
125				# Is this a boot disk?
126				if [[ $_disk == $ROOTDISK ]]; then
127					fdisk -Ay -b "${bootsectorsize}" ${_disk} >/dev/null
128				else
129					fdisk -Ay ${_disk} >/dev/null
130				fi
131			elif disk_has $_disk gpt; then
132				# Is this a boot disk?
133				if [[ $_disk == $ROOTDISK ]]; then
134					fdisk -gy -b "${bootsectorsize}" ${_disk} >/dev/null
135
136					# With root on softraid,
137					# 'installboot -p' on the root disk
138					# nukes the EFI Sys partition on
139					# the chunks.
140					$KEEP_EFI_SYS || installboot -p $_disk
141				else
142					fdisk -gy ${_disk} >/dev/null
143				fi
144			else
145				fdisk -iy -b "${bootsectorsize}@${bootsectorstart}:${bootparttype}" ${_disk} >/dev/null
146
147				# With root on softraid, 'installboot -p' on
148				# the root disk nukes the EFI Sys partition on
149				# the chunks.
150				$KEEP_EFI_SYS || installboot -p $_disk
151			fi
152			echo "done."
153			return ;;
154		[eE]*)
155			if disk_has $_disk gpt; then
156				# Manually configure the GPT.
157				cat <<__EOT
158
159You will now create two GPT partitions. The first must have an id
160of 'EF' and be large enough to contain the OpenBSD boot programs,
161at least 32768 blocks. The second must have an id of 'A6' and will
162contain your OpenBSD data. Neither may overlap other partitions.
163Inside the fdisk command, the 'manual' command describes the fdisk
164commands in detail.
165
166$(fdisk $_disk)
167__EOT
168				fdisk -e $_disk
169
170				if ! disk_has $_disk gpt openbsd; then
171					echo -n "No OpenBSD partition in GPT,"
172				elif ! disk_has $_disk gpt efisys; then
173					echo -n "No EFI Sys partition in GPT,"
174				else
175					return
176				fi
177			else
178				# Manually configure the MBR.
179				cat <<__EOT
180
181You will now create one MBR partition to contain your OpenBSD data
182and one MBR partition on which the OpenBSD boot program is located.
183Neither partition will overlap any other partition.
184
185The OpenBSD MBR partition will have an id of 'A6' and the boot MBR
186partition will have an id of '${bootparttype}' (${bootfstype}).
187The boot partition will be at least 16MB and be the first 'MSDOS'
188partition on the disk.
189
190$(fdisk ${_disk})
191__EOT
192				fdisk -e ${_disk}
193				disk_has $_disk mbr openbsd && return
194				echo -n "No OpenBSD partition in MBR,"
195			fi
196			echo " try again." ;;
197		esac
198	done
199}
200
201md_prep_disklabel() {
202	local _disk=$1 _f=/tmp/i/fstab.$1
203
204	md_prep_fdisk $_disk
205
206	disklabel_autolayout $_disk $_f || return
207	[[ -s $_f ]] && return
208
209	# Edit disklabel manually.
210	# Abandon all hope, ye who enter here.
211	disklabel -F $_f -E $_disk
212}
213
214md_congrats() {
215}
216
217md_consoleinfo() {
218	local _fw _fw2
219
220	DEFCONS=y
221	case $(scan_dmesg '/^\([^ ]*\).*: console.*std.*$/s//\1/p') in
222	wsdisplay0)
223		CTTY=ttyC0;;
224	*)
225		CTTY=console;;
226	esac
227	case $CSPEED in
228	9600|19200|38400|57600|115200|1500000)
229		;;
230	*)
231		CSPEED=115200;;
232	esac
233
234	case ${COMPATIBLE} in
235	apple,*)
236		_fw=$(dmesgtail | sed -n '\!^bwfm0: failed!{s!^.*/\(.*\),.*$!\1!p;q;}')
237		_fw2=${COMPATIBLE##*apple,}
238		make_dev sd0
239		if mount -o ro /dev/sd0l /mnt2 2>/dev/null; then
240			rm -rf /usr/mdec/rpi /etc/firmware/apple
241			rm -rf /etc/firmware/brcm /etc/firmware/apple-bwfm
242			if [[ -s /mnt2/vendorfw/firmware.tar ]]; then
243				[[ -n $_fw ]] && tar -x -C /etc/firmware \
244				    -f /mnt2/vendorfw/firmware.tar "*$_fw*" 2>/dev/null
245				[[ -n $_fw2 ]] && tar -x -C /etc/firmware \
246				    -f /mnt2/vendorfw/firmware.tar "*$_fw2*" 2>/dev/null
247				mv /etc/firmware/brcm /etc/firmware/apple-bwfm 2>/dev/null
248			fi
249			umount /mnt2
250		fi
251	esac
252}
253