From 39b84ff8812a3460f60e00ec2729dba9a7eb7849 Mon Sep 17 00:00:00 2001 From: Irina Gómez Date: Fri, 14 Dec 2018 11:02:11 +0100 Subject: #802 UEFI compatibility: allows postconfigure and log in to Ubuntu. --- client/engine/Boot.lib | 111 +++++++++++++++++++++++++++++++++++++++---------- client/engine/UEFI.lib | 91 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+), 21 deletions(-) create mode 100644 client/engine/UEFI.lib (limited to 'client/engine') diff --git a/client/engine/Boot.lib b/client/engine/Boot.lib index e9ddf38e..539be0b1 100755 --- a/client/engine/Boot.lib +++ b/client/engine/Boot.lib @@ -42,7 +42,7 @@ function ogBoot () { # Variables locales. local PART TYPE MNTDIR PARAMS KERNEL INITRD APPEND FILE LOADER f -local EFIDISK EFIPART EFIDIR BOOTLABEL BOOTNO +local EFIDISK EFIPART EFIDIR BOOTLABEL BOOTNO DIRGRUB b # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then @@ -79,28 +79,36 @@ case "$TYPE" in [ -e "$MNTDIR/etc" ] && APPEND=$(echo $APPEND | awk -v P="$PART " '{sub (/root=[-+=_/a-zA-Z0-9]* /,"root="P);print}') # Comprobar tipo de sistema. if ogIsEfiActive; then - # Obtener parcición EFI. - read -e EFIDISK EFIPART <<<"$(ogGetEsp)" - [ -n "$EFIPART" ] || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? # Comprobar si el Kernel está firmado. if ! file -k "$MNTDIR/$KERNEL" | grep -q "EFI app"; then ogRaiseError $OG_ERR_NOTOS "$1 $2 ($TYPE, EFI)" return $? fi - # Crear directorio para el cargador y copiar los ficheros. - EFIDIR=$(ogMount $EFIDISK $EFIPART) || exit $? - BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) - mkdir -p $EFIDIR/EFI/$BOOTLABEL - cp $MNTDIR/$KERNEL $EFIDIR/EFI/$BOOTLABEL/vmlinuz.efi - cp $MNTDIR/$INITRD $EFIDIR/EFI/$BOOTLABEL/initrd.img + ### Se realiza en la postconfiguracion ¿lo volvemos a hacer aquí? + ## Configuramos el grub.cfg de la partición EFI + ## Directorio del grub en la partición de sistema + #for f in $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do + # [ -r $f ] && DIRGRUB=$(dirname $f) + #done + #DIRGRUB=${DIRGRUB#$MNTDIR/} + #ogGrubUEFIConf $1 $2 $DIRGRUB || return $? + # Borrar cargador guardado con la misma etiqueta. + BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) BOOTNO=$(efibootmgr -v | awk -v L=$BOOTLABEL '{if ($2==L) print $1}') - [ -n "$BOOTNO" ] && efibootmgr -B -b ${BOOTNO:4:4} + for b in $BOOTNO; do + efibootmgr -B -b ${b:4:4} &>/dev/null + done + # Obtener parcición EFI. + read -e EFIDISK EFIPART <<<"$(ogGetEsp)" # Crear orden de arranque (con unos valores por defecto). - efibootmgr -C -d $(ogDiskToDev $EFIDISK) -p $EFIPART -L "$BOOTLABEL" -l /EFI/$BOOTLABEL/vmlinuz.efi -u "initrd=/EFI/$BOOTLABEL/initrd.img $APPEND" + efibootmgr -C -d $(ogDiskToDev $EFIDISK) -p $EFIPART -L "$BOOTLABEL" -l "/EFI/$BOOTLABEL/grubx64.efi" &>/dev/null # Marcar próximo arranque y reiniciar. BOOTNO=$(efibootmgr -v | awk -v L="$BOOTLABEL" '{if ($2==L) print $1}') - [ -n "$BOOTNO" ] && efibootmgr -n ${BOOTNO:4:4} + [ -n "$BOOTNO" ] && efibootmgr -n ${BOOTNO:4:4} &>/dev/null + # Incluimos en el orden de arranque + BOOTORDER=$(efibootmgr | awk -v L="BootOrder:" '{if ($1==L) print $2}') + [[ $BOOTORDER =~ ${BOOTNO:4:4} ]] || efibootmgr -o $BOOTORDER,${BOOTNO:4:4} reboot else # Arranque BIOS: configurar kernel Linux con los parámetros leídos de su GRUB. @@ -731,6 +739,7 @@ function ogGrubInstallMbr () # Variables locales. local PART DISK VERSION FIRSTAGE SECONSTAGE CHECKOS KERNELPARAM BACKUPNAME +local EFIDISK EFIPART EFISECONDSTAGE EFISUBDIR # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then @@ -758,7 +767,7 @@ BACKUPNAME=".backup.og" FIRSTSTAGE=$(ogDiskToDev 1) #localizar disco segunda etapa del grub -SECONDSTAGE=$(ogMount $DISK $PART) +SECONDSTAGE=$(ogMount "$DISK" "$PART") || return $? # prepara el directorio principal de la segunda etapa [ -d ${SECONDSTAGE}/boot/grub/ ] || mkdir -p ${SECONDSTAGE}/boot/grub/ @@ -766,6 +775,19 @@ SECONDSTAGE=$(ogMount $DISK $PART) #Localizar directorio segunda etapa del grub PREFIXSECONDSTAGE="/boot/grubMBR" +# Instalamos grub para EFI en ESP +if ogIsEfiActive; then + read EFIDISK EFIPART <<< $(ogGetEsp) + # Comprobamos que exista ESP y el directorio para ubuntu + EFISECONDSTAGE=$(ogMount $EFIDISK $EFIPART) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? + EFISUBDIR=$(printf "Part-%02d-%02d" $DISK $PART) + [ -d ${EFISECONDSTAGE}/EFI/$EFISUBDIR ] || mkdir -p ${EFISECONDSTAGE}/EFI/$EFISUBDIR + #Instalar el grub + grub-install --force --target x86_64-efi --efi-directory=${EFISECONDSTAGE} --root-directory=${EFISECONDSTAGE}/EFI/$EFISUBDIR $FIRSTSTAGE + # Solo para ubuntu: falta generalizar + mv -v $EFISECONDSTAGE/EFI/ubuntu/grubx64.efi $EFISECONDSTAGE/EFI/$EFISUBDIR +fi + # Si Reconfigurar segunda etapa (grub.cfg) == FALSE if [ -f ${SECONDSTAGE}/boot/grub/grub.cfg -o -f ${SECONDSTAGE}/boot/grub/grub.cfg$BACKUPNAME ] then @@ -776,7 +798,12 @@ then # Si no se reconfigure se borra los ficheros previos de configuración específicos de opengnsys. [ -d ${SECONDSTAGE}${PREFIXSECONDSTAGE} ] && rm -fr ${SECONDSTAGE}${PREFIXSECONDSTAGE} # Reactivamos el grub con el grub.cfg original. - grub-install --force --root-directory=${SECONDSTAGE} $FIRSTSTAGE + if ogIsEfiActive; then + # Configuración de grub.cfg para EFI + ogGrubUEFIConf $1 $2 + else + grub-install --force --root-directory=${SECONDSTAGE} $FIRSTSTAGE + fi return $? fi fi @@ -801,8 +828,13 @@ sed -i 's/^set -e/#set -e/' /etc/grub.d/00_header #Preparar configuración segunda etapa: crear entrada del sistema operativo grubSyntax "$KERNELPARAM" >> ${SECONDSTAGE}${PREFIXSECONDSTAGE}/boot/grub/grub.cfg -#Instalar el grub -grub-install --force --root-directory=${SECONDSTAGE}${PREFIXSECONDSTAGE} $FIRSTSTAGE +# Instalar el grub no EFI, configurar EFI +# Para EFI en ESP para otros en la partición de sistema. +if ogIsEfiActive; then + ogGrubUEFIConf $1 $2 ${PREFIXSECONDSTAGE} +else + grub-install --force --root-directory=${SECONDSTAGE}${PREFIXSECONDSTAGE} $FIRSTSTAGE +fi } @@ -831,6 +863,7 @@ function ogGrubInstallPartition () # Variables locales. local PART DISK VERSION FIRSTAGE SECONSTAGE CHECKOS KERNELPARAM BACKUPNAME +local EFIDISK EFIPART EFISECONDSTAGE EFISUBDIR # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then @@ -861,6 +894,19 @@ SECONDSTAGE=$(ogMount $DISK $PART) #Localizar directorio segunda etapa del grub PREFIXSECONDSTAGE="/boot/grubPARTITION" +# Si es EFI instalamos el grub en la ESP +if ogIsEfiActive; then + read EFIDISK EFIPART <<< $(ogGetEsp) + # Comprobamos que exista ESP y el directorio para ubuntu + EFISECONDSTAGE=$(ogMount $EFIDISK $EFIPART) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? + EFISUBDIR=$(printf "Part-%02d-%02d" $DISK $PART) + [ -d ${EFISECONDSTAGE}/EFI/$EFISUBDIR ] || mkdir -p ${EFISECONDSTAGE}/EFI/$EFISUBDIR + #Instalar el grub + grub-install --force --target x86_64-efi --efi-directory ${EFISECONDSTAGE} --root-directory=${EFISECONDSTAGE}/EFI/ubuntu $FIRSTSTAGE + # Solo para ubuntu: falta generalizar + mv -v $EFISECONDSTAGE/EFI/ubuntu/grubx64.efi $EFISECONDSTAGE/EFI/$EFISUBDIR +fi + # Si Reconfigurar segunda etapa (grub.cfg) == FALSE if [ -f ${SECONDSTAGE}/boot/grub/grub.cfg -o -f ${SECONDSTAGE}/boot/grub/grub.cfg$BACKUPNAME ] then @@ -871,7 +917,12 @@ then # Si no se reconfigure se borra los ficheros previos de configuración específicos de opengnsys. [ -d ${SECONDSTAGE}${PREFIXSECONDSTAGE} ] && rm -fr ${SECONDSTAGE}${PREFIXSECONDSTAGE} # Reactivamos el grub con el grub.cfg original. - grub-install --force --root-directory=${SECONDSTAGE} $FIRSTSTAGE + if ogIsEfiActive; then + # Configuración de grub.cfg para EFI + ogGrubUEFIConf $1 $2 + else + grub-install --force --root-directory=${SECONDSTAGE} $FIRSTSTAGE + fi return $? fi fi @@ -892,8 +943,12 @@ sed -i 's/^set -e/#set -e/' /etc/grub.d/00_header #Preparar configuración segunda etapa: crear entrada del sistema operativo grubSyntax $DISK $PART "$KERNELPARAM" >> ${SECONDSTAGE}${PREFIXSECONDSTAGE}/boot/grub/grub.cfg -#Instalar el grub -grub-install --force --root-directory=${SECONDSTAGE}${PREFIXSECONDSTAGE} $FIRSTSTAGE +#Instalar el grub si no es EFI, configurar si es EFI +if ogIsEfiActive; then + ogGrubUEFIConf $1 $2 ${PREFIXSECONDSTAGE} +else + grub-install --force --root-directory=${SECONDSTAGE}${PREFIXSECONDSTAGE} $FIRSTSTAGE +fi } @@ -912,11 +967,15 @@ grub-install --force --root-directory=${SECONDSTAGE}${PREFIXSECONDSTAGE} $FIRSTS #@version 1.0.6b - correccion. Si no hay partición fisica para la SWAP, eliminar entrada del fstab. #@author Antonio J. Doblas Viso. Universidad de Malaga. #@date 2016-11-03 +#@version 1.1.1 - Se configura la partición ESP (para sistemas EFI) (ticket #802) +#@author Irina Gómez, ETSII Universidad de Sevilla +#@date 2018-12-13 #*/ ## function ogConfigureFstab () { # Variables locales. local FSTAB DEFROOT PARTROOT DEFSWAP PARTSWAP +local EFIDISK EFIPART DEVEFI OPTEFI # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then @@ -954,9 +1013,19 @@ else echo "No hay partición SWAP -> configuramos FSTAB" # Mensaje temporal. sed "/swap/d" ${FSTAB}.backup > ${FSTAB} fi -} +# Si es un sistema EFI incluimos partición ESP (Si existe la modificamos) +if [ ogIsEfiActive ]; then + read EFIDISK EFIPART <<< $(ogGetEsp) + DEVEFI=$(ogDiskToDev $EFIDISK $EFIPART) + # Opciones de la partición ESP: si no existe ponemos un valor por defecto + OPTEFI=$(awk '$1!~/#/ && $2=="/boot/efi" {print $3"\t"$4"\t"$5"\t"$6 }' ${FSTAB}) + OPTEFI=${OPTEFI:-vfat\tumask=0077\t0\t1} + sed -i /"boot\/efi"/d ${FSTAB} + echo -e "$DEVEFI\t/boot/efi\tvfat\tumask=0077\t0\t1" >> ${FSTAB} +fi +} #/** # ogSetLinuxName int_ndisk int_nfilesys [str_name] diff --git a/client/engine/UEFI.lib b/client/engine/UEFI.lib new file mode 100644 index 00000000..5672e09c --- /dev/null +++ b/client/engine/UEFI.lib @@ -0,0 +1,91 @@ +#!/bin/bash +# Libreria provisional para uso de UEFI +# Las funciones se incluirán las librerías ya existentes + +#/** +# ogGrubUEFIConf int_ndisk int_part str_dir_grub +#@brief Genera el fichero grub.cfg de la ESP +#@param int_ndisk nº de orden del disco +#@param int_part nº de partición +#@param str_dir_grub nombre del directorio de grub en la partición de sistema. ej: grubPARTITION +#@return (nada, por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@TODO Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario. +#*/ ## +function ogGrubUEFIConf { +local EFIDIR BOOTLABEL GRUBEFI UUID DEVICE DIRGRUB + +# Si se solicita, mostrar ayuda. +if [ "$*" == "help" ]; then + ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" \ + "$FUNCNAME 1 2" \ + "$FUNCNAME 1 3 grubPARTITION/boot/grub" \ + return +fi + +# Error si no se reciben al menos 2 parámetros. +[ $# -ge 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" || return $? + +# Directorio del grub en la partición de sistema +DIRGRUB="${3:-boot/grub}" + +EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? +BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) +GRUBDIR="$EFIDIR/EFI/$BOOTLABEL/boot/grub" +# Comprobamos que existe directorio +[ -d "$GRUBDIR" ] || mkdir -p "$GRUBDIR" +# Parcheamos uuid y particion en grub.cfg +UUID=$(blkid -o value -s UUID $(ogDiskToDev $1 $2)) +DEVICE="hd$(expr $1 - 1 ),gpt$2" + +cat << EOT > $GRUBDIR/grub.cfg +set root='$DEVICE' +set prefix=(\$root)'/$DIRGRUB' +configfile \$prefix/grub.cfg +EOT + +# Provisional: confirmar si el segundo archivo se utiliza +cp $GRUBDIR/grub.cfg "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" +} + +#/** +# ogUUIDChange int_ndisk str_repo +#@brief Reemplaza el UUID de un sistema de ficheros. +#@param int_ndisk nº de orden del disco +#@param int_part nº de partición +#@return (nada, por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@TODO Se utiliza el comando uuidgen que no existe en el ogLive +#*/ ## +function ogUUIDChange { +local MNTDIR DEVICE UUID NEWUUID f + +# Si se solicita, mostrar ayuda. +if [ "$*" == "help" ]; then + ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \ + "$FUNCNAME 1 2" + return +fi + +# Error si no se reciben al menos 2 parámetros. +[ $# -eq 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $? + +# Comprobamos que exista la partición +MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_NOTFOUND "Device $1 $2" || return $? +DEVICE=$(ogDiskToDev $1 $2) +UUID=$(blkid -o value -s UUID $DEVICE) +NEWUUID=$(uuidgen) + +# Cambiamos UUID a la partición +ogUnmount $1 $2 +tune2fs $DEVICE -U $NEWUUID + +# Cambiamos UUID en la configuración (fstab y grub) +ogMount $1 $2 +for f in $MNTDIR/etc/fstab $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do + [ -r $f ] && echo sed -i s/$UUID/$NEWUUID/g $f + [ -r $f ] && sed -i s/$UUID/$NEWUUID/g $f +done +} -- cgit v1.2.3-18-g5258