Hello,
Attached patch adds support for compressing modules (and locales) with gzip or
xz. /boot/grub size is reduced ~45-55%.
I haven't done any real performance tests but here is short summary from
virtualbox (no gfxmenu and no unicode font) - time measured start after
grub_machine_init() and stop after menu_init() :
no compression: ~980 ms
gzip: ~890 ms
xz: ~950 ms
I must say that results are far better then I've expected. It should be even
more interesting with other compressors - like LZO which is designed for
decompression speed and produces file ~10% larger compared to gzip --best
Please keep in mind that compressed fonts are special use case (random access,
use of bufio) which would require further evaluation and implemenation (pseudo
random access is possible in gzip/xz, but not implemented yet in xzio, didn't
check gzio status) for not being extremely suboptimal. I'll try to adress this
issue in future after some thinking through.
Patch depends on transparent io and xz compression support. (to boot with xz
compression also 07a_xzio_fix.diff is required)
Please test and comment.
--
Szymon K. Janc
[email protected] // GG: 1383435
=== modified file 'util/grub-install.in'
--- util/grub-install.in 2010-04-03 18:52:06 +0000
+++ util/grub-install.in 2010-04-10 20:36:33 +0000
@@ -71,6 +71,7 @@
-h, --help print this message and exit
-v, --version print the version information and exit
--modules=MODULES pre-load specified modules MODULES
+ --compress=COMPRESSOR compress data with COMPRESSOR (gzip or xz)
--root-directory=DIR install GRUB images under the directory DIR
instead of the root directory
--grub-setup=FILE use FILE as grub-setup
@@ -116,6 +117,12 @@
exit 0 ;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
+ --compress=*)
+ compress=`echo "$option" | sed 's/--compress=//'`
+ if [ "$compress" != "xz" ] && [ "$compress" != "gzip" ] ; then
+ echo "Unknown compressor "$compress". Supported: gzip, xz."
+ exit 1
+ fi ;;
--font=*)
font=`echo "$option" | sed 's/--font=//'` ;;
--root-directory=*)
@@ -244,13 +251,69 @@
exit 1
fi
+# Set compressor and decompressor module
+if [ "$compress" = "gzip" ]; then
+ compressor=`whereis -b gzip|cut -c 7-`
+
+ if [ "$compressor" = "" ] ; then
+ echo "Specified gzip compression but gzip binary not found."
+ exit 1
+ fi
+
+ compressor_opt=" --best"
+ compressor_opt_bzj=""
+ decmod="gzio"
+elif [ "$compress" = "xz" ]; then
+ compressor=`whereis -b xz|cut -c 5-`
+
+ if [ "$compressor" = "" ] ; then
+ echo "Specified xz compression but xz binary not found."
+ exit 1
+ fi
+
+ compressor_opt=" --lzma2=dict=64KiB --check=crc32"
+ decmod="xzio"
+
+ if [ "$target_cpu" = "i386" ] || [ "$target_cpu" = "x86_64" ] ; then
+ compressor_opt_bzj=" --x86=start=0"
+ elif [ "$target_cpu" = "powerpc" ] ; then
+ compressor_opt_bzj=" --powerpc=start=0"
+ elif [ "$target_cpu" = "sparc64" ] ; then
+ compressor_opt_bzj=" --sparc=start=0"
+ fi
+
+fi
+
+# Check compressor dependencies.
+find_dep()
+{
+ tmp=`grep ^$1: ${pkglibdir}/moddep.lst|sed s/"$1:"//`
+ if [ "$tmp" = "" ] ; then return ; fi
+ decmod="$decmod $tmp"
+ for i in $tmp ;do find_dep $i ; done
+}
+
+if [ "$decmod" != "" ] ; then
+ find_dep $decmod
+ decmod=`echo $decmod|tr " " "\n"|sort|uniq|tr "\n" " "`
+fi
+
# Copy the GRUB images to the GRUB directory.
for file in ${grubdir}/*.mod ${grubdir}/*.lst ${grubdir}/*.img ${grubdir}/efiemu??.o; do
if test -f $file && [ "`basename $file`" != menu.lst ]; then
rm -f $file || exit 1
fi
done
-for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+for file in ${pkglibdir}/*.mod; do
+ temp=`basename $file .mod`
+ temp=`echo $decmod | tr " " "\n" | grep "^$temp$"`
+ if [ "$compressor" = "" ] || [ "$temp" != "" ] ; then
+ cp -f $file ${grubdir} || exit 1
+ else
+ $compressor $compressor_opt_bcj $compressor_opt $file -c > ${grubdir}/`basename $file` || exit 1
+ fi
+done
+for file in ${pkglibdir}/*.lst; do
cp -f $file ${grubdir} || exit 1
done
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then
@@ -265,7 +328,11 @@
mkdir -p ${grubdir}/locale/
for dir in ${localedir}/*; do
if test -f "$dir/LC_MESSAGES/grub.mo"; then
+ if [ "$compressor" = "" ] ; then
cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo"
+ else
+ $compressor $compressor_opt $dir/LC_MESSAGES/grub.mo -c > ${grubdir}/locale/${dir##*/}.mo
+ fi
fi
done
@@ -299,6 +366,7 @@
modules="$modules $disk_module"
modules="$modules $fs_module $partmap_module $devabstraction_module"
+
relative_grubdir=`make_system_path_relative_to_its_root ${grubdir}` || exit 1
if [ "x${relative_grubdir}" = "x" ] ; then
relative_grubdir=/
@@ -307,6 +375,17 @@
prefix_drive=
config_opt=
+# Remove embed config file.
+rm -f ${grubdir}/load.cfg
+
+if [ "$compress" = "gzip" ]; then
+ config_opt="-c ${grubdir}/load.cfg "
+ echo "insmod gzio" >> ${grubdir}/load.cfg
+elif [ "$compress" = "xz" ]; then
+ config_opt="-c ${grubdir}/load.cfg "
+ echo "insmod xzio" >> ${grubdir}/load.cfg
+fi
+
if [ "x${devabstraction_module}" = "x" ] ; then
if [ x"${install_device}" != x ]; then
if echo "${install_device}" | grep -qx "(.*)" ; then
@@ -327,7 +406,7 @@
echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
exit 1
fi
- echo "search.fs_uuid ${uuid} root " > ${grubdir}/load.cfg
+ echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg
echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg
config_opt="-c ${grubdir}/load.cfg "
modules="$modules search_fs_uuid"
@@ -337,7 +416,7 @@
echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
exit 1
fi
- echo "search.fs_uuid ${uuid} root " > ${grubdir}/load.cfg
+ echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg
echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg
config_opt="-c ${grubdir}/load.cfg "
modules="$modules search_fs_uuid"
_______________________________________________
Grub-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel