mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-21 05:53:14 +00:00
212 lines
3.7 KiB
Bash
Executable File
212 lines
3.7 KiB
Bash
Executable File
#!/bin/sh
|
|
set -e -o pipefail
|
|
bootdir="$1"
|
|
file="$2"
|
|
|
|
if [ -z "$bootdir" -o -z "$file" ]; then
|
|
die "Usage: $0 /boot /boot/grub/grub.cfg"
|
|
fi
|
|
|
|
reset_entry() {
|
|
name=""
|
|
kexectype="elf"
|
|
kernel=""
|
|
initrd=""
|
|
modules=""
|
|
append=""
|
|
}
|
|
|
|
filedir=`dirname $file`
|
|
bootdir="${bootdir%%/}"
|
|
bootlen="${#bootdir}"
|
|
appenddir="${filedir:$bootlen}"
|
|
|
|
fix_path() {
|
|
path="$@"
|
|
if [ "${path:0:1}" != "/" ]; then
|
|
path="$appenddir/$path"
|
|
fi
|
|
}
|
|
|
|
echo_entry() {
|
|
if [ "$kexectype" = "elf" ]; then
|
|
if [ -z "$kernel" ]; then return; fi
|
|
|
|
fix_path $kernel
|
|
entry="$name|$kexectype|kernel $path"
|
|
if [ -n "$initrd" ]; then
|
|
for init in $(echo $initrd | tr ',' ' '); do
|
|
fix_path $init
|
|
entry="$entry|initrd $path"
|
|
done
|
|
fi
|
|
if [ -n "$append" ]; then
|
|
entry="$entry|append $append"
|
|
fi
|
|
|
|
echo $(eval "echo \"$entry\"")
|
|
fi
|
|
if [ "$kexectype" = "multiboot" -o "$kexectype" = "xen" ]; then
|
|
if [ -z "$kernel" ]; then return; fi
|
|
|
|
fix_path $kernel
|
|
echo $(eval "echo \"$name|$kexectype|kernel $path$modules\"")
|
|
fi
|
|
}
|
|
|
|
search_entry() {
|
|
case $line in
|
|
menuentry* | MENUENTRY* )
|
|
state="grub"
|
|
reset_entry
|
|
name=`echo $line | tr "'" "\"" | cut -d\" -f 2`
|
|
;;
|
|
|
|
label* | LABEL* )
|
|
state="syslinux"
|
|
reset_entry
|
|
name=`echo $line | cut -c6- `
|
|
esac
|
|
}
|
|
|
|
grub_entry() {
|
|
if [ "$line" = "}" ]; then
|
|
echo_entry
|
|
state="search"
|
|
return
|
|
fi
|
|
|
|
# add info to menuentry
|
|
trimcmd=`echo $line | tr '\t ' ' ' | tr -s ' '`
|
|
cmd=`echo $trimcmd | cut -d\ -f1`
|
|
val=`echo $trimcmd | cut -d\ -f2-`
|
|
case $cmd in
|
|
multiboot*)
|
|
# TODO: differentiate between Xen and other multiboot kernels
|
|
kexectype="xen"
|
|
kernel="$val"
|
|
;;
|
|
module*)
|
|
case $val in
|
|
--nounzip*) val=`echo $val | cut -d\ -f2-` ;;
|
|
esac
|
|
fix_path $val
|
|
modules="$modules|module $path"
|
|
;;
|
|
linux*)
|
|
kernel=`echo $trimcmd | cut -d\ -f2`
|
|
append=`echo $trimcmd | cut -d\ -f3-`
|
|
;;
|
|
initrd*)
|
|
initrd="$val"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
syslinux_end() {
|
|
# finish menuentry
|
|
|
|
# attempt to parse out of append if missing initrd
|
|
if [ -z "$initrd" ]; then
|
|
newappend=""
|
|
for param in $append; do
|
|
case $param in
|
|
initrd=*)
|
|
initrd=`echo $param | cut -d\= -f2`
|
|
;;
|
|
*) newappend="$newappend $param" ;;
|
|
esac
|
|
done
|
|
append="${newappend##' '}"
|
|
fi
|
|
|
|
appenddir="$(echo $appenddir | cut -d\/ -f -2)"
|
|
echo_entry
|
|
state="search"
|
|
}
|
|
|
|
syslinux_multiboot_append() {
|
|
splitval=`echo "${val// --- /|}" | tr '|' '\n'`
|
|
while read line
|
|
do
|
|
if [ -z "$kernel" ]; then
|
|
kernel="$line"
|
|
else
|
|
fix_path $line
|
|
modules="$modules|module $path"
|
|
fi
|
|
done << EOF
|
|
$splitval
|
|
EOF
|
|
}
|
|
|
|
syslinux_entry() {
|
|
case $line in
|
|
"")
|
|
syslinux_end
|
|
return
|
|
;;
|
|
label* | LABEL* )
|
|
syslinux_end
|
|
search_entry
|
|
return
|
|
;;
|
|
esac
|
|
|
|
# add info to menuentry
|
|
trimcmd=`echo $line | tr '\t ' ' ' | tr -s ' '`
|
|
cmd=`echo $trimcmd | cut -d\ -f1`
|
|
val=`echo $trimcmd | cut -d\ -f2-`
|
|
case $trimcmd in
|
|
menu* | MENU* )
|
|
cmd2=`echo $trimcmd | cut -d \ -f2`
|
|
if [ "$cmd2" = "label" -o "$cmd2" = "LABEL" ]; then
|
|
name=`echo $trimcmd | cut -c11- | tr -d '^'`
|
|
fi
|
|
;;
|
|
linux* | LINUX* | kernel* | KERNEL* )
|
|
case $val in
|
|
# TODO: differentiate between Xen and other multiboot kernels
|
|
*mboot.c32) kexectype="xen" ;;
|
|
*.c32)
|
|
# skip this entry
|
|
state="search"
|
|
;;
|
|
*)
|
|
kernel="${val#"$bootdir"}"
|
|
esac
|
|
;;
|
|
initrd* | INITRD* )
|
|
initrd="${val#"$bootdir"}"
|
|
;;
|
|
append* | APPEND* )
|
|
if [ "$kexectype" = "multiboot" -o "$kexectype" = "xen" ]; then
|
|
syslinux_multiboot_append
|
|
else
|
|
append="$val"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
state="search"
|
|
while read line
|
|
do
|
|
case $state in
|
|
search)
|
|
search_entry
|
|
;;
|
|
grub)
|
|
grub_entry
|
|
;;
|
|
syslinux)
|
|
syslinux_entry
|
|
;;
|
|
esac
|
|
done < "$file"
|
|
|
|
# handle EOF case
|
|
if [ "$state" = "syslinux" ]; then
|
|
syslinux_end
|
|
fi
|