Adds UEFI support to boot loader installation
--- setup
+++ setup
@@ -128,6 +128,21 @@
     fi
 }
 
+# getkernelversion()
+# outputs the kernel version
+#
+# parameters: none
+# outputs:    kernel version on success
+#             nothing on failure
+# returns:    0 on success
+#             1 on failure
+getkernelversion()
+{
+    local kernver=$(ls $DESTDIR/boot/kernel-genkernel-* |sed -e "s|kernel-genkernel||g" -e "s|$DESTDIR/boot/||") \
+        || return 1
+    echo "${kernver}"
+}
+
 findpartitions() {
     workdir="$PWD"
     for devpath in $(finddisks); do
@@ -727,6 +742,164 @@
     fi
 }
 
+# douefigrub()
+# writes kernel to UEFI as new boot option
+# parameters:
+#     kernelpath: path to kernel, relative to partition root
+#     initrdpath: path to initrd
+#     bootparams: other boot params for kernel
+# returns: 1 on failure
+douefigrub() {
+    # check if grub2 is installed
+    grub2-mkimage -? 2>/dev/null 1>&2
+    if [ $? -ne 0 ]; then
+        DIALOG --msgbox "Error: Couldn't find grub2-mkimage.  Is GRUB-2 installed?" 0 0
+        return 1
+    fi
+    local kernelpath="${1}"
+    local initrdpath="${2}"
+    local bootparams="${3}"
+    # uefipart: uefi partition, ex. /dev/sda1
+    DIALOG --menu "Select the partition to use as UEFI boot partition" 21 50 13 NONE - $PARTS 2>$ANSWER || return 1
+    local uefipart=$(cat $ANSWER)
+    PARTS="$(echo $PARTS | sed -e "s#${uefipart}\ _##g")"
+    [ "$uefipart" = "NONE" ] && return 1
+    # grubpart: grub partition, ex. (hd0,2)
+    DIALOG --inputbox "Verify your GRUB device path" 8 65 "(hd0,2)" 2>$ANSWER || return 1
+    local grubpart=$(cat $ANSWER)
+    # uefimount: uefi partition mount point, ex. /boot
+    local uefimount="$(mount | grep "^${uefipart} " | cut -d' ' -f 3)"
+    # mount if not mounted
+    if [ "${uefimount}" = "" ]; then
+        mkdir -p /tmp/efibootpart || return 1
+        mount "${uefipart}" /tmp/efibootpart || return 1
+        uefimount=/tmp/efibootpart
+    fi
+    # safety check for /EFI/BOOT/BOOTX64.EFI (case insensitive for fat)
+    local findefi="$(find "${uefimount}" -iwholename "${uefimount}/efi/boot/bootx64.efi")"
+    if [ "${findefi}" != "" ]; then
+        DIALOG --msgbox "Error: ${findefi} exists, refusing to overwrite!" 0 0
+        return 1
+    fi
+    # safety check for /boot/grub2 (case insensitive for fat)
+    local findgrub2="$(find "${uefimount}" -iwholename "${uefimount}/boot/grub2")"
+    if [ "${findgrub2}" != "" ]; then
+        DIALOG --msgbox "Error: ${findgrub2} exists, refusing to overwrite!" 0 0
+        return 1
+    fi
+    # create grub image
+    mkdir -p "${uefimount}/EFI/BOOT" || return 1
+    grub2-mkimage -p /boot/grub2 -o "${uefimount}/EFI/BOOT/BOOTX64.EFI" -O x86_64-efi part_msdos part_gpt fat normal \
+        || return 1
+    # copy grub modules
+    mkdir -p "${uefimount}/boot/grub2" || return 1
+    cp -ar /usr/lib/grub/x86_64-efi "${uefimount}/boot/grub2/" \
+        || return 1
+    # create a crude grug.cfg
+    mkdir -p "${uefimount}/boot/grub2" || return 1
+    cat >> "${uefimount}/boot/grub2/grub.cfg" <<EOF
+timeout=5
+menuentry 'Pentoo' {
+    insmod efi_gop
+    insmod efi_uga
+    insmod part_msdos
+    insmod part_gpt
+    root=${grubpart}
+    linux ${kernelpath} ${bootparams}
+    initrd ${initrdpath}
+}
+EOF
+    DIALOG --msgbox "UEFI boot image successfully installed. You can now review the GRUB-2 config file." 0 0
+    [ "$EDITOR" ] || geteditor
+    $EDITOR "${uefimount}/boot/grub2/grub.cfg"
+    DIALOG --msgbox "Success: UEFI booting by GRUB-2 installed!" 0 0
+}
+
+# douefi()
+# writes kernel to UEFI as new boot option
+# parameters:
+#     kernelpath: path to kernel, relative to partition root
+#     initrdpath: path to initrd
+#     bootparams: other boot params for kernel
+# returns: 1 on failure
+#
+douefi() {
+    modprobe efivars
+    # check if booted through UEFI
+    efibootmgr -v 2>/dev/null 1>&2
+    if [ $? -ne 0 ]; then
+        DIALOG --msgbox "Error: Couldn't read from UEFI. Did you boot through UEFI?" 0 0
+        return 1
+    fi
+    # kernel path with \\ instead of /
+    local kernelpath=${1//\//\\\\}
+    # initrd path with \ instead of /
+    local initrdpath=${2//\//\\}
+    local bootparams="${3}"
+    # kernelpart: kernel partition, ex. /dev/sda2
+    DIALOG --menu "Select the partition with the kernel (/boot)" 21 50 13 NONE - $PARTS 2>$ANSWER || return 1
+    local kernelpart=$(cat $ANSWER)
+    PARTS="$(echo $PARTS | sed -e "s#${kernelpart}\ _##g")"
+    [ "$kernelpart" = "NONE" ] && return 1
+    # kernelpart as disk and trailing part-number
+    local kernelpartnu=$(expr match "${kernelpart}" '.*\([1-9][0-9]*\)')
+    local kernelpartdisk=${kernelpart:0: -${#kernelpartnu}}
+    # write to UEFI
+    echo "${bootparams} initrd=${initrdpath}" | \
+        iconv -f ascii -t ucs2 | \
+        efibootmgr --create --gpt \
+            --disk "${kernelpartdisk}" --part "${kernelpartnu}" \
+            --label "Pentoo" \
+            --loader "${kernelpath}" \
+            --append-binary-args -
+    if [ $? -ne 0 ]; then
+        DIALOG --msgbox "Error: Couldn't write to UEFI!" 0 0
+        return 1
+    fi
+    DIALOG --msgbox "Success: Direct UEFI booting installed!" 0 0
+}
+
+# dobootloader()
+# installs boot loader
+# parameters:
+#     bootmode:
+#         - uefigrub: installs GRUB2 UEFI-image plus menu
+#         - uefi: boot kernel direclty by UEFI
+# returns: 1 on failure
+#
+dobootloader() {
+    local bootmode="${1}"
+    local _kernver=$(getkernelversion)
+    local kernelpath="/boot/kernel-genkernel${_kernver}"
+    local initrdpath="/boot/initramfs-genkernel${_kernver}"
+    local bootparams="root=/dev/ram0 real_root=${PART_ROOT}"
+    # select UEFI boot partition
+    PARTS=$(findpartitions _)
+    # compose boot parameters
+    # parse kernel cmdline (only video mode for now)
+    for _var in $(cat /proc/cmdline); do
+        case $_var in
+            video=*)
+                eval $(echo $_var) ;;
+        esac
+    done
+    bootparams+=" video=${video} console=tty1 ro"
+    case "${bootmode}" in
+        uefigrub)
+            douefigrub "${kernelpath}" "${initrdpath}" "${bootparams}" \
+                || return 1
+            ;;
+        uefi)
+            douefi "${kernelpath}" "${initrdpath}" "${bootparams}" \
+            || return 1
+            ;;
+    esac
+}
+
+# dogrub()
+# installs grub
+# params: none
+# returns: 1 on failure
 dogrub() {
     get_grub_map
     local grubmenu="$DESTDIR/boot/grub/menu.lst"
@@ -764,7 +937,7 @@
 			esac
 		done
 	    # get kernel version
-	    local _kernver=$(ls $DESTDIR/boot/kernel-genkernel-* |sed -e "s|kernel-genkernel||g" -e "s|$DESTDIR/boot/||")
+	    local _kernver=$(getkernelversion)
             cat >>$grubmenu <<EOF
 
 # (0) Pentoo
@@ -997,11 +1170,15 @@
 install_bootloader()
 {
     DIALOG --colors --menu "Which bootloader would you like to use?  Grub is the Pentoo default.\n\n" \
-        10 65 2 \
+        12 75 4 \
         "GRUB" "Use the GRUB bootloader (default)" \
+        "UEFI-GRUB" "Use GRUB2 and UEFI" \
+        "UEFI" "Boot kernel directly by UEFI" \
         "None" "\Zb\Z1Warning\Z0\ZB: you must install your own bootloader!" 2>$ANSWER
     case $(cat $ANSWER) in
         "GRUB") dogrub ;;
+        "UEFI-GRUB") dobootloader 'uefigrub' ;;
+        "UEFI") dobootloader 'uefi' ;;
     esac
 }
 
