Skip to content

Instantly share code, notes, and snippets.

@rstemmer
Created March 20, 2013 16:19
Show Gist options
  • Save rstemmer/5206004 to your computer and use it in GitHub Desktop.
Save rstemmer/5206004 to your computer and use it in GitHub Desktop.
Make GRUB2 to add your Linux From Scratch to the boot-menu. !! READ THE COMMENTS !!
#!/bin/sh
set -e
# Copyright (C) 2013 Ralf Stemmer ([email protected]) #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# INSTALL:
## cp -v ./grubcfg-23_lfs.sh /etc/grub.d/23_lfs
## chmod +x /etc/grub.d/23_lfs
## chmod -x /etc/grub.d/30_os-prober # optional
# how shall I call this OS
OSNAME="Linux From Scratch"
# give some parameters to the kernel
KERNELPARAMETERS="root=/dev/sda3"
# configure GRUB. This will be executed by grub before the kernel gets started
GRUBSETTINGS="load_video
set gfxpayload=keep
insmod part_msdos
insmod ext2
set root='hd0,msdos1'"
# where can I find the boot-partition?
# if it's a directory, the script looks for the kernel inside this directory.
# if it's a device, the script assumes this is the boot-partition and mounts it to PATH_TMPMP
# (you can use redundant paths)
PATH_BOOT=('/mnt/lfs/boot' '/dev/sda1')
#PATH_BOOT=('./fakeboot') # I used this to test the script :)
PATH_TMPMP='/mnt/tmp-42231337' # temporary mountpoint (will be removed after usage)
# Some helper-functions for logging
function print_headline
{
echo -e "\n\e[1;36m$1\e[0m" >> /root/23_lfs.log
}
function print_step
{
echo -e "\e[1;36m - \e[1;34m$1\e[0m" >> /root/23_lfs.log
}
function print_substep
{
echo -e " \e[0;36m · \e[0;36m$1\e[0m" >> /root/23_lfs.log
}
# look for the kernels we want top access with GRUB
print_headline "Preparing for $OSNAME-Boot-Entries"
for x in ${PATH_BOOT[@]} ; do
print_step "Checking $x"
DO_UNMOUNT="false" # true: $x was mounted temporarily, so unmount it
DO_BREAK="false" # true: Everything found, no further searching necessary
# STEP 1: Prepare the directory (mount it if necessary)
if [ -b $x ] ; then
# $x is a device, lets see if it is mounted
SEARCHPATH=$(mount | grep $x | cut -d ' ' -f 3)
# $x seems not to be mounted, so let's mount it
if [ ! -d "$SEARCHPATH" ] ; then
print_substep "Mounting $x temporarily"
SEARCHPATH=$PATH_TMPMP
mkdir $SEARCHPATH
mount $x $SEARCHPATH
DO_UNMOUNT="true"
else
print_substep "$x is mounted to $SEARCHPATH"
fi
elif [ -d $x ] ; then
# $x is a valid path, use it for searching
print_substep "$x is a valid path"
SEARCHPATH=$x
else
print_substep "$x is not a valid path"
print_substep "\e[0;33m$x will be skipped"
continue
fi
# STEP 2: Find all relevant files
# So, now we have to find the files grub needs to boot
# vmlinuz*
# !! NO INITRAMFS SUPPORTED, you may add this by your own if you need it
# You can handle them similar to vmlinuz*
print_substep "Looking for relevant files …"
if [ ! -d $SEARCHPATH ] ; then
print_substep "\e[1;31mInvalid search-path ($SEARCHPATH) - Execution canceled"
exit 1
fi
VMLINUZ=$(find $SEARCHPATH -maxdepth 1 -type f -iname "vmlinuz*" -exec basename {} \; | sort -r)
# so, if we found the files, the loop can be left
if [ "$VMLINUZ" ] ; then
print_substep "\e[0;32mKernels found"
DO_BREAK="true"
fi
# STEP 3: cleaning up
if [ $DO_UNMOUNT == "true" ] ; then
print_substep "Unmounting $x"
umount $x
rmdir $SEARCHPATH
fi
if [ $DO_BREAK == "true" ] ; then
break
fi
done
# just to be sure that everything is as expected during the next steps
if [ -z "$VMLINUZ" ] ; then
print_headline "\e[1;31mNo relevant files found, execution canceled!"
exit 1
fi
# put the list of files into an array
VMLINUZ_ARRAY=(${VMLINUZ// / })
# STEP 4: Create primary menu entry
VMLINUZ_ENTRY=${VMLINUZ_ARRAY[0]} # kernel for this entry
print_step "Create primary entry for $OSNAME with $VMLINUZ_ENTRY"
KERNEL_VERSION=${VMLINUZ_ENTRY#*-}
ENTRYNAME="$OSNAME (Linux $KERNEL_VERSION)"
# GRUBSETTINGS
cat << EOF
menuentry '$ENTRYNAME' --class gnu-linux --class gnu --class os {
$GRUBSETTINGS
echo 'Linux $KERNEL_VERSION wird geladen …'
linux /$VMLINUZ_ENTRY $KERNELPARAMETERS
}
EOF
# STEP 5: Create sub-menu with older kernels
print_step "Create sub-menu for $OSNAME"
ENTRYNAME="Erweiterte Optionen für $OSNAME"
# start of submenu
cat << EOF
submenu '$ENTRYNAME' $menuentry_id_option {
EOF
# remove the latest version, this one was already handled
unset VMLINUZ_ARRAY[0]
# an entry for each kernel-version
for VMLINUZ_ENTRY in ${VMLINUZ_ARRAY[@]}
do
KERNEL_VERSION=${VMLINUZ_ENTRY#*-}
ENTRYNAME="$OSNAME (Linux $KERNEL_VERSION)"
print_substep "Create entry for $OSNAME with $VMLINUZ_ENTRY"
cat << EOF
menuentry '$ENTRYNAME' --class gnu-linux --class gnu --class os {
$GRUBSETTINGS
echo 'Linux $KERNEL_VERSION wird geladen …'
linux /$VMLINUZ_ENTRY $KERNELPARAMETERS
}
EOF
done
# end of submenu
cat << EOF
}
EOF
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment