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