LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices


Reply
  Search this Thread
Old 04-30-2018, 05:54 PM   #1
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Rep: Reputation: Disabled
[Call for testing] Script to populate grub.cfg with all EFI entries.


Hello,

The attached script writes a grub.cfg file including entries for all EFI applications (including EFI loaders) found on block devices attached to the system, mounted or not, including IDE and SATA disks, NVMe, USB connected drives, eMMC drives, whatever.

It could be useful for folks running multi-boot systems, including non Linux ones, for instance run after elilo.

I didn't test with eMMC drives because I don't have any and there is no virtual drives available for VirtualBox.

Please test and report your findings here.

The file is written in /tmp, not directly in /boot/grub, so there is no risk running the script, I think.

I also paste the code below.
Code:
#!/bin/sh
# Copyright 2018 Didier Spaier <didier~at~slint~dot~fr>
# 
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  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.

# Purpose: this script writes a GRUB config file including an entry for
# each EFI application found in any device attached to the computer,
# including but not limited to EFI loaders.

# Limitations: this script only handles EFI images accessible at time of
# running it, stored in an ESP with a FAT file system, with a partition
# table labeled either msdos or gpt.
if [ $(id -u) -ne 0 ]; then
	echo "Only root may run this script."
	exit
fi
if [ ! -d /sys/firmware/efi ]; then
	echo "EFI booting is not enabled, game over."
	exit
fi
# The UEFI specification states that an EFI System partition should have 
# a GUID of C12A7328-F81F-11D2-BA4B-00A0C93EC93B for a GPT disk layout.
# In case of a MBR disk layout instead, an ESP should have an OS type of
# 0xEF. lsblk writes these values in the same field PARTTYPE.
ESPPARTTYPE=C12A7328-F81F-11D2-BA4B-00A0C93EC93B
OSTYPE=0xEF
ESPLIST=$(mktemp)
lsblk -l -o parttype,name,uuid,pkname|\
grep -i -F -e "$ESPPARTTYPE" -e "$OSTYPE"|sed "s/[^ ]* //" > $ESPLIST
if [ ! -s $ESPLIST ]; then # No EFI partitions
	echo "No EFI partition found, game over."
	rm $ESPLIST
	exit
fi
if [ -f /tmp/grub.cfg ]; then
	mv /tmp/grub.cfg /tmp/grub.cfg.orig
fi
MNT=$(mktemp -d)
while read NAME UUID PARENT; do
	TRAN=$(lsblk -l -o name,tran|grep "^$PARENT "|sed "s/.* //")
	ATTACH=""
	if [ "$TRAN" = "usb" ]; then
		ATTACH="through USB"
	fi
	mount -U $UUID $MNT || exit 1
	( cd $MNT
	EFIPATHS=$(mktemp)
	find -iname "*.efi"|sed s/.// > EFIPATHS
	for EFIPATH in $(<EFIPATHS); do
		EFIFILE=$(file $MNT/$EFIPATH|grep 'PE32+ executable (EFI application')
		if [ ! "$EFIFILE" = "" ]; then
			cat <<EOF >> /tmp/grub.cfg
menuentry "$EFIPATH on /dev/$NAME (UUID $UUID) $ATTACH" {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root $UUID
	chainloader $EFIPATH
}
EOF
		fi
	done
	)
done < $ESPLIST
rm -f $ESPLIST
umount $MNT 2>/dev/null
rmdir $MNT 2>/dev/null
echo "All done, now :
1) Check /tmp/grub.cfg
2) Copy or move it to /boot/grub/
3) Run grub-install"
Attached Files
File Type: txt efi4grubconfig.txt (3.0 KB, 14 views)

Last edited by Didier Spaier; 05-01-2018 at 03:20 AM. Reason: Cosmetic change to enhance portability.
 
Old 05-02-2018, 05:31 PM   #2
laprjns
Member
 
Registered: Oct 2005
Location: Connecticut USA
Distribution: SalixOS
Posts: 183

Rep: Reputation: 90
Gave the script a try on my laptop. First here are all the *.efi files on my ESP

Code:
rich[~]$ tree -f -i /boot/efi/EFI/ | grep .efi$
/boot/efi/EFI/Boot/Shell.efi
/boot/efi/EFI/Boot/bootx64-trueos.efi
/boot/efi/EFI/Boot/bootx64.efi
/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi
/boot/efi/EFI/Microsoft/Boot/bootmgr.efi
/boot/efi/EFI/Microsoft/Boot/bootx64.efi
/boot/efi/EFI/Microsoft/Boot/memtest.efi
/boot/efi/EFI/Salix-Xfce-14.2/elilo.efi
/boot/efi/EFI/Slackware/elilo.efi
/boot/efi/EFI/Slint/elilo.efi
/boot/efi/EFI/refind/drivers_x64/btrfs_x64.efi
/boot/efi/EFI/refind/drivers_x64/ext2_x64.efi
/boot/efi/EFI/refind/drivers_x64/ext4_x64.efi
/boot/efi/EFI/refind/drivers_x64/hfs_x64.efi
/boot/efi/EFI/refind/drivers_x64/iso9660_x64.efi
/boot/efi/EFI/refind/drivers_x64/ntfs_x64.efi
/boot/efi/EFI/refind/drivers_x64/reiserfs_x64.efi
/boot/efi/EFI/refind/refind_x64.efi
/boot/efi/EFI/refind/tools_x64/gptsync_x64.efi
/boot/efi/EFI/tools/Shellx64.efi
/boot/efi/EFI/tools/gdisk.efi
/boot/efi/EFI/tools/ipxe.efi
/boot/efi/EFI/tools/ipxe_discovery.efi
/boot/efi/EFI/tools/memtest/BOOTX64.efi
/boot/efi/EFI/trueOS/bootx64-trueos.efi
/boot/efi/EFI/ubuntu/fwupx64.efi
/boot/efi/EFI/ubuntu/grubx64.efi
And this is the grub.cfg file that your script created

Code:
rich[Downloads]$ cat /tmp/grub.cfg
menuentry "/EFI/Slint/elilo.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/Slint/elilo.efi
}
menuentry "/EFI/Microsoft/Boot/bootx64.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/Microsoft/Boot/bootx64.efi
}
menuentry "/EFI/Boot/bootx64-trueos.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/Boot/bootx64-trueos.efi
}
menuentry "/EFI/Salix-Xfce-14.2/elilo.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/Salix-Xfce-14.2/elilo.efi
}
menuentry "/EFI/tools/gdisk.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/tools/gdisk.efi
}
menuentry "/EFI/Slackware/elilo.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/Slackware/elilo.efi
}
menuentry "/EFI/ubuntu/fwupx64.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/ubuntu/fwupx64.efi
}
menuentry "/EFI/ubuntu/grubx64.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/ubuntu/grubx64.efi
}
menuentry "/EFI/trueOS/bootx64-trueos.efi on /dev/sda1 (UUID 9037-2232) " {
	insmod part_gpt
	insmod part_msdos
	insmod fat
	search --fs-uuid --set=root 9037-2232
	chainloader /EFI/trueOS/bootx64-trueos.efi
}
rich[Downloads]$
Not sure why the script doesn't create stanzas for all the *.efi files, although most of them are junk anyway. Was really surprised that it didn't create one for refind.

Last edited by laprjns; 05-02-2018 at 06:33 PM.
 
1 members found this post helpful.
Old 05-02-2018, 06:14 PM   #3
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by laprjns View Post
Gave the script a try on my laptop. First here are all the *.efi files on my ESP

Code:
rich[~]$ tree -f -i /boot/efi/EFI/ | grep .efi$
/boot/efi/EFI/Boot/Shell.efi
/boot/efi/EFI/Boot/bootx64-trueos.efi
/boot/efi/EFI/Boot/bootx64.efi
/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi
/boot/efi/EFI/Microsoft/Boot/bootmgr.efi
/boot/efi/EFI/Microsoft/Boot/bootx64.efi
/boot/efi/EFI/Microsoft/Boot/memtest.efi
/boot/efi/EFI/Salix-Xfce-14.2/elilo.efi
/boot/efi/EFI/Slackware/elilo.efi
/boot/efi/EFI/Slint/elilo.efi
/boot/efi/EFI/refind/drivers_x64/btrfs_x64.efi
/boot/efi/EFI/refind/drivers_x64/ext2_x64.efi
/boot/efi/EFI/refind/drivers_x64/ext4_x64.efi
/boot/efi/EFI/refind/drivers_x64/hfs_x64.efi
/boot/efi/EFI/refind/drivers_x64/iso9660_x64.efi
/boot/efi/EFI/refind/drivers_x64/ntfs_x64.efi
/boot/efi/EFI/refind/drivers_x64/reiserfs_x64.efi
/boot/efi/EFI/refind/refind_x64.efi
/boot/efi/EFI/refind/tools_x64/gptsync_x64.efi
/boot/efi/EFI/tools/Shellx64.efi
/boot/efi/EFI/tools/gdisk.efi
/boot/efi/EFI/tools/ipxe.efi
/boot/efi/EFI/tools/ipxe_discovery.efi
/boot/efi/EFI/tools/memtest/BOOTX64.efi
/boot/efi/EFI/trueOS/bootx64-trueos.efi
/boot/efi/EFI/ubuntu/fwupx64.efi
/boot/efi/EFI/ubuntu/grubx64.efi
An this is the grub.cfg file that your script created

Code:
rich[Downloads]$ cat /tmp/grub.cfg
menuentry "/EFI/Slint/elilo.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/Slint/elilo.efi
}
menuentry "/EFI/Microsoft/Boot/bootx64.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/Microsoft/Boot/bootx64.efi
}
menuentry "/EFI/Boot/bootx64-trueos.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/Boot/bootx64-trueos.efi
}
menuentry "/EFI/Salix-Xfce-14.2/elilo.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/Salix-Xfce-14.2/elilo.efi
}
menuentry "/EFI/tools/gdisk.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/tools/gdisk.efi
}
menuentry "/EFI/Slackware/elilo.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/Slackware/elilo.efi
}
menuentry "/EFI/ubuntu/fwupx64.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/ubuntu/fwupx64.efi
}
menuentry "/EFI/ubuntu/grubx64.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/ubuntu/grubx64.efi
}
menuentry "/EFI/trueOS/bootx64-trueos.efi on /dev/sda1 (UUID 9037-2232) " {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root 9037-2232
    chainloader /EFI/trueOS/bootx64-trueos.efi
}
rich[Downloads]$
Not sure why the script doesn't create stanzas for all the *.efi files, although most of them are junk anyway. Was really surprised that it didn't create one for refind.
Thanks for testing.

I assume that this test:
Code:
EFIFILE=$(file $MNT/$EFIPATH|grep 'PE32+ executable (EFI application')
is too selective. To check, please provide the output of this command:
Code:
tree -f -i /boot/efi/EFI/ | grep .efi$ | xargs file
 
Old 05-02-2018, 06:25 PM   #4
laprjns
Member
 
Registered: Oct 2005
Location: Connecticut USA
Distribution: SalixOS
Posts: 183

Rep: Reputation: 90
Here you go;
Code:
rich[~]$ tree -f -i /boot/efi/EFI/ | grep .efi$ | xargs file
/boot/efi/EFI/Boot/Shell.efi:                      MS-DOS executable
/boot/efi/EFI/Boot/bootx64-trueos.efi:             PE32+ executable (EFI application) x86-64, for MS Windows
/boot/efi/EFI/Boot/bootx64.efi:                    MS-DOS executable
/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi:         PE32+ executable (DLL) (EFI application) x86-64, for MS Windows
/boot/efi/EFI/Microsoft/Boot/bootmgr.efi:          PE32+ executable (DLL) x86-64, for MS Windows
/boot/efi/EFI/Microsoft/Boot/bootx64.efi:          PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
/boot/efi/EFI/Microsoft/Boot/memtest.efi:          PE32+ executable x86-64, for MS Windows
/boot/efi/EFI/Salix-Xfce-14.2/elilo.efi:           PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
/boot/efi/EFI/Slackware/elilo.efi:                 PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
/boot/efi/EFI/Slint/elilo.efi:                     PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
/boot/efi/EFI/refind/drivers_x64/btrfs_x64.efi:    MS-DOS executable
/boot/efi/EFI/refind/drivers_x64/ext2_x64.efi:     MS-DOS executable
/boot/efi/EFI/refind/drivers_x64/ext4_x64.efi:     MS-DOS executable
/boot/efi/EFI/refind/drivers_x64/hfs_x64.efi:      MS-DOS executable
/boot/efi/EFI/refind/drivers_x64/iso9660_x64.efi:  MS-DOS executable
/boot/efi/EFI/refind/drivers_x64/ntfs_x64.efi:     MS-DOS executable
/boot/efi/EFI/refind/drivers_x64/reiserfs_x64.efi: MS-DOS executable
/boot/efi/EFI/refind/refind_x64.efi:               MS-DOS executable
/boot/efi/EFI/refind/tools_x64/gptsync_x64.efi:    MS-DOS executable
/boot/efi/EFI/tools/Shellx64.efi:                  MS-DOS executable
/boot/efi/EFI/tools/gdisk.efi:                     PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
/boot/efi/EFI/tools/ipxe.efi:                      MS-DOS executable
/boot/efi/EFI/tools/ipxe_discovery.efi:            MS-DOS executable
/boot/efi/EFI/tools/memtest/BOOTX64.efi:           MS-DOS executable
/boot/efi/EFI/trueOS/bootx64-trueos.efi:           PE32+ executable (EFI application) x86-64, for MS Windows
/boot/efi/EFI/ubuntu/fwupx64.efi:                  PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
/boot/efi/EFI/ubuntu/grubx64.efi:                  PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
 
1 members found this post helpful.
Old 05-02-2018, 06:37 PM   #5
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Thanks. So, this confirms my assumption.

Now, as the script's purpose is to build a boot menu, do you think that some of the missing .efi files should be included in the output file, and which ones?

Maybe /boot/efi/EFI/refind/refind_x64.efi? Others?
 
Old 05-03-2018, 05:00 AM   #6
laprjns
Member
 
Registered: Oct 2005
Location: Connecticut USA
Distribution: SalixOS
Posts: 183

Rep: Reputation: 90
Quote:
Originally Posted by Didier Spaier View Post
Thanks. So, this confirms my assumption.

Now, as the script's purpose is to build a boot menu, do you think that some of the missing .efi files should be included in the output file, and which ones?
Well let see. For the EFI/Boot directory I would only add the bootx64.efi. This directory is suppose to be for a fallback boot option in the event that nothing else boots. In my opinion some distro miss-use it. Note that trueOS (BSD) added an efi file there.

Window - Only add entry for bootmgfw.efi.

Tools directory (EFI/tools) it would be nice to add all the tools, maybe is a sub menu if possible. That what is nice about refind, it adds smaller launch icons for tools in a separate line from the main OS launch applications.

For ubuntu, EFI/ubuntu, (its actually Mint) just add an entry for the grubx64.efi. The other file, fwupx64.efi is for launching a firmware update utility.

And finally rEFInd. I not sure that launching a boot manager from another boot manager make much sense, but yeah for the sake of completeness I think it should be added.
 
Old 05-05-2018, 04:15 PM   #7
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by laprjns View Post
Well let see. For the EFI/Boot directory I would only add the bootx64.efi. This directory is suppose to be for a fallback boot option in the event that nothing else boots. In my opinion some distro miss-use it. Note that trueOS (BSD) added an efi file there.

Window - Only add entry for bootmgfw.efi.

Tools directory (EFI/tools) it would be nice to add all the tools, maybe is a sub menu if possible. That what is nice about refind, it adds smaller launch icons for tools in a separate line from the main OS launch applications.

For ubuntu, EFI/ubuntu, (its actually Mint) just add an entry for the grubx64.efi. The other file, fwupx64.efi is for launching a firmware update utility.

And finally rEFInd. I not sure that launching a boot manager from another boot manager make much sense, but yeah for the sake of completeness I think it should be added.
To check I installed refind in the VM and removed the restriction to "PE32+ executable (EFI application)" and ran the script then grub-install with that. I noted that the entries to files in
boot/efi/EFI/refind/drivers_x64/ do nothing. I assume that they are only used by refind itself internally (like the files in /usr/libexec, as an analogy).

/boot/efi/EFI/refind/tools_x64/gptsync_x64.efi works, but it's not our business an hybrid MBR anyway as this feature is provided "only for Apple Macs that dual-boot with Windows or some BIOS-mode OS."

So I am tempted to write stanzas in the file only if one of these conditions is met:
  • The file is a "PE32+ executable" and also an "(EFI application)" according to the file utility.
  • The file is named bootx64.efi
But, before I change this please generate grub.cfg with the "unrestricted" script below, copy or move it to /boot/grub and run grub-install.

It is possible than refind be still first started, in this case you can just refresh it and start grub.efi from it.

I would like to know which of the resulting entries are actually enabled from the boot menu after that.

Then, I am considering allowing the user to customize each stanza's label.

Code:
#!/bin/sh
# Copyright 2018 Didier Spaier <didier~at~slint~dot~fr>
# 
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  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.

# Purpose: this script writes a GRUB config file including an entry for
# each EFI application found in any device attached to the computer,
# including but not limited to EFI loaders.

# Limitations: this script only handles EFI images accessible at time of
# running it, stored in an ESP with a FAT file system, with a partition
# table labeled either msdos or gpt.
if [ $(id -u) -ne 0 ]; then
    echo "Only root may run this script."
    exit
fi
if [ ! -d /sys/firmware/efi ]; then
    echo "EFI booting is not enabled, game over."
    exit
fi
# The UEFI specification states that an EFI System partition should have 
# a GUID of C12A7328-F81F-11D2-BA4B-00A0C93EC93B for a GPT disk layout.
# In case of a MBR disk layout instead, an ESP should have an OS type of
# 0xEF. lsblk writes these values in the same field PARTTYPE.
ESPPARTTYPE=C12A7328-F81F-11D2-BA4B-00A0C93EC93B
OSTYPE=0xEF
ESPLIST=$(mktemp)
lsblk -l -o parttype,name,uuid,pkname|\
grep -i -F -e "$ESPPARTTYPE" -e "$OSTYPE"|sed "s/[^ ]* //" > $ESPLIST
if [ ! -s $ESPLIST ]; then # No EFI partitions
    echo "No EFI partition found, game over."
    rm $ESPLIST
    exit
fi
if [ -f /tmp/grub.cfg ]; then
    mv /tmp/grub.cfg /tmp/grub.cfg.orig
fi
MNT=$(mktemp -d)
while read NAME UUID PARENT; do
    TRAN=$(lsblk -l -o name,tran|grep "^$PARENT "|sed "s/.* //")
    ATTACH=""
    if [ "$TRAN" = "usb" ]; then
        ATTACH="through USB"
    fi
    mount -U $UUID $MNT || exit 1
    ( cd $MNT
    EFIPATHS=$(mktemp)
    find -iname "*.efi"|sed s/.// > EFIPATHS
    for EFIPATH in $(<EFIPATHS); do
#        EFIFILE=$(file $MNT/$EFIPATH|grep 'PE32+ executable (EFI application')
#        if [ ! "$EFIFILE" = "" ]; then
            cat <<EOF >> /tmp/grub.cfg
menuentry "$EFIPATH on /dev/$NAME (UUID $UUID) $ATTACH" {
    insmod part_gpt
    insmod part_msdos
    insmod fat
    search --fs-uuid --set=root $UUID
    chainloader $EFIPATH
}
EOF
#        fi
    done
    )
done < $ESPLIST
rm -f $ESPLIST
umount $MNT 2>/dev/null
rmdir $MNT 2>/dev/null
echo "All done, now :
1) Check /tmp/grub.cfg
2) Copy or move it to /boot/grub/
3) Run grub-install"

Last edited by Didier Spaier; 05-06-2018 at 05:16 AM.
 
Old 05-06-2018, 05:05 AM   #8
laprjns
Member
 
Registered: Oct 2005
Location: Connecticut USA
Distribution: SalixOS
Posts: 183

Rep: Reputation: 90
Hopefully I'll have some time today to test it. Regarding rEFInd, I forgot to add that you should ignore anything in the refind/driver directory. In fact I would suggest that you only add a stanza for refind/refind.efi
 
Old 05-06-2018, 05:03 PM   #9
laprjns
Member
 
Registered: Oct 2005
Location: Connecticut USA
Distribution: SalixOS
Posts: 183

Rep: Reputation: 90
Here's the list of menu items that your script produced on my system.
Code:
/EFI/Slint/elilo.efi on /dev/sda1
/EFI/refind/drivers_x64/hfs_x64.efi on /dev/sda1
/EFI/refind/drivers_x64/btrfs_x64.efi on /dev/sda1
/EFI/refind/drivers_x64/ext4_x64.efi on /dev/sda1
/EFI/refind/drivers_x64/iso9660_x64.efi on /dev/sda1
/EFI/refind/drivers_x64/ext2_x64.efi on /dev/sda1
/EFI/refind/drivers_x64/reiserfs_x64.efi on /dev/sda1
/EFI/refind/drivers_x64/ntfs_x64.efi on /dev/sda1
/EFI/refind/refind_x64.efi on /dev/sda1
/EFI/refind/tools_x64/gptsync_x64.efi on /dev/sda1
/EFI/Microsoft/Boot/bootmgr.efi on /dev/sda1
/EFI/Microsoft/Boot/memtest.efi on /dev/sda1
/EFI/Microsoft/Boot/bootmgfw.efi on /dev/sda1
/EFI/Microsoft/Boot/bootx64.efi on /dev/sda1
/EFI/Boot/Shell.efi on /dev/sda1
/EFI/Boot/bootx64.efi on /dev/sda1
/EFI/Boot/bootx64-trueos.efi on /dev/sda1
/EFI/Salix-Xfce-14.2/elilo.efi on /dev/sda1
/EFI/tools/Shellx64.efi on /dev/sda1
/EFI/tools/gdisk.efi on /dev/sda1
/EFI/tools/ipxe.efi on /dev/sda1
/EFI/tools/ipxe_discovery.efi on /dev/sda1
/EFI/tools/memtest/BOOTX64.efi on /dev/sda1
/EFI/Slackware/elilo.efi on /dev/sda1
/EFI/ubuntu/fwupx64.efi on /dev/sda1
/EFI/ubuntu/grubx64.efi on /dev/sda1
/EFI/trueOS/bootx64-trueos.efi on /dev/sda1
Going from top to bottom, you can ignore the rEFInd driver directory as they don't boot nor are they meant to. The only image in the Microsoft directory that booted was bootmgfw.efi, which boots into Win 10. All three of the images in the Boot directory booted, Shell.efi to the UEFI Shell, bootx64.efi booted into a rEFInd menu and bootx64-trueos.efi to TrueOS (BSD). The boot images in the Salix, Slint and Slackware all boot into the appropriate OS. Every image in the EFI/Tool directory work, but I don't think the ipx images are configured correctly. The fwupx64.efi in the ubuntu directory doesn't boot. The grub64.efi boots into a grub menu for Mint. bootx64-trueos.efi boots into TrueOS BSD.
 
1 members found this post helpful.
Old 05-11-2018, 01:07 PM   #10
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
OK, now I have compared what says rEFInd (using default options) with what says this script.

Considering your last post I will select files whose name ends on .efi:
  • that "file" characterize as both a PE32+ executable and an EFI application
  • and/or that are found in EFI/BOOT which is somehow a fallback directory to store bootloaders if entries in the firmware's menu fail.
I wonder if it's useful to include files in /EFI/tools, as probably users who install them will start them from the rEFInd menu, as they are considered addons of rEFInd (though admittedly people already using rEFInd won't need this script anyway...), so that would uselessly clutter the list.

I have a (maybe last) question before beginning the real work: in your last post you didn't mention /boot/efi/EFI/Microsoft/Boot/bootx64.efi as bootig but wrote "The only image in the Microsoft directory that booted was bootmgfw.efi, which boots into Win 10" Isn't this other entry also booting?

Last edited by Didier Spaier; 05-11-2018 at 01:12 PM.
 
Old 05-12-2018, 04:52 AM   #11
laprjns
Member
 
Registered: Oct 2005
Location: Connecticut USA
Distribution: SalixOS
Posts: 183

Rep: Reputation: 90
Quote:
Originally Posted by Didier Spaier View Post
Considering your last post I will select files whose name ends on .efi:
  • .....
  • and/or that are found in EFI/BOOT which is somehow a fallback directory to store bootloaders if entries in the firmware's menu fail.
Yes this is suppose to be a directory for a fallback bootable efi image, however it seems to me that the purpose of this directory is widely misunderstood. At first there were some efi firmware implementation that would only boot efi images from this directory. Now it seems like almost every distribution wants to throw a image into this directory and give it the generic bootx64.efi name.

Quote:
I wonder if it's useful to include files in /EFI/tools, as probably users who install them will start them from the rEFInd menu, as they are considered addons of rEFInd (though admittedly people already using rEFInd won't need this script anyway...), so that would uselessly clutter the list.
Yes I think you should include them. Although it not prevalent, some systems (HP and Apple) come with this directory on the system's ESP. I personally would like to see UEFI tightening up the spec for what should go into the ESP and where it should go, with EFI/Tools becoming the standard directory where uefi tool images be stored. Right now tools such as memtest get install all over the place depending on which distro is installing them.

Quote:
I have a (maybe last) question before beginning the real work: in your last post you didn't mention /boot/efi/EFI/Microsoft/Boot/bootx64.efi as bootig but wrote "The only image in the Microsoft directory that booted was bootmgfw.efi, which boots into Win 10" Isn't this other entry also booting?
On my laptop, booting this images fails into a grub rescue prompt. Not sure how it got installed, but I do not think it was part of the Windows installation.
 
1 members found this post helpful.
Old 05-12-2018, 07:26 AM   #12
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Thanks again Rich.

Quote:
Originally Posted by laprjns View Post
Quote:
Originally Posted by Didier Spaier View Post
  • ....
  • and/or that are found in EFI/BOOT which is somehow a fallback directory to store bootloaders if entries in the firmware's menu fail.
Yes this is suppose to be a directory for a fallback bootable efi image, however it seems to me that the purpose of this directory is widely misunderstood. At first there were some efi firmware implementation that would only boot efi images from this directory. Now it seems like almost every distribution wants to throw a image into this directory and give it the generic bootx64.efi name.
Which makes hard to identify the distribution is concern both for my script and for rEFInd. os-prober can sometimes do better, but not in all cases. We have to live with that, only thing we can do is include all these images, and allow the user to modify the stanza's label or title, I think.

Quote:
Originally Posted by laprjns View Post
Quote:
Originally Posted by Didier Spaier View Post
I wonder if it's useful to include files in /EFI/tools, as probably users who install them will start them from the rEFInd menu, as they are considered addons of rEFInd (though admittedly people already using rEFInd won't need this script anyway...), so that would uselessly clutter the list.
Yes I think you should include them. Although it not prevalent, some systems (HP and Apple) come with this directory on the system's ESP. I personally would like to see UEFI tightening up the spec for what should go into the ESP and where it should go, with EFI/Tools becoming the standard directory where uefi tool images be stored. Right now tools such as memtest get install all over the place depending on which distro is installing them.
OK I will include all of them. And maybe all /path/to/Shell*.efi although "file" just says it's a MS-DOS executable.

Quote:
Originally Posted by laprjns View Post
Quote:
Originally Posted by Didier Spaier View Post
I have a (maybe last) question before beginning the real work: in your last post you didn't mention /boot/efi/EFI/Microsoft/Boot/bootx64.efi as bootig but wrote "The only image in the Microsoft directory that booted was bootmgfw.efi, which boots into Win 10" Isn't this other entry also booting?
On my laptop, booting this images fails into a grub rescue prompt. Not sure how it got installed, but I do not think it was part of the Windows installation.
It will be included anyway. Missing a boot loader is worst than having a not working stanza in the boot menu, and I will provide a mean for the user to easily edit all stanzas (add, delete, modify) anyway.

Last edited by Didier Spaier; 05-12-2018 at 08:40 AM.
 
Old 05-12-2018, 04:48 PM   #13
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Let me quote some lines of the EFI Specification, Version 2.7 Errata A :
Code:
13.3.1.3 Directory Structure

An EFI system partition that is present on a hard disk must contain an EFI defined directory in the
root directory. This directory is named EFI. All OS loaders and applications will be stored in
subdirectories below EFI. Applications that are loaded by other applications or drivers are not
required to be stored in any specific location in the EFI system partition. The choice of the
subdirectory name is up to the vendor, but all vendors must pick names that do not collide with
any other vendor’s subdirectory name. This applies to system manufacturers, operating system
vendors, BIOS vendors, and third party tool vendors, or any other vendor that wishes to install files
on an EFI system partition. There must also only be one executable EFI image for each supported
processor architecture in each vendor subdirectory. This guarantees that there is only one image
that can be loaded from a vendor subdirectory by the EFI Boot Manager. If more than one
executable EFI image is present, then the boot behavior for the system will not be deterministic.
There may also be an optional vendor subdirectory called BOOT.

This directory contains EFI images that aide in recovery if the boot selections for the software
installed on the EFI system partition are ever lost. Any additional UEFI-compliant executables must
be in subdirectories below the vendor subdirectory. The following is a sample directory structure
for an EFI system partition present on a hard disk.

\EFI
    \<OS Vendor 1 Directory>
        <OS Loader Image>
    \<OS Vendor 2 Directory>
        <OS Loader Image>
    . . .
    \<OS Vendor N Directory>
        <OS Loader Image>
    \<OEM Directory>
        <OEM Application Image>
    \<BIOS Vendor Directory>
        <BIOS Vendor Application Image>
    \<Third Party Tool Vendor Directory>
        <Third Party Tool Vendor Application Image>
    \BOOT
        BOOT{machine type short name}.EFI
        
For removable media devices there must be only one UEFI-compliant system partition, and that
partition must contain an UEFI-defined directory in the root directory. The directory will be named
EFI. All OS loaders and applications will be stored in a subdirectory below EFI called BOOT. There
must only be one executable EFI image for each supported processor architecture in the BOOT
directory. For removable media to be bootable under EFI, it must be built in accordance with the
rules laid out in Section 3.5.1.1. This guarantees that there is only one image that can be
automatically loaded from a removable media device by the EFI Boot Manager. Any additional EFI
executables must be in directories other than BOOT. The following is a sample directory structure
for an EFI system partition present on a removable media device.
\EFI
    \BOOT
        BOOT{machine type short name}.EFI
This leads to this question: should the script provide only stanzas for OS loaders or also for other applications like tools, shells, boot managers? Bearing in mind that in an ideal world all OS loaders at least should be accessible from the firmware's menu, but we are not in an ideal work (yet). Maybe include all we can and let the user remove what could be redundant is the way to go?

Last edited by Didier Spaier; 05-12-2018 at 05:12 PM.
 
Old 05-18-2018, 04:51 PM   #14
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Update and plan

Update: I checked that an ESP on an NVMe devices be detected, installing the soon to be released openSUSE 15 in a dedicated NVMe virtual disk in EFI mode.

As an aside I tried this distribution because my friend Martin Brückner who maintains WackoWiki just wrote me that he likes it. Well, I am pleased with Plasma 5.12, not so with the installer that proposed to erase my other systems to make room for openSUSE until I give it the room it wanted on its own device

Status report:

  1. Write the EFI boot manager image. Done
  2. Allow to write a stanza for the boot manager in the firmware's menu. Done, needs testing on bare metal.
  3. Allow to write the EFI boot manager on an USB stick, as a "customized rescue boot manager". WIP.
  4. Allow the user to edit the boot menu, after having checked the entries, so that the labels be more informative. The association between ESP/EFI image path and corresponding label would be stored in a separate file, read by the script when (re)building the EFI boot manager image. TBD
  5. Check that the script be distribution agnostic, (portable, in other words) i.e. that it can be used at least on other Linux distributions, maybe on other at least partially POSIX compliant systems. TBD.
I will request more testing when step 3 and 4 will have been completed.
 
1 members found this post helpful.
Old 06-06-2018, 05:16 PM   #15
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2.1 on Lenovo Thinkpad W520
Posts: 8,518

Original Poster
Rep: Reputation: Disabled
Status report

The new shell script, named EFI3M for "EFI multi-boot menu maker" allow the user to:
  • Build and install the multi-boot menu on a mass storage device attached to the computer, and optionally in its firmware. The boot menu includes an entry for most .efi files found in ESP in all devices attached to the computer.
  • Make a rescue USB stick providing the boot menu.
  • Edit the boot menu: hide boot entries, edit their labels, change their display order.
It works at least on Slackware version 14.2 and Slint64-14.2.1.1.

On second thought (and though I tried hard to make it fully POSIX compliant) I won't try to make this script work on non Slackware-based distributions. Instead I plan to provide an hybrid ISO image, intended to be written on an USB stick, loading a an initramfs allowing to run EFI3M. This will allow to boot all OS installed on the computer on any kind of mass storage device, provided that an EFI boot loader be found for them on the computer. The initramfs won't even need to include GRUB, as BOOTx64.EFI (that weighs just 693K) would be already installed in an ESP of the USB stick, so only a few utilities allowing EFI3M to write and then customize grub.cfg would be necessary.

I will be grateful for comments about this plan but first for testing reports of EFI3M as it is, attached to this post and also stored in http://slint.fr/testing/

I will internationalize EFI3M but as English is not my native language, please do not hesitate to state any typo or bad wording or phrasing of the dialogs and propose enhancements to make the instructions easier to understand and follow.

I attach a few pics, just to give an idea.

PS Saturday 9 June 2018: I have removed the (buggy) file EFI3M.txt that was attached to this post.
Attached Thumbnails
Click image for larger version

Name:	menu_after_customization.png
Views:	21
Size:	8.3 KB
ID:	27831   Click image for larger version

Name:	menu_before_customization.png
Views:	17
Size:	11.8 KB
ID:	27832   Click image for larger version

Name:	menu.png
Views:	17
Size:	26.6 KB
ID:	27833   Click image for larger version

Name:	customization-3.png
Views:	16
Size:	71.0 KB
ID:	27834  

Last edited by Didier Spaier; 06-09-2018 at 04:03 PM. Reason: Removing the attached file, buggy.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to remove from grub2/grub.cfg entries of old non-existing kernels? kaza Fedora 2 03-05-2018 02:46 PM
[SOLVED] Need help managing efi entries jozmak Linux - Newbie 22 07-17-2017 12:12 PM
[SOLVED] Novice script questions: osdetect.cfg, EFI boot EYo Slackware 3 11-22-2014 02:08 AM
3.4 Kernel in testing and EFI stub arubin Slackware 0 11-21-2012 01:44 PM
[SOLVED] Grub can't find grub.cfg when booting - error: no such device Breagha Linux - Software 8 03-14-2010 12:40 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware

All times are GMT -5. The time now is 06:27 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration