build - Add the 'efisetup' script
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 23 Mar 2017 02:06:57 +0000 (19:06 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 23 Mar 2017 02:06:57 +0000 (19:06 -0700)
* Add the 'efisetup' script to /usr/sbin.  This script is capable of
  creating a pristine UEFI bootable DragonFlyBSD installation on the
  target drive.  The target drive will be wiped.

  Note that this script does only a basic installation... literally once
  it sets up the partitions it just does an installworld, make distribution,
  and installkernel, and then some minor adjustments to create the initial
  /etc/rc.conf, /etc/fstab, and /boot/loader.conf.

* Requires that you previously did a buildworld and buildkernel
  before running the script.

usr.sbin/Makefile
usr.sbin/efisetup/Makefile [new file with mode: 0644]
usr.sbin/efisetup/efisetup.8 [new file with mode: 0644]
usr.sbin/efisetup/efisetup.sh [new file with mode: 0755]

index 8169e1e..4ef5781 100644 (file)
@@ -33,6 +33,7 @@ SUBDIR= 802_11 \
        dntpd \
        edquota \
        efivar \
+       efisetup \
        faithd \
        fdcontrol \
        fdformat \
diff --git a/usr.sbin/efisetup/Makefile b/usr.sbin/efisetup/Makefile
new file mode 100644 (file)
index 0000000..0ba863a
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+SCRIPTS=efisetup.sh
+SCRIPTSNAME=efisetup
+MAN= efisetup.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/efisetup/efisetup.8 b/usr.sbin/efisetup/efisetup.8
new file mode 100644 (file)
index 0000000..1c2f43a
--- /dev/null
@@ -0,0 +1,93 @@
+.\" Copyright (c) 2017 Matthew Dillon, All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd March 22, 2017
+.Dt EFISETUP 8
+.Os
+.Sh NAME
+.Nm efisetup
+.Nd Create a complete UEFI install on a fresh drive
+.Sh SYNOPSIS
+.Nm
+.Op Fl s Ar swapsize{m,g}
+.Op Fl S Ar serialno
+.Ar drive
+.Sh DESCRIPTION
+This program will create a fresh UEFI install of DragonFly on a drive.
+The drive will be completely reformatted and any prior contents will be
+lost!
+.Pp
+.Bl -tag -width 20m
+.It Fl s Ar swapsize{m,g}
+Specify the size of the swap partition, default is "8g".
+.It Fl S Ar serialno
+Specify the serial number of the device as it would appear
+under /dev/serno/*.  In most cases this is simply the reported
+serial number, however note that the
+.Xr nvme 4
+driver will tack on a namespace id to the reported serial number,
+typically "-1".
+Only specify the serial number, do not specify a path prefix.
+If you use this option the script will install path references in fstab
+and so forth using the serno/ path.  If you do not use this option,
+the drive name will be used instead.
+We recommend using this option.
+.It Ar drive
+Specify the drive, for example "nvme0".  You may omit the "/dev/" prefix
+if you wish.
+The raw drive should be specified, do not specify a serno/ path here.
+.El
+.Sh USAGE
+.Nm
+expects you to have completed a buildworld and buildkernel
+sequence before running the program,
+see
+.Xr build 7
+for more information on how to build a fresh system.
+.Pp
+.Nm
+will create a fresh GPT slice table with two slices,
+install the required EFI boot files on slice 0, and
+install a DragonFly 64-bit disklabel on slice 1.
+The program will then proceed to create partitions 'a', 'b', and 'c'
+in the disklabel, mount them, and install the world and kernel.
+.Pp
+After the world and kernel are installed,
+.Nm
+will make adjustments to the target /boot/loader.conf, /etc/fstab,
+and /etc/rc.conf with the appropriate disk paths, then unmount.
+.Pp
+After completion of the operation you should be able to boot from the
+drive and then finish up your adjustments to /etc/rc.conf to get
+the network up and so forth.
+This script does only a very basic installation.
+For a more substantial initial installation you should boot from a
+DragonFlyBSD install image and select an EFI installation.
+.Sh SEE ALSO
+.Xr efivar 3
+.Xr efivar 8
+.Pp
+The
+.Nm
+utility appeared in
+.Dx 4.8 .
diff --git a/usr.sbin/efisetup/efisetup.sh b/usr.sbin/efisetup/efisetup.sh
new file mode 100755 (executable)
index 0000000..0723e6c
--- /dev/null
@@ -0,0 +1,254 @@
+#!/bin/sh
+#
+# efisetup [-s swap] [-S serialno] <rawdrive>
+#
+# Copyright (c) 2017 Matthew Dillon. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#       Email: Matthew Dillon <dillon@backplane.com>
+#
+
+help() {
+       echo "WARNING! EFISETUP WILL WIPE THE TARGET DRIVE!"
+       echo ""
+       echo "efisetup [-s <swap>{m,g}] [-S serialno] <rawdrive>"
+       echo "    -s <swap{m,g}     Defaults to 8g"
+       echo "    -S serialno       Used to adjust loader.conf, fstab, etc"
+       echo "                      If not specified, drive spec is used"
+       exit 1
+}
+
+fail() {
+       echo "failed on $*"
+       exit 1
+}
+
+var=
+fopt=0
+swap=8g
+serno=
+
+for _switch ; do
+       case $_switch in
+       -f)
+               fopt=1
+               ;;
+       -h)
+               help
+               ;;
+       -s)
+               var=swap
+               ;;
+       -S)
+               var=serno
+               ;;
+       -*)
+               echo "Bad option: $_switch"
+               exit 1
+               ;;
+       *)
+               if [ "x$var" != "x" ]; then
+                       eval ${var}=$_switch
+                       var=
+               else
+                       if [ "x$drive" != "x" ]; then
+                           echo "Specify only one target drive"
+                           echo "WARNING! efisetup will wipe the target drive"
+                           exit 1
+                       fi
+                       drive=$_switch
+               fi
+               ;;
+       esac
+done
+
+if [ "x$drive" = "x" ]; then
+       help
+fi
+
+if [ ! -c $drive ]; then
+       if [ ! -c /dev/$drive ]; then
+           echo "efisetup: $drive is not a char-special device"
+           exit 1
+       fi
+       drive="/dev/$drive"
+fi
+
+if [ $fopt == 0 ]; then
+       echo -n "This will wipe $drive, are you sure? "
+       read ask
+       case $ask in
+       y)
+               ;;
+       yes)
+               ;;
+       Y)
+               ;;
+       YES)
+               ;;
+       *)
+               echo "Aborting command"
+               exit 1
+               ;;
+       esac
+fi
+
+# Ok, do all the work.  Start by creating a fresh EFI
+# partition table
+#
+gpt destroy $drive > /dev/null 2>&1
+dd if=/dev/zero of=$drive bs=32k count=64 > /dev/null 2>&1
+gpt create $drive
+if [ $? != 0 ]; then
+    echo "gpt create failed"
+    exit 1
+fi
+
+# GPT partitioning
+#
+#
+gpt add -i 0 -s 524288 -t "EFI System" ${drive}
+sects=`gpt show /dev/nvme0 | sort -n +1 | tail -1 | awk '{ print $2; }'`
+sects=$(($sects / 2048 * 2048))
+gpt add -i 1 -s $sects -t "DragonFly Label64" ${drive}
+sleep 0.5
+
+mkdir -p /efimnt
+if [ $? != 0 ]; then fail "mkdir -p /efimnt"; fi
+
+# GPT s0 - EFI boot setup
+#
+newfs_msdos ${drive}s0
+mount_msdos ${drive}s0 /efimnt
+mkdir -p /efimnt/efi/boot
+cp /boot/boot1.efi /efimnt/efi/boot/bootx64.efi
+umount /efimnt
+
+# GPT s1 - DragonFlyBSD disklabel setup
+#
+disklabel -r -w ${drive}s1 auto
+if [ $? != 0 ]; then fail "initial disklabel"; fi
+
+rm -f /tmp/label.$$
+disklabel ${drive}s1 > /tmp/label.$$
+cat >> /tmp/label.$$ << EOF
+a: 1g  0       4.2BSD
+b: ${swap}     *       swap
+d: *   *       HAMMER
+EOF
+
+disklabel -R ${drive}s1 /tmp/label.$$
+if [ $? != 0 ]; then fail "disklabel setup"; fi
+
+#rm -f /tmp/label.$$
+sleep 0.5
+newfs ${drive}s1a
+if [ $? != 0 ]; then fail "newfs ${drive}s1a"; fi
+newfs_hammer -L ROOT ${drive}s1d
+if [ $? != 0 ]; then fail "newfs_hammer ${drive}s1d"; fi
+
+# DragonFly mounts, setup for installation
+#
+echo "Mounting DragonFly for copying"
+mount ${drive}s1d /efimnt
+if [ $? != 0 ]; then fail "mount ${drive}s1d"; fi
+mkdir -p /efimnt/boot
+mount ${drive}s1a /efimnt/boot
+if [ $? != 0 ]; then fail "mount ${drive}s1a"; fi
+
+# INSTALLWORLD SEQUENCE
+#
+echo "Mounted onto /efimnt and /efimnt/boot"
+echo "Type yes to continue with install"
+echo "You must have a built the world and kernel already."
+echo "^C here if you did not."
+
+echo -n "Continue? "
+read ask
+case $ask in
+y)
+       ;;
+yes)
+       ;;
+Y)
+       ;;
+YES)
+       ;;
+*)
+       echo "Stopping here.  /efimnt and /efimnt/boot remain mounted"
+       exit 1
+       ;;
+esac
+
+# Setup initial installworld sequence
+#
+cd /usr/src
+make installworld DESTDIR=/efimnt
+if [ $? != 0 ]; then fail "make installworld"; fi
+make installkernel DESTDIR=/efimnt
+if [ $? != 0 ]; then fail "make installkernel"; fi
+cd /usr/src/etc
+make distribution DESTDIR=/efimnt
+if [ $? != 0 ]; then fail "make distribution"; fi
+
+# Calculate base drive path given serial
+# number (or no serial number).
+#
+# serno - full drive path or serial number, sans slice & partition,
+#        including the /dev/, which we use as an intermediate
+#        variable.
+#
+# mfrom - partial drive path as above except without the /dev/,
+#        allowed in mountfrom and fstab.
+#
+if [ "x$serno" == "x" ]; then
+    serno=${drive}
+    mfrom="`echo ${drive} | sed -e 's#/dev/##g'`"
+else
+    serno="serno/${serno}."
+    mfrom="serno/${serno}."
+fi
+
+echo "Fixingup files for a ${serno}s1d root"
+
+# Add mountfrom to /efimnt/boot/loader.conf
+#
+echo "vfs.root.mountfrom=\"hammer:${mfrom}s1d\"" >> /efimnt/boot/loader.conf
+
+# Add dumpdev to /etc/rc.conf
+#
+echo "dumpdev=\"/dev/${mfrom}s1b\"" >> /efimnt/etc/rc.conf
+
+# Create a fresh /etc/fstab
+#
+printf "%-20s %-15s hammer\trw\t1 1\n" "${mfrom}s1d" "/" \
+                       >> /efimnt/etc/fstab
+printf "%-20s %-15s ufs\trw\t1 1\n" "${mfrom}s1a" "/boot" \
+                       >> /efimnt/etc/fstab
+printf "%-20s %-15s swap\tsw\t0 0\n" "${mfrom}s1b" "none" \
+                       >> /efimnt/etc/fstab
+printf "%-20s %-15s procfs\trw\t4 4\n" "proc" "/proc" \
+                       >> /efimnt/etc/fstab
+
+echo "Unmounting /efimnt/boot and /efimnt"
+umount /efimnt/boot
+umount /efimnt