xref: /dragonfly/usr.sbin/efisetup/efisetup.sh (revision 52509364)
1#!/bin/sh
2#
3# efisetup [-s swap] [-S serialno] <rawdrive>
4#
5# Copyright (c) 2017 Matthew Dillon. All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27#       Email: Matthew Dillon <dillon@backplane.com>
28#
29
30help() {
31	echo "WARNING! EFISETUP WILL WIPE THE TARGET DRIVE!"
32	echo ""
33	echo "efisetup [-s <swap>{m,g}] [-S serialno] <rawdrive>"
34	echo "    -s <swap{m,g}     Defaults to 8g"
35	echo "    -S serialno       Used to adjust loader.conf, fstab, etc"
36	echo "                      If not specified, drive spec is used"
37	exit 1
38}
39
40fail() {
41	echo "failed on $*"
42	exit 1
43}
44
45var=
46fopt=0
47swap=8g
48serno=
49
50for _switch ; do
51	case $_switch in
52	-f)
53		fopt=1
54		;;
55	-h)
56		help
57		;;
58	-s)
59		var=swap
60		;;
61	-S)
62		var=serno
63		;;
64	-*)
65		echo "Bad option: $_switch"
66		exit 1
67		;;
68	*)
69		if [ "x$var" != "x" ]; then
70			eval ${var}=$_switch
71			var=
72		else
73			if [ "x$drive" != "x" ]; then
74			    echo "Specify only one target drive"
75			    echo "WARNING! efisetup will wipe the target drive"
76			    exit 1
77			fi
78			drive=$_switch
79		fi
80		;;
81	esac
82done
83
84if [ "x$drive" = "x" ]; then
85	help
86fi
87
88if [ ! -c $drive ]; then
89	if [ ! -c /dev/$drive ]; then
90	    echo "efisetup: $drive is not a char-special device"
91	    exit 1
92	fi
93	drive="/dev/$drive"
94fi
95
96if [ $fopt == 0 ]; then
97	echo -n "This will wipe $drive, are you sure? "
98	read ask
99	case $ask in
100	y)
101		;;
102	yes)
103		;;
104	Y)
105		;;
106	YES)
107		;;
108	*)
109		echo "Aborting command"
110		exit 1
111		;;
112	esac
113fi
114
115# Ok, do all the work.  Start by creating a fresh EFI
116# partition table
117#
118gpt destroy $drive > /dev/null 2>&1
119dd if=/dev/zero of=$drive bs=32k count=64 > /dev/null 2>&1
120gpt create $drive
121if [ $? != 0 ]; then
122    echo "gpt create failed"
123    exit 1
124fi
125
126# GPT partitioning
127#
128#
129gpt add -i 0 -s 524288 -t "EFI System" ${drive}
130sects=`gpt show /dev/nvme0 | sort -n +1 | tail -1 | awk '{ print $2; }'`
131sects=$(($sects / 2048 * 2048))
132gpt add -i 1 -s $sects -t "DragonFly Label64" ${drive}
133sleep 0.5
134
135mkdir -p /efimnt
136if [ $? != 0 ]; then fail "mkdir -p /efimnt"; fi
137
138# GPT s0 - EFI boot setup
139#
140newfs_msdos ${drive}s0
141mount_msdos ${drive}s0 /efimnt
142mkdir -p /efimnt/efi/boot
143cp /boot/boot1.efi /efimnt/efi/boot/bootx64.efi
144umount /efimnt
145
146# GPT s1 - DragonFlyBSD disklabel setup
147#
148disklabel -r -w ${drive}s1 auto
149if [ $? != 0 ]; then fail "initial disklabel"; fi
150
151rm -f /tmp/label.$$
152disklabel ${drive}s1 > /tmp/label.$$
153cat >> /tmp/label.$$ << EOF
154a: 1g	0	4.2BSD
155b: ${swap}	*	swap
156d: *	*	HAMMER
157EOF
158
159disklabel -R ${drive}s1 /tmp/label.$$
160if [ $? != 0 ]; then fail "disklabel setup"; fi
161
162#rm -f /tmp/label.$$
163sleep 0.5
164newfs ${drive}s1a
165if [ $? != 0 ]; then fail "newfs ${drive}s1a"; fi
166newfs_hammer -L ROOT ${drive}s1d
167if [ $? != 0 ]; then fail "newfs_hammer ${drive}s1d"; fi
168
169# DragonFly mounts, setup for installation
170#
171echo "Mounting DragonFly for copying"
172mount ${drive}s1d /efimnt
173if [ $? != 0 ]; then fail "mount ${drive}s1d"; fi
174mkdir -p /efimnt/boot
175mount ${drive}s1a /efimnt/boot
176if [ $? != 0 ]; then fail "mount ${drive}s1a"; fi
177
178# INSTALLWORLD SEQUENCE
179#
180echo "Mounted onto /efimnt and /efimnt/boot"
181echo "Type yes to continue with install"
182echo "You must have a built the world and kernel already."
183echo "^C here if you did not."
184
185echo -n "Continue? "
186read ask
187case $ask in
188y)
189	;;
190yes)
191	;;
192Y)
193	;;
194YES)
195	;;
196*)
197	echo "Stopping here.  /efimnt and /efimnt/boot remain mounted"
198	exit 1
199	;;
200esac
201
202# Setup initial installworld sequence
203#
204cd /usr/src
205make installworld DESTDIR=/efimnt
206if [ $? != 0 ]; then fail "make installworld"; fi
207make installkernel DESTDIR=/efimnt
208if [ $? != 0 ]; then fail "make installkernel"; fi
209cd /usr/src/etc
210make distribution DESTDIR=/efimnt
211if [ $? != 0 ]; then fail "make distribution"; fi
212
213# Calculate base drive path given serial
214# number (or no serial number).
215#
216# serno - full drive path or serial number, sans slice & partition,
217#	  including the /dev/, which we use as an intermediate
218#	  variable.
219#
220# mfrom - partial drive path as above except without the /dev/,
221#	  allowed in mountfrom and fstab.
222#
223if [ "x$serno" == "x" ]; then
224    serno=${drive}
225    mfrom="`echo ${drive} | sed -e 's#/dev/##g'`"
226else
227    serno="serno/${serno}."
228    mfrom="serno/${serno}."
229fi
230
231echo "Fixingup files for a ${serno}s1d root"
232
233# Add mountfrom to /efimnt/boot/loader.conf
234#
235echo "vfs.root.mountfrom=\"hammer:${mfrom}s1d\"" >> /efimnt/boot/loader.conf
236
237# Add dumpdev to /etc/rc.conf
238#
239echo "dumpdev=\"/dev/${mfrom}s1b\"" >> /efimnt/etc/rc.conf
240
241# Create a fresh /etc/fstab
242#
243printf "%-20s %-15s hammer\trw\t1 1\n" "${mfrom}s1d" "/" \
244			>> /efimnt/etc/fstab
245printf "%-20s %-15s ufs\trw\t1 1\n" "${mfrom}s1a" "/boot" \
246			>> /efimnt/etc/fstab
247printf "%-20s %-15s swap\tsw\t0 0\n" "${mfrom}s1b" "none" \
248			>> /efimnt/etc/fstab
249printf "%-20s %-15s procfs\trw\t4 4\n" "proc" "/proc" \
250			>> /efimnt/etc/fstab
251
252echo "Unmounting /efimnt/boot and /efimnt"
253umount /efimnt/boot
254umount /efimnt
255