Merge remote-tracking branch 'origin/vendor/BINUTILS234'
[dragonfly.git] / usr.sbin / efisetup / efisetup.sh
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
30 help() {
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
40 fail() {
41         echo "failed on $*"
42         exit 1
43 }
44
45 var=
46 fopt=0
47 swap=8g
48 serno=
49
50 for _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
82 done
83
84 if [ "x$drive" = "x" ]; then
85         help
86 fi
87
88 if [ ! -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"
94 fi
95
96 if [ $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
113 fi
114
115 # Ok, do all the work.  Start by creating a fresh EFI
116 # partition table
117 #
118 gpt destroy $drive > /dev/null 2>&1
119 dd if=/dev/zero of=$drive bs=32k count=64 > /dev/null 2>&1
120 gpt create $drive
121 if [ $? != 0 ]; then
122     echo "gpt create failed"
123     exit 1
124 fi
125
126 # GPT partitioning
127 #
128 #
129 gpt add -i 0 -s 524288 -t "EFI System" ${drive}
130 sects=`gpt show ${drive} | sort -n +1 | tail -1 | awk '{ print $2; }'`
131 sects=$(($sects / 2048 * 2048))
132 gpt add -i 1 -s $sects -t "DragonFly Label64" ${drive}
133 sleep 0.5
134
135 mkdir -p /efimnt
136 if [ $? != 0 ]; then fail "mkdir -p /efimnt"; fi
137
138 # GPT s0 - EFI boot setup
139 #
140 newfs_msdos ${drive}s0
141 mount_msdos ${drive}s0 /efimnt
142 mkdir -p /efimnt/efi/boot
143 cp /boot/boot1.efi /efimnt/efi/boot/bootx64.efi
144 umount /efimnt
145
146 # GPT s1 - DragonFlyBSD disklabel setup
147 #
148 disklabel -r -w ${drive}s1 auto
149 if [ $? != 0 ]; then fail "initial disklabel"; fi
150
151 rm -f /tmp/label.$$
152 disklabel ${drive}s1 > /tmp/label.$$
153 cat >> /tmp/label.$$ << EOF
154 a: 1g   0       4.2BSD
155 b: ${swap}      *       swap
156 d: *    *       HAMMER2
157 EOF
158
159 disklabel -R ${drive}s1 /tmp/label.$$
160 if [ $? != 0 ]; then fail "disklabel setup"; fi
161
162 #rm -f /tmp/label.$$
163 sleep 0.5
164 newfs ${drive}s1a
165 if [ $? != 0 ]; then fail "newfs ${drive}s1a"; fi
166 newfs_hammer2 ${drive}s1d
167 if [ $? != 0 ]; then fail "newfs_hammer2 ${drive}s1d"; fi
168
169 # DragonFly mounts, setup for installation
170 #
171 echo "Mounting DragonFly for copying"
172 mount ${drive}s1d /efimnt
173 if [ $? != 0 ]; then fail "mount ${drive}s1d"; fi
174 mkdir -p /efimnt/boot
175 mount ${drive}s1a /efimnt/boot
176 if [ $? != 0 ]; then fail "mount ${drive}s1a"; fi
177
178 # INSTALLWORLD SEQUENCE
179 #
180 echo "Mounted onto /efimnt and /efimnt/boot"
181 echo "Type yes to continue with install"
182 echo "You must have a built the world and kernel already."
183 echo "^C here if you did not."
184
185 echo -n "Continue? "
186 read ask
187 case $ask in
188 y)
189         ;;
190 yes)
191         ;;
192 Y)
193         ;;
194 YES)
195         ;;
196 *)
197         echo "Stopping here.  /efimnt and /efimnt/boot remain mounted"
198         exit 1
199         ;;
200 esac
201
202 # Setup initial installworld sequence
203 #
204 cd /usr/src
205 make installworld DESTDIR=/efimnt
206 if [ $? != 0 ]; then fail "make installworld"; fi
207 make installkernel DESTDIR=/efimnt
208 if [ $? != 0 ]; then fail "make installkernel"; fi
209 cd /usr/src/etc
210 make distribution DESTDIR=/efimnt
211 if [ $? != 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 #
223 if [ "x$serno" == "x" ]; then
224     serno=${drive}
225     mfrom="`echo ${drive} | sed -e 's#/dev/##g'`"
226 else
227     serno="serno/${serno}."
228     mfrom="serno/${serno}."
229 fi
230
231 echo "Fixingup files for a ${serno}s1d root"
232
233 # Add mountfrom to /efimnt/boot/loader.conf
234 #
235 echo "vfs.root.mountfrom=\"hammer2:${mfrom}s1d\"" >> /efimnt/boot/loader.conf
236
237 # Add dumpdev to /etc/rc.conf
238 #
239 echo "dumpdev=\"/dev/${mfrom}s1b\"" >> /efimnt/etc/rc.conf
240
241 # Create a fresh /etc/fstab
242 #
243 printf "%-20s %-15s hammer2\trw\t1 1\n" "${mfrom}s1d" "/" \
244                         >> /efimnt/etc/fstab
245 printf "%-20s %-15s ufs\trw\t1 1\n" "${mfrom}s1a" "/boot" \
246                         >> /efimnt/etc/fstab
247 printf "%-20s %-15s swap\tsw\t0 0\n" "${mfrom}s1b" "none" \
248                         >> /efimnt/etc/fstab
249 printf "%-20s %-15s procfs\trw\t4 4\n" "proc" "/proc" \
250                         >> /efimnt/etc/fstab
251
252 echo "Unmounting /efimnt/boot and /efimnt"
253 umount /efimnt/boot
254 umount /efimnt