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
szy...@janc.net.pl // 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
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to