diff options
author | wiktor w brodlo <wiktor@brodlo.net> | 2011-07-07 22:41:09 +0000 |
---|---|---|
committer | wiktor w brodlo <wiktor@brodlo.net> | 2011-07-07 22:41:09 +0000 |
commit | f1a49dbf6383678d9672f3c122e1e5415e6c3be0 (patch) | |
tree | 28a536506d725870437bc5ec3c0899dd14bac90a /sys-boot/grub | |
parent | the libuser patch (diff) | |
download | anaconda-overlay-f1a49dbf6383678d9672f3c122e1e5415e6c3be0.tar.gz anaconda-overlay-f1a49dbf6383678d9672f3c122e1e5415e6c3be0.tar.bz2 anaconda-overlay-f1a49dbf6383678d9672f3c122e1e5415e6c3be0.zip |
GRUB2 from Sabayon
Diffstat (limited to 'sys-boot/grub')
50 files changed, 9891 insertions, 0 deletions
diff --git a/sys-boot/grub/Manifest b/sys-boot/grub/Manifest new file mode 100644 index 0000000..f46c98d --- /dev/null +++ b/sys-boot/grub/Manifest @@ -0,0 +1,53 @@ +AUX 00_fonts 462 RMD160 828b03d1201aa8b8abe339305ff4e2a8b99d1d33 SHA1 fcdaf4ac95ca318750c33153be993dac0e9c8c99 SHA256 fbe13c4e5373835fb529c6c9454ac07a3e523bd56529483d0ec86f9583ae8fed +AUX 05_distro_theme 1180 RMD160 ee8d8707e07dbf9877be5bbc9322263822d4ddad SHA1 ad9fb101b7f959ca2392d404a86bec299f326c88 SHA256 cff76aaf874da7270265eca015ffada92f30609699f8cc956a4df0c480a9a5fc +AUX default-splash-5.4.png 641815 RMD160 175bf793a542654e765fecca89f6c628e7a8a586 SHA1 a8ceabcef3854517d879522ab5155540ddeca3d9 SHA256 f9eedc888fd11d899000397f073d042ce5a4230923966f9d12828263f0a2d14a +AUX default-splash-6.png 1006813 RMD160 9c00ed318f4b40486289b1bcf9d7d085d5d9c67c SHA1 aea9184f94b7c60deef172e730b5aada5fe209de SHA256 27da12fccce3fc4a40724471b9ebd4c2fed30c743fcd049a4c53963f87e17e24 +AUX default-splash.png 379111 RMD160 c399047d7d63e72495416f0f25cdc4c7bcc38946 SHA1 d0e6e920e4ce973c460d4bb994e4a87e2e32e8aa SHA256 09de78447d236669252b4669a341b5589043466bcb6bbf80e334462024c655c8 +AUX grub-0.97-gfxmenu-v8.patch 23313 RMD160 ee79292a61a4fcbfa2afe5bea56e56ee4efbfe01 SHA1 b4e567009e61e9bc6a2e60bae3333681c458debc SHA256 c2f7897027842631a95a654e7978d43e6d21d8c06426ff2d966678e3fca0ba4a +AUX grub-0.97-uuid.patch 144339 RMD160 58816e0fc819a0c5afc2da0024611ec650119be2 SHA1 9b5a0fb112eaf143b8b81f487b3b515a13423372 SHA256 9766e446665a955e2dab10e5e42d83b3384b5e6e306c3eba70a08f35a3fbf129 +AUX grub-0.97-uuid_doc.patch 1364 RMD160 667f9e91ed037cac61a00e2ea4dda5d94ad4369c SHA1 1b12abc7270624c8192bdc692264584eea947e9a SHA256 371ca0229b5036071f418f4ca3d8b724b2ea8719954edadbf4ddfa4e937a089b +AUX grub-1.96-genkernel.patch 634 RMD160 bc1fdaa51e3f0e3b777a303e0f1c76987c7e69e5 SHA1 e79384a3ac32bfd74c884ead8133b1691a743316 SHA256 8ee327465d9b6d704a78b0c7b31cfdee7c6e7e9f9897e8d0a86198430f0c6ea0 +AUX grub-1.97-genkernel.patch 998 RMD160 7b52c250c821f4c57c61a11d5f1f430795521b20 SHA1 30e4612a70a3bda444f29f3de35e838ed2c2c9e4 SHA256 a0cfc467d85e50108fbb9f2d76de24db0557e53aadb7afd8562404c138548625 +AUX grub-1.97-hostdisk.patch 1840 RMD160 bb6ea6dc165e12e3af61bcc159dafdbd9d439370 SHA1 478bf182c4d5371b8e08d50d47b318fc5e99d49a SHA256 dec80ac94b7e3d7ececca3e11b2afc9f65f8ce38ca27091d13b81484eae3ef57 +AUX grub-1.97-vga-deprecated.patch 477 RMD160 7cbdb7fad80b409f3939e728131e368b08cf0766 SHA1 a77497bd36c28221a7cc166dc1130b404fe05aa2 SHA256 2a95589c2967f3991289fe86bd3697fdd6f43282226a6ac5947b546c49ca2e00 +AUX grub-1.97-wallpaper-settings-support.patch 545 RMD160 701b01fbd760bc6413570d4399f5eb929005d81d SHA1 e599af9cfeefff585c9e2bce064ad988145dc2eb SHA256 8d9415fb6bbde2563f7713291396cef226f83a7c95d0ed86124e582463c04f3f +AUX grub-1.98-add-legacy-rootfs-detection.patch 2250 RMD160 684cd457b26e25ace6a5e725a69d815ac356c098 SHA1 282c6df94df7e0daf5c7f29525fb2095d11a45ee SHA256 bc337f2cea948ab385a2085d08e6ed92434bfef4ad3b8100fa58efd910d2aefe +AUX grub-1.98-follow-dev-mapper-symlinks.patch 793 RMD160 fe6ab74c302555e434c6e0c69022ba93c6b5ed4e SHA1 4f4e2f4b59d231566b63e611ae0d1cbb4b76d143 SHA256 82227c1fc973c2b075a222bc7b4d0a7bc4a59143a170e04090a27a7950080dd4 +AUX grub-1.98-genkernel-initramfs-single.patch 457 RMD160 62d63c5cbeffa7b1323964818253b4b14f6bdbee SHA1 d56ed964a8250928dd39a844f9950cc924988322 SHA256 6c95716ebd62fb1710ae86ee65bba159c90f2468b0af4e4bb63cb18dea2ac430 +AUX grub-1.98-genkernel.patch 1095 RMD160 597ea9c38f52f3f733fb68c2b8e7951e14cd6963 SHA1 afd82815bd292f517d9aa56128ee321fdc2071f9 SHA256 ef07667e5601a3dcf0e26e639b0a3acbf03484effe182aec16afdfebcdd110fc +AUX grub-1.98-wallpaper-settings-support.patch 520 RMD160 49bc8578c63aa6294e9bbad53d98a7460135a539 SHA1 ba4ea49dc6b8e70ee6ef12ba5b4be91fed608765 SHA256 605a922190a848bf2c68c2e8ff9d425b792758739c25f739d0ab4ffe8dcddbf1 +AUX grub-1.99-disable-floppies.patch 763 RMD160 a169a6e23e20e42b681a21e0c448d94d18661334 SHA1 49db692f53ecf5e4a682ca4d73d0c41117151f11 SHA256 b1bebdc1fd62534b05907a9aaab2571be05047321320f9a8afece875225d6d5d +AUX grub-1.99-genkernel.patch 433 RMD160 36be73354333ba3ea6ef7b25d4d55e889d21aba5 SHA1 a4e1a2a3635778387737316156c30370a2200d5c SHA256 368171fa84d446c93479973013105f2eab9eaf0e407b37693e491b4492618880 +AUX grub-1.99-vga-deprecated-not-yet.patch 575 RMD160 21f930d2ac90da42a52e95a8ed6fb07925b41554 SHA1 9efe1ecb47ee3882ba7bd635e4108da8df07f8d5 SHA256 d16821ea7c2bc49f16912880d0d5a32d3a517893d4ca339acdb845259902a820 +AUX grub-1.99-vga-deprecated.patch 408 RMD160 8b2c8560d8bf39bc06a110eaa81a388c3fd49b42 SHA1 7e7f196b86c6d8634e3889881687f5d303fa3d5e SHA256 55dd23c6a6a862a045b71e6dd564c76df08086af0d05a16311f46cc1a5f7941a +AUX grub-1.99-wallpaper-settings-support.patch 521 RMD160 5a47c70dfc686a3741f99e4aad475f30c38a6876 SHA1 e70335fb11e92a182462f92866bf31324d070c34 SHA256 d21265645972e57278341cd27b1406f9f630f94cc1722374832cca95453ce807 +AUX grub-1.99-workaround-raid-bios-bug.patch 808 RMD160 749e9eacf6cb9c58274b77720650d77a86cd3604 SHA1 60fde97e779e940207376723535ad523b92a0531 SHA256 011c480d2001e37a8b7a347ddabe072c5c912932deda016badeeb1e57a6f63d6 +AUX grub.conf.gentoo 627 RMD160 d90fb4373bad476f98ec9c5065d6cdfd9e3b706f SHA1 004f2fc04605ec9190de0a87e7df8bbc33daff89 SHA256 914b15af252210a32776196437cd8013e10e57d5780e66877ef3fe9a2b4b9776 +AUX grub2-default 2084 RMD160 1a7ed37eeda753b279c6f6d864d9122d439631da SHA1 c2f697c4c525c50931b8f00864af0a9249c08777 SHA256 df286f514070ba4e4ee70a65f7f68a7103ffba4d230fb1dc99f9667515a9ca16 +AUX grub2-default-1.99 2113 RMD160 2ad38a800e66d7cb904b77e0167f4da51e390b0d SHA1 4b191d88d42e865d3efa882601da52ad6ace62be SHA256 b6e255a0e4127709e92d4049b23295feab6c026e7945b3b0ec4f675d9058a45e +AUX splash.xpm.gz 6251 RMD160 d7b6f187c45597dab59415163fc9d0c154d40cbe SHA1 3b8615b6e105fcbcd6530b46947e06d480caa8f4 SHA256 46397f66ab9dbb2215d5191d94e6ca5aecb53f84ad70cc17aeb319353ba201b2 +AUX ubuntu-upstream-1.98/01_uuids_and_lvm_dont_play_along_nicely.diff 611 RMD160 0269ad21a4e5723383b2f04670088cc6b1a1e636 SHA1 344e63b80d9e3d057d41bc50e980a1b1c311a426 SHA256 282635fd75266dfe9222afc892f02a9f9fbc227f05556054531fb63704f9cd55 +AUX ubuntu-upstream-1.98/902_boot_blocklist_hack.diff 590 RMD160 12856f69930dc7783cf4184cc431e43d91f83b49 SHA1 941ed1934cf60c3564da010cd975248b92e321f4 SHA256 27466e25257cc267b0048086ae0ad76aa07bd703fa1827342c83b11bff843b84 +AUX ubuntu-upstream-1.98/904_disable_floppies.diff 743 RMD160 bc98e9c85245edac6c666f0eeca51da2b6b9cfb6 SHA1 bdba3cfe65b73c86ab3e74858a6baa3f8b20cf1e SHA256 930b1d38af76e477d4c0d9e357441882da3367fbe107561aa7fc25e8ccad2a80 +AUX ubuntu-upstream-1.98/956_loopback_root.diff 3893 RMD160 cd235a733fd209fc4a4ead82756b5dd3765fd97c SHA1 f47642fd61690ade9096ca170e8dfe6c81315df7 SHA256 aff4cb00a6915749a31441fd777b23328647fbad52095cf2eb9cf313af45f0e3 +AUX ubuntu-upstream-1.98/957_handle_loopback.diff 1601 RMD160 601da4911f5929ad44eea07cf78928b145f5d8d1 SHA1 01d03179ada50ee744f06d2f175d7966efc1c06d SHA256 64f735f93dd08f67042e8159af11653095a6707efa3cccc21ea8b0bd6078e7ec +AUX ubuntu-upstream-1.98/958_linux_no_loopmount.diff 772 RMD160 05d5f158c5280a1ee9e7961d4f3069aacb7ca632 SHA1 7bb9547c634b5f9c44106cb43b9d843efc49e442 SHA256 aea5604df288a1809d406321200c5f4de13c04c5af91610b6b89a09add11ba37 +AUX ubuntu-upstream-1.98/960_raid_virtio.diff 4372 RMD160 76cc430483034d1821ec285f4799b4f841649401 SHA1 10904dce33757f4bcdbb0c7451106ef88bd453a4 SHA256 9ebb1ab4caaf72303ee6ab309bd0117674d20d15358f8f91800abd714555baf0 +AUX ubuntu-upstream-1.98/961_dmraid_probe.diff 17773 RMD160 ebdece5470a4f2248d5ccf086543d607092a205a SHA1 8e342077cc26c4185896729da5482070be0be973 SHA256 0c068a31fb30f139f9284d0b2df8334e07cf49a3912da9327278e3085f7fa2ff +AUX ubuntu-upstream-1.98/962_no_device_map.diff 3556 RMD160 3c5ab122095e4ead78ba4504ff00b84277fa3f79 SHA1 9bf10e7e2f99ef6f41f901af10c3b6383bd8b371 SHA256 69d9dbb92fb7b05bb2441265d4fd9d592296dd85754212f7e9f3dfcf7e11d13f +AUX ubuntu-upstream-1.98/968_hostdisk_speedup.diff 9928 RMD160 abfd47d57a3f7dbd4d9e4f1e6f679402c6891128 SHA1 e6a7d804139d5d1e8cd7f303a53bd37b6b83d02b SHA256 2ad5578356748f85c3bdaa24214613f2f061619ae4ea8e3db2fa1aeffe481f11 +AUX ubuntu-upstream-1.98/969_lvm_raid_probe.diff 7890 RMD160 3d109278f3fdc5e24cbc8d8a6a6a5403e128a91f SHA1 6c53f1d1720ce70d82da2f6b525340b0b764396d SHA256 207a4ebafdead64387bca3a071465dcabb6179b3cfdc179965c4530ad571f1d2 +AUX ubuntu-upstream-1.98/970_fix_locale_installation.diff 2332 RMD160 91465a322dc4fe64110b00c48e8364615b0dc8db SHA1 50489d6de1276e16970dce9fac894e5983f9be5d SHA256 b748151f4e16862136ac0f74604259a146ee9329043193230d44e9570e810456 +AUX ubuntu-upstream-1.98/971_langpacks.diff 1266 RMD160 a9dc3b8c32a4903b8cf8c3b0f65b538b46749100 SHA1 29c681dd01942760f078f889cb9bf66a8a2a24c6 SHA256 c2ec2b37b5fbdd10214150659bca41c3dc016d75060e17d36f191af314222bc5 +AUX ubuntu-upstream-1.98/974_drive_probe.diff 959 RMD160 639eb5037c1e1e6e3bb58282dc7dd41333a6a7a5 SHA1 1698d3366e2aeb7aeca906059544d955744dd071 SHA256 4e73d0330b5093f48151e65d7bf12bb2a968d6ecfeccf0bdc97a48000cb43b03 +AUX ubuntu-upstream-1.98/975_hostdisk_hd.diff 4125 RMD160 bc514a49151ca9e155be5bea0974dd564c922f8b SHA1 1bda370ec48ee6660fa6b8ed2c9eaf3c2a84504d SHA256 0c53c9ab6d161c316a0f0d0e9476004f66e44d664c95e23c6324ef821b2970a9 +AUX ubuntu-upstream/01_uuids_and_lvm_dont_play_along_nicely.diff 611 RMD160 0269ad21a4e5723383b2f04670088cc6b1a1e636 SHA1 344e63b80d9e3d057d41bc50e980a1b1c311a426 SHA256 282635fd75266dfe9222afc892f02a9f9fbc227f05556054531fb63704f9cd55 +AUX ubuntu-upstream/904_disable_floppies.diff 743 RMD160 bc98e9c85245edac6c666f0eeca51da2b6b9cfb6 SHA1 bdba3cfe65b73c86ab3e74858a6baa3f8b20cf1e SHA256 930b1d38af76e477d4c0d9e357441882da3367fbe107561aa7fc25e8ccad2a80 +DIST grub-0.97-patches-1.9.tar.bz2 51809 RMD160 a745902212dbd22f4d9f0bb0d563ffd44b429eaa SHA1 1d9da2df8bccef9821ebbbc2f5c5353dbd90bf4d SHA256 6b8445c9260803f059031cbe7475a45fee6499fc2dbd911288af6169455c4028 +DIST grub-0.97.tar.gz 971783 RMD160 7fb5674edf0c950bd38e94f85ff1e2909aa741f0 SHA1 2580626c4579bd99336d3af4482c346c95dac4fb SHA256 4e1d15d12dbd3e9208111d6b806ad5a9857ca8850c47877d36575b904559260b +DIST grub-1.98.tar.gz 2449386 RMD160 197fb8d7c673bd67ae81eda53a2baa2968cc1e69 SHA1 e83a2c438f4773a2e272c225983c0145e1ffd641 SHA256 bef2c1892e052967b65aab6aa62ac702c0e50ef8848506eacf3c0b2f5007c614 +DIST grub-1.99.tar.xz 2639224 RMD160 d59a47fa40b2be0d5ea5b2b00ff5538cfa147747 SHA1 a5ae9558f30ce7757a76aa130088b053a87e2fb6 SHA256 f308148d4c83c6f16a73b58a0cd39381656edb740929028cae7ad5f0d651021b +EBUILD grub-0.97-r22.ebuild 7588 RMD160 86e8c77ec7ee193919bdec359e53a8236a4b4c77 SHA1 212944ff569048769c15fd6676a63e6eea4c0cef SHA256 ff5b303cedd5a05c39f8903fbfb215512ab58f12ff023773d739eb3fa244f8bd +EBUILD grub-1.98-r10.ebuild 3654 RMD160 872a03a3073ca18bc853048b65159af52495c915 SHA1 1cb89aa08a8265a97834964661999cfe93c99b6b SHA256 875e175940856ef613be27a65f136772a366c93289100abc07cb083333ae46df +EBUILD grub-1.98-r9.ebuild 3799 RMD160 70067983c5394c5f2f876e8be18eee97bf1dd4dd SHA1 149c73a384e913b0d27b7fee61d4d0110cf0eb34 SHA256 271d79ea8be44a6aeebcf9af6676a2c90c4ec43120882225a5b5b8fe3ba4f6d5 +EBUILD grub-1.99.ebuild 7808 RMD160 0fa7ce32a511cf50f19f1fbda105895481dab7b3 SHA1 84442136e82509c963ee7ce390be794368f9fee7 SHA256 be84ddee0a8b02572b5b201afd4cd250fffe80f25a4524ce33c6e1dc7cf1cda2 diff --git a/sys-boot/grub/files/00_fonts b/sys-boot/grub/files/00_fonts new file mode 100755 index 0000000..d2dcbaf --- /dev/null +++ b/sys-boot/grub/files/00_fonts @@ -0,0 +1,14 @@ +# Create required fonts, otherwise graphic mode won't be loaded +if [ -x "/bin/grub-mkfont" ]; then + # This is the bare minimum + grub-mkfont --output=/boot/grub/unifont.pf2 \ + /usr/share/fonts/unifont/unifont.pcf.gz + + # let's load DejaVu if exists, no deps against it + # to avoid crazy deps on critical pkg + if [ -x "/usr/share/fonts/dejavu/DejaVuSans.ttf" ]; then + grub-mkfont --output=/boot/grub/dejavu.pf2 \ + /usr/share/fonts/dejavu/DejaVuSans.ttf + fi + +fi diff --git a/sys-boot/grub/files/05_distro_theme b/sys-boot/grub/files/05_distro_theme new file mode 100644 index 0000000..cb4c197 --- /dev/null +++ b/sys-boot/grub/files/05_distro_theme @@ -0,0 +1,51 @@ +#!/bin/bash -e + +. /lib/grub/grub-mkconfig_lib + +set_blue_theme() +{ + cat << EOF +set menu_color_normal=cyan/blue +set menu_color_highlight=white/blue +EOF +} + +# check for usable backgrounds +use_bg=false +if [ "$GRUB_TERMINAL_OUTPUT" = "gfxterm" ] && [ -n "${GRUB_WALLPAPER}" ]; then + for i in /boot/grub/`basename ${GRUB_WALLPAPER}` ${GRUB_WALLPAPER} ; do + if is_path_readable_by_grub $i ; then + bg=$i + case ${bg} in + *.png) reader=png ;; + *.tga) reader=tga ;; + *.jpg|*.jpeg) reader=jpeg ;; + esac + if test -e /boot/grub/${reader}.mod ; then + echo "Found background image: `basename ${bg}`" >&2 + use_bg=true + break + fi + fi + done +fi + +# set the background if possible +if ${use_bg} ; then + prepare_grub_to_access_device `${grub_probe} --target=device ${bg}` + cat << EOF +insmod ${reader} +if background_image `make_system_path_relative_to_its_root ${bg}` ; then + set color_normal=${GRUB_COLOR_NORMAL} + set color_highlight=${GRUB_COLOR_HIGHLIGHT} +else +EOF +fi + +# otherwise, set the traditional Debian blue theme +if ${use_bg} ; then + set_blue_theme | sed -e "s/^/ /g" + echo "fi" +else + set_blue_theme +fi diff --git a/sys-boot/grub/files/default-splash-5.4.png b/sys-boot/grub/files/default-splash-5.4.png Binary files differnew file mode 100644 index 0000000..2197887 --- /dev/null +++ b/sys-boot/grub/files/default-splash-5.4.png diff --git a/sys-boot/grub/files/default-splash-6.png b/sys-boot/grub/files/default-splash-6.png Binary files differnew file mode 100644 index 0000000..6e61b40 --- /dev/null +++ b/sys-boot/grub/files/default-splash-6.png diff --git a/sys-boot/grub/files/default-splash.png b/sys-boot/grub/files/default-splash.png Binary files differnew file mode 100644 index 0000000..263b1ee --- /dev/null +++ b/sys-boot/grub/files/default-splash.png diff --git a/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch b/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch new file mode 100644 index 0000000..7921fc8 --- /dev/null +++ b/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch @@ -0,0 +1,1003 @@ +diff -Nurp grub-0.97.orig/docs/grub.texi grub-0.97/docs/grub.texi +--- grub-0.97.orig/docs/grub.texi 2009-08-03 16:25:36.636294219 +0200 ++++ grub-0.97/docs/grub.texi 2009-08-03 16:25:52.207398764 +0200 +@@ -2118,6 +2118,7 @@ These commands can only be used in the m + * default:: Set the default entry + * fallback:: Set the fallback entry + * hiddenmenu:: Hide the menu interface ++* gfxmenu:: Use graphical menu interface + * timeout:: Set the timeout + * title:: Start a menu entry + @end menu +@@ -2150,6 +2151,15 @@ fallback entry numbers. + @end deffn + + ++@node gfxmenu ++@subsection gfxmenu ++ ++@deffn Command gfxmenu file ++Use the graphical menu interface. The graphics data are taken from ++@var{file} and must be created using 'mkbootmsg' from the gfxboot package. ++@end deffn ++ ++ + @node hiddenmenu + @subsection hiddenmenu + +diff -Nurp grub-0.97.orig/grub/asmstub.c grub-0.97/grub/asmstub.c +--- grub-0.97.orig/grub/asmstub.c 2009-08-03 16:25:36.483169221 +0200 ++++ grub-0.97/grub/asmstub.c 2009-08-03 16:25:52.217342924 +0200 +@@ -480,6 +480,32 @@ set_vbe_mode (int mode_number) + return 0; + } + ++/* graphical menu functions . */ ++int ++gfx_init (gfx_data_t *gfx_data) ++{ ++ return 0; ++} ++ ++int ++gfx_done (gfx_data_t *gfx_data) ++{ ++ return 0; ++} ++ ++int ++gfx_input (gfx_data_t *gfx_data, int *menu_entry) ++{ ++ return 0; ++} ++ ++int ++gfx_setup_menu (gfx_data_t *gfx_data) ++{ ++ return 0; ++} ++ ++ + /* low-level timing info */ + int + getrtsecs (void) +diff -Nurp grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S +--- grub-0.97.orig/stage2/asm.S 2004-06-19 18:55:22.000000000 +0200 ++++ grub-0.97/stage2/asm.S 2009-08-03 16:25:52.218406926 +0200 +@@ -1610,6 +1610,286 @@ ENTRY(set_vbe_mode) + popl %ebp + ret + ++ ++/* ++ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++ * ++ * graphical menu functions ++ * ++ */ ++ ++/* ++ * int gfx_init (gfx_data_t *gfx_data) ++ * ++ * init gfx things ++ * ++ * return vales: ++ * 0: ok ++ * 1: failed ++ * sets gfx_data->ok ++ */ ++ ++ENTRY(gfx_init) ++ pushl %ebp ++ movl %esp, %ebp ++ ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ ++ movl 8(%ebp),%edx ++ movl %edx,%edi ++ leal gfx_ofs_sys_cfg(%edx),%esi ++ andl $0xf,%edi ++ shrl $4,%edx ++ ++ pushl %ebp ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ pushw %ds ++ movw %dx,%ds ++ ++ lcall *gfx_ofs_jmp_table + 4 * 0 (%di) ++ ++ sbbl %ebx,%ebx ++ negl %ebx ++ ++ popw %ds ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ popl %ebp ++ ++ movl %ebx,%eax ++ xorl $1,%ebx ++ movl 8(%ebp),%edx ++ movl %ebx,gfx_ofs_ok(%edx) ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ++ popl %ebp ++ ret ++ ++ ++/* ++ * int gfx_done (gfx_data_t *gfx_data) ++ * ++ * shut down gfx things ++ * ++ * return vales: ++ * always 0 ++ * sets gfx_data->ok ++ */ ++ ++ENTRY(gfx_done) ++ pushl %ebp ++ movl %esp, %ebp ++ ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ ++ movl 8(%ebp),%edx ++ movl %edx,%ebx ++ andl $0xf,%ebx ++ shrl $4,%edx ++ ++ pushl %ebp ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ pushw %ds ++ ++ movw %dx,%ds ++ ++ lcall *gfx_ofs_jmp_table + 4 * 1 (%bx) ++ ++ popw %ds ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ popl %ebp ++ ++ xorl %eax,%eax ++ movl 8(%ebp),%edx ++ movl %eax,gfx_ofs_ok(%edx) ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ++ popl %ebp ++ ret ++ ++ ++/* ++ * int gfx_input (gfx_data_t *gfx_data, int *menu_entry) ++ * ++ * let user enter a command line ++ * ++ * uses gfx_data->cmdline as buffer ++ * ++ * return values: ++ * 1: abort ++ * 2: boot ++ * menu_entry: selected entry ++ */ ++ ++ENTRY(gfx_input) ++ pushl %ebp ++ movl %esp, %ebp ++ ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ ++ movl 8(%ebp),%edx ++ movl %edx,%ebx ++ leal gfx_ofs_sys_cfg(%edx),%esi ++ andl $0xf,%ebx ++ shrl $4,%edx ++ ++ pushl %ebp ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ pushw %ds ++ ++ movw %dx,%ds ++ ++ movl gfx_ofs_cmdline(%bx),%edi ++ movl gfx_ofs_cmdline_len(%bx),%ecx ++ movl gfx_ofs_timeout(%bx),%eax ++ imull $18,%eax ++ ++ lcall *gfx_ofs_jmp_table + 4 * 2 (%bx) ++ ++ movl %eax,%ecx ++ ++ popw %ds ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ popl %ebp ++ ++ movl 12(%ebp),%edx ++ movl %ebx,(%edx) ++ ++ movl %ecx,%eax ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ++ popl %ebp ++ ret ++ ++ ++/* ++ * int gfx_setup_menu (gfx_data_t *gfx_data) ++ * ++ * draw boot menu ++ * ++ * return values: ++ * always 0 ++ */ ++ ++/* menu entry descriptor */ ++#define menu_entries 0 ++#define menu_default 2 /* seg:ofs */ ++#define menu_ent_list 6 /* seg:ofs */ ++#define menu_ent_size 10 ++#define menu_arg_list 12 /* seg:ofs */ ++#define menu_arg_size 16 ++#define sizeof_menu_desc 18 ++ ++ENTRY(gfx_setup_menu) ++ pushl %ebp ++ movl %esp, %ebp ++ ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ ++ movl 8(%ebp),%edx ++ movl %edx,%ebx ++ andl $0xf,%ebx ++ shrl $4,%edx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ pushw %ds ++ ++ movw %dx,%ds ++ shll $4,%edx ++ ++ subw $sizeof_menu_desc,%sp ++ movw %esp,%ebp ++ ++ movl gfx_ofs_menu_entries(%bx),%eax ++ movw %ax,menu_entries(%bp) ++ ++ movl gfx_ofs_menu_default_entry(%bx),%eax ++ subl %edx,%eax ++ movw %ax,menu_default(%bp) ++ movw %ds,menu_default+2(%bp) ++ ++ movl gfx_ofs_menu_list(%bx),%eax ++ subl %edx,%eax ++ movw %ax,menu_ent_list(%bp) ++ movw %ds,menu_ent_list+2(%bp) ++ ++ movl gfx_ofs_menu_entry_len(%bx),%eax ++ movw %ax,menu_ent_size(%bp) ++ ++ movl gfx_ofs_args_list(%bx),%eax ++ subl %edx,%eax ++ movw %ax,menu_arg_list(%bp) ++ movw %ds,menu_arg_list+2(%bp) ++ ++ movl gfx_ofs_args_entry_len(%bx),%eax ++ movw %ax,menu_arg_size(%bp) ++ ++ movl %ss,%esi ++ shll $4,%esi ++ addl %ebp,%esi ++ ++ lcall %ds: *gfx_ofs_jmp_table + 4 * 3 (%bx) ++ ++ addw $sizeof_menu_desc,%sp ++ ++ popw %ds ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax,%eax ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ++ popl %ebp ++ ret ++ ++ ++/* ++ * ++ * end graphics stuff ++ * ++ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++ */ ++ + + /* + * gateA20(int linear) +diff -Nurp grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c +--- grub-0.97.orig/stage2/builtins.c 2009-08-03 16:25:36.601273171 +0200 ++++ grub-0.97/stage2/builtins.c 2009-08-03 16:25:52.219523396 +0200 +@@ -67,6 +67,8 @@ int fallback_entryno; + int fallback_entries[MAX_FALLBACK_ENTRIES]; + /* The number of current entry. */ + int current_entryno; ++/* graphics file */ ++char graphics_file[64]; + /* The address for Multiboot command-line buffer. */ + static char *mb_cmdline; + /* The password. */ +@@ -1335,6 +1337,26 @@ static struct builtin builtin_fstest = + }; + + ++/* graphics */ ++static int ++gfxmenu_func (char *arg, int flags) ++{ ++ memmove(graphics_file, arg, sizeof graphics_file - 1); ++ graphics_file[sizeof graphics_file - 1] = 0; ++ ++ return 0; ++} ++ ++static struct builtin builtin_gfxmenu = ++{ ++ "gfxmenu", ++ gfxmenu_func, ++ BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "gfxmenu FILE", ++ "Use the graphical menu from FILE." ++}; ++ ++ + /* geometry */ + static int + geometry_func (char *arg, int flags) +@@ -4989,6 +5011,7 @@ struct builtin *builtin_table[] = + &builtin_find, + &builtin_fstest, + &builtin_geometry, ++ &builtin_gfxmenu, + &builtin_halt, + &builtin_help, + &builtin_hiddenmenu, +diff -Nurp grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h +--- grub-0.97.orig/stage2/shared.h 2004-06-19 18:40:09.000000000 +0200 ++++ grub-0.97/stage2/shared.h 2009-08-03 16:25:52.219523396 +0200 +@@ -374,6 +374,22 @@ extern char *grub_scratch_mem; + #endif /* WITHOUT_LIBC_STUBS */ + + ++/* see typedef gfx_data_t below */ ++#define gfx_ofs_ok 0x00 ++#define gfx_ofs_code_seg 0x04 ++#define gfx_ofs_jmp_table 0x08 ++#define gfx_ofs_sys_cfg 0x38 ++#define gfx_ofs_cmdline 0x6c ++#define gfx_ofs_cmdline_len 0x70 ++#define gfx_ofs_menu_list 0x74 ++#define gfx_ofs_menu_default_entry 0x78 ++#define gfx_ofs_menu_entries 0x7c ++#define gfx_ofs_menu_entry_len 0x80 ++#define gfx_ofs_args_list 0x84 ++#define gfx_ofs_args_entry_len 0x88 ++#define gfx_ofs_timeout 0x8c ++ ++ + #ifndef ASM_FILE + /* + * Below this should be ONLY defines and other constructs for C code. +@@ -595,6 +611,38 @@ extern int fallback_entryno; + extern int default_entry; + extern int current_entryno; + ++ ++/* ++ * graphics menu stuff ++ * ++ * Note: gfx_data and all data referred to in it must lie within a 64k area. ++ */ ++typedef struct { ++ unsigned ok; /* set while we're in graphics mode */ ++ unsigned code_seg; /* code segment of binary graphics code */ ++ unsigned jmp_table[12]; /* link to graphics functions */ ++ unsigned char sys_cfg[52]; /* sys_cfg[0]: identifies boot loader (grub == 2) */ ++ char *cmdline; /* command line returned by gfx_input() */ ++ unsigned cmdline_len; /* length of the above */ ++ char *menu_list; /* list of menu entries, each of fixed length (menu_entry_len) */ ++ char *menu_default_entry; /* the default entry */ ++ unsigned menu_entries; /* number of entries in menu_list */ ++ unsigned menu_entry_len; /* one entry */ ++ char *args_list; /* same structure as menu_list, menu_entries entries */ ++ unsigned args_entry_len; /* one entry */ ++ unsigned timeout; /* in seconds (0: no timeout) */ ++} __attribute__ ((packed)) gfx_data_t; ++ ++extern gfx_data_t *graphics_data; ++ ++/* pointer to graphics image data */ ++extern char graphics_file[64]; ++ ++int gfx_init(gfx_data_t *gfx_data); ++int gfx_done(gfx_data_t *gfx_data); ++int gfx_input(gfx_data_t *gfx_data, int *menu_entry); ++int gfx_setup_menu(gfx_data_t *gfx_data); ++ + /* The constants for password types. */ + typedef enum + { +diff -Nurp grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c +--- grub-0.97.orig/stage2/stage2.c 2005-03-19 18:51:57.000000000 +0100 ++++ grub-0.97/stage2/stage2.c 2009-08-03 16:25:52.220523160 +0200 +@@ -22,6 +22,8 @@ + + grub_jmp_buf restart_env; + ++gfx_data_t *graphics_data; ++ + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) + + # if defined(PRESET_MENU_STRING) +@@ -310,6 +312,12 @@ restart: + + if (! auth && password) + { ++ if (*graphics_file) ++ { ++ printf ("\ ++ WARNING: graphical menu doesn\'t work\ ++ in conjunction with the password feature\n" ); ++ } + printf ("\ + Press enter to boot the selected OS or \'p\' to enter a\n\ + password to unlock the next set of features."); +@@ -753,6 +761,496 @@ restart: + } + + ++ ++#if 0 ++/* for debugging */ ++static void hexdump(unsigned char *buf, unsigned len) ++{ ++ int i, j = 0; ++ char s[17]; ++ unsigned addr = (unsigned) buf; ++ ++ s[16] = 0; ++ while(len--) { ++ i = buf[j]; ++ i = i & 0xff; ++ s[j & 15] = (i >= 0x20 && i <= 0x7e) ? i : '.'; ++ if(!(j & 15)) { ++ printf("%x ", j + addr); ++ } ++ if(!(j & 7) && (j & 15)) printf(" "); ++ /* stupid grub_printf */ ++ printf("%x", (i >> 4) & 0x0f); ++ printf("%x ", i & 0x0f); ++ if(!(++j & 15)) { ++ printf(" %s\n", s); ++ } ++ } ++ ++ if(j & 15) { ++ s[j & 15] = 0; ++ if(!(j & 8)) printf(" "); ++ i = 1 + 3 * (16 - (j & 15)); ++ while(i--) printf(" "); ++ printf("%s\n", s); ++ } ++} ++#endif ++ ++ ++/* kernel + (grub-)module options */ ++#define GFX_CMD_BUF_SIZE 512 ++ ++/* command line separator char */ ++#define GFX_CMD_SEP 1 ++ ++/* ++ * Go through config entry and find kernel args, if any. ++ * Put things into buf and return it. ++ */ ++static char *get_kernel_args(char *cfg, char *buf) ++{ ++ int i, j; ++ char *s, *t = "", *p, *t2; ++ ++ *(p = buf) = 0; ++ ++ for(j = 0; ; j++) { ++ s = get_entry(cfg, j, 0); ++ if(!*s) break; ++ if( ++ (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) && ++ (s[6] == ' ' || s[6] == '\t') ++ ) { ++ t = skip_to(0, s); ++ t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL; ++ if(*t) t = skip_to(0, t); ++ if(t2 && t2 < t) break; /* module is likely a normal initrd -> skip */ ++ i = strlen(t); ++ if(p - buf + i > GFX_CMD_BUF_SIZE - 2) break; ++ *p++ = GFX_CMD_SEP; ++ strcpy(p, t); ++ p += i; ++ ++ continue; ++ } ++ } ++ ++ if(*buf) buf++; /* skip initial separator char */ ++ ++ return buf; ++} ++ ++ ++/* ++ * Check header and return code start offset. ++ */ ++static unsigned magic_ok(unsigned char *buf) ++{ ++ if( ++ *(unsigned *) buf == 0x0b2d97f00 && /* magic id */ ++ (buf[4] == 8) /* version 8 */ ++ ) { ++ return *(unsigned *) (buf + 8); ++ } ++ ++ return 0; ++} ++ ++ ++/* ++ * Search cpio archive for gfx file. ++ */ ++static unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len) ++{ ++ unsigned i, fname_len, code_start = 0; ++ ++ *gfx_file_start = 0; ++ ++ for(i = 0; i < len;) { ++ if((len - i) >= 0x1a && (buf[i] + (buf[i + 1] << 8)) == 0x71c7) { ++ fname_len = *(unsigned short *) (buf + i + 20); ++ *file_len = *(unsigned short *) (buf + i + 24) + (*(unsigned short *) (buf + i + 22) << 16); ++ i += 26 + fname_len; ++ i = ((i + 1) & ~1); ++ if((code_start = magic_ok(buf + i))) { ++ *gfx_file_start = i; ++ return code_start; ++ } ++ i += *file_len; ++ i = ((i + 1) & ~1); ++ } ++ else { ++ break; ++ } ++ } ++ ++ return code_start; ++} ++ ++static inline unsigned char * stack_ptr(void) ++{ ++ unsigned char * u; ++ ++ asm("movl %%esp, %0" : "=r" (u)); ++ ++ return u; ++} ++ ++static void sleep(int delay) ++{ ++ int tick, last_tick = currticks(); ++ ++ delay *= 18; ++ ++ while(delay--) { ++ while((tick = currticks()) == last_tick) { } ++ last_tick = tick; ++ } ++} ++ ++static void wait_for_key() ++{ ++ printf("Press a key to continue..."); ++ getkey(); ++ printf("\r \r"); ++} ++ ++ ++/* ++ * Leave that much space on the heap. Everything else goes to the graphics ++ * functions. ++ * ++ * 0x2000 is _not_ enough ++ */ ++#define MIN_HEAP_SIZE 0x4000 ++#define MIN_GFX_FREE 0x1000 ++ ++#define SC_BOOTLOADER 0 ++#define SC_FAILSAFE 3 ++#define SC_SYSCONFIG_SIZE 4 ++#define SC_BOOTLOADER_SEG 8 ++#define SC_XMEM_0 24 ++#define SC_XMEM_1 26 ++#define SC_XMEM_2 28 ++#define SC_XMEM_3 30 ++#define SC_FILE 32 ++#define SC_ARCHIVE_START 36 ++#define SC_ARCHIVE_END 40 ++#define SC_MEM0_START 44 ++#define SC_MEM0_END 48 ++ ++/* ++ * Does normally not return. ++ */ ++static void ++run_graphics_menu (char *menu_entries, char *config_entries, int num_entries, ++ char *heap, int entryno) ++{ ++ unsigned char *buf, *buf_ext; ++ unsigned buf_size, buf_ext_size, code_start, file_start; ++ char *s, *t, *t2, *cfg, *new_config, *p; ++ char *saved_heap; ++ int i, j, max_len, gfx_file_size, verbose; ++ int selected_entry; ++ gfx_data_t *gfx_data; ++ char *cmd_buf; ++ unsigned mem0_start, mem0_end, file_len; ++ ++ /* ++ * check gfx_data_t struct offsets for consistency; gcc will optimize away ++ * the whole block ++ */ ++ ++ /* dummy function to make ld fail */ ++ { ++ extern void wrong_struct_size(void); ++ #define gfx_ofs_check(a) if(gfx_ofs_##a != (char *) &gfx_data->a - (char *) gfx_data) wrong_struct_size(); ++ gfx_ofs_check(ok); ++ gfx_ofs_check(code_seg); ++ gfx_ofs_check(jmp_table); ++ gfx_ofs_check(sys_cfg); ++ gfx_ofs_check(cmdline); ++ gfx_ofs_check(cmdline_len); ++ gfx_ofs_check(menu_list); ++ gfx_ofs_check(menu_default_entry); ++ gfx_ofs_check(menu_entries); ++ gfx_ofs_check(menu_entry_len); ++ gfx_ofs_check(args_list); ++ gfx_ofs_check(args_entry_len); ++ gfx_ofs_check(timeout); ++ #undef gfx_ofs_check ++ } ++ ++ if(!num_entries) return; ++ ++ graphics_data = gfx_data = (gfx_data_t *) heap; ++ heap += sizeof *gfx_data; ++ memset(gfx_data, 0, sizeof *gfx_data); ++ ++ gfx_data->sys_cfg[SC_BOOTLOADER] = 2; /* bootloader: grub */ ++ gfx_data->sys_cfg[SC_SYSCONFIG_SIZE] = 52; /* config data size */ ++ *(unsigned short *) (gfx_data->sys_cfg + SC_BOOTLOADER_SEG) = (unsigned) gfx_data >> 4; /* segment */ ++ gfx_data->sys_cfg[SC_XMEM_0] = 0x28; /* 8MB @ 2MB, see buf_ext below */ ++ // gfx_data->sys_cfg[SC_XMEM_1] = 0xYZ; /* Z MB @ Y MB */ ++ verbose = (*(unsigned char *) 0x417) & 3 ? 1 : 0; /* SHIFT pressed */ ++ gfx_data->sys_cfg[SC_FAILSAFE] = verbose; ++ ++ gfx_data->timeout = grub_timeout >= 0 ? grub_timeout : 0; ++ ++ ++ /* setup command line edit buffer */ ++ ++ gfx_data->cmdline_len = 256; ++ ++ gfx_data->cmdline = heap; ++ heap += gfx_data->cmdline_len; ++ memset(gfx_data->cmdline, 0, gfx_data->cmdline_len); ++ ++ cmd_buf = heap; ++ heap += GFX_CMD_BUF_SIZE; ++ ++ /* setup menu entries */ ++ ++ for(i = max_len = 0; i < num_entries; i++) { ++ j = strlen(get_entry(menu_entries, i, 0)); ++ if(j > max_len) max_len = j; ++ } ++ ++ if(!max_len) return; ++ ++ gfx_data->menu_entry_len = max_len + 1; ++ gfx_data->menu_entries = num_entries; ++ ++ gfx_data->menu_list = heap; ++ heap += gfx_data->menu_entry_len * gfx_data->menu_entries; ++ ++ memset(gfx_data->menu_list, 0, gfx_data->menu_entry_len * gfx_data->menu_entries); ++ ++ for(i = 0; i < (int) gfx_data->menu_entries; i++) { ++ strcpy(gfx_data->menu_list + i * gfx_data->menu_entry_len, get_entry(menu_entries, i, 0)); ++ } ++ ++ gfx_data->menu_default_entry = gfx_data->menu_list + entryno * gfx_data->menu_entry_len; ++ ++ ++ /* setup list of kernel args */ ++ ++ for(i = max_len = 0; i < num_entries; i++) { ++ s = get_kernel_args(get_entry(config_entries, i, 1), cmd_buf); ++ j = strlen(s); ++ if(j > max_len) max_len = j; ++ } ++ ++ gfx_data->args_entry_len = max_len + 1; ++ ++ gfx_data->args_list = heap; ++ heap += gfx_data->args_entry_len * gfx_data->menu_entries; ++ ++ memset(gfx_data->args_list, 0, gfx_data->args_entry_len * gfx_data->menu_entries); ++ ++ for(i = 0; i < (int) gfx_data->menu_entries; i++) { ++ strcpy(gfx_data->args_list + i* gfx_data->args_entry_len, get_kernel_args(get_entry(config_entries, i, 1), cmd_buf)); ++ } ++ ++ ++ /* go back here when we no longer need the graphics data */ ++ saved_heap = heap; ++ ++ ++ /* get memory area to be used by graphics functions */ ++ ++ /* use 8MB starting at 2MB as file buffer; see SC_XMEM_0 above (A20 is enabled anyway) */ ++ buf_ext = (unsigned char *) (2 << 20); ++ buf_ext_size = 8 << 20; ++ ++ /* must be 16-byte aligned */ ++ buf = (unsigned char *) (((unsigned) heap + 0xf) & ~0xf); ++ ++ buf_size = stack_ptr() - buf - MIN_HEAP_SIZE; ++ buf_size &= ~0xf; ++ ++ mem0_start = (unsigned) buf; ++ mem0_end = mem0_start + buf_size; ++ ++ if(verbose) { ++ printf("low memory 0x%x - 0x%x (%d bytes)\n", mem0_start, mem0_end, buf_size); ++ wait_for_key(); ++ } ++ ++ heap += buf_size; ++ ++ /* read the file */ ++ ++ if(!grub_open(graphics_file)) { ++ printf("%s: file not found\n", graphics_file); ++ sleep(5); ++ heap = saved_heap; ++ return; ++ } ++ ++ gfx_file_size = grub_read(buf_ext, buf_ext_size); ++ ++ grub_close(); ++ ++ if(gfx_file_size <= 0) { ++ printf("%s: read error\n", graphics_file); ++ sleep(5); ++ heap = saved_heap; ++ return; ++ } ++ ++ if(verbose) { ++ printf("%s: %d bytes (%d bytes left)\n", graphics_file, gfx_file_size, buf_ext_size - gfx_file_size); ++ wait_for_key(); ++ } ++ ++ /* locate file inside cpio archive */ ++ if(!(code_start = find_file(buf_ext, gfx_file_size, &file_start, &file_len))) { ++ printf("%s: invalid file format\n", graphics_file); ++ sleep(5); ++ heap = saved_heap; ++ return; ++ } ++ ++ if(verbose) { ++ printf("init: start 0x%x, len %d; code offset 0x%x\n", file_start, file_len, code_start); ++ wait_for_key(); ++ } ++ ++ if(file_len - code_start + MIN_GFX_FREE > buf_size) { ++ printf("not enough free memory: %d extra bytes need\n", file_len - code_start + MIN_GFX_FREE - buf_size); ++ sleep(5); ++ heap = saved_heap; ++ return; ++ } ++ ++ memcpy((void *) buf, (void *) (buf_ext + file_start + code_start), file_len - code_start); ++ ++ mem0_start += file_len - code_start; ++ mem0_start = (mem0_start + 3) & ~3; /* align */ ++ ++ /* init interface to graphics functions */ ++ ++ *(unsigned *) (gfx_data->sys_cfg + SC_FILE) = (unsigned) buf_ext + file_start; ++ *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_START) = (unsigned) buf_ext; ++ *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_END) = (unsigned) buf_ext + gfx_file_size; ++ *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_START) = mem0_start; ++ *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_END) = mem0_end; ++ ++ gfx_data->code_seg = (unsigned) buf >> 4; ++ ++ if(verbose) { ++ printf("init 0x%x, archive 0x%x - 0x%x, low mem 0x%x - 0x%x\ncode seg 0x%x\n", ++ (unsigned) buf_ext + file_start, ++ (unsigned) buf_ext, (unsigned) buf_ext + gfx_file_size, ++ mem0_start, mem0_end, gfx_data->code_seg ++ ); ++ wait_for_key(); ++ } ++ ++ for(i = 0; (unsigned) i < sizeof gfx_data->jmp_table / sizeof *gfx_data->jmp_table; i++) { ++ gfx_data->jmp_table[i] = (gfx_data->code_seg << 16) + ((unsigned short *) buf)[i]; ++ } ++ ++ if(verbose) { ++ for(i = 0; i < 12; i++) { ++ printf("%d: 0x%x\n", i, gfx_data->jmp_table[i]); ++ } ++ ++ for(i = 0; i < gfx_data->menu_entries; i++) { ++ printf("\"%s\" -- \"%s\"\n", ++ gfx_data->menu_list + i * gfx_data->menu_entry_len, ++ gfx_data->args_list + i * gfx_data->args_entry_len ++ ); ++ } ++ ++ printf("default: \"%s\"\n", gfx_data->menu_default_entry); ++ wait_for_key(); ++ } ++ ++ /* switch to graphics mode */ ++ ++ if(gfx_init(gfx_data)) { ++ printf("graphics initialization failed\n"); ++ sleep(5); ++ heap = saved_heap; ++ return; ++ } ++ ++ gfx_setup_menu(gfx_data); ++ ++ i = gfx_input(gfx_data, &selected_entry); ++ ++ /* ESC -> show text menu */ ++ if(i == 1) { ++ gfx_done(gfx_data); ++ grub_timeout = -1; ++ ++ heap = saved_heap; ++ return; ++ } ++ ++ gfx_done(gfx_data); ++ ++ heap = saved_heap; /* free most of the graphics data */ ++ ++ // printf("cmdline: >%s<, entry = %d\n", gfx_data->cmdline, selected_entry); ++ ++ if(selected_entry < 0 || selected_entry > num_entries) return; ++ ++ /* for 'savedefault' */ ++ current_entryno = selected_entry; ++ ++ ++ /* create new config with modified kernel option */ ++ ++ cfg = get_entry(config_entries, selected_entry, 1); ++ ++ new_config = heap; ++ ++ for(p = gfx_data->cmdline, i = 0; ; i++) { ++ s = get_entry(cfg, i, 0); ++ if(!*s) { ++ if(!i) *heap++ = 0; ++ *heap++ = 0; ++ break; ++ } ++ /* note: must match get_kernel_args() */ ++ if( ++ (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) && ++ (s[6] == ' ' || s[6] == '\t') ++ ) { ++ t = skip_to(0, s); ++ t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL; ++ if(*t) t = skip_to(0, t); ++ if(t2 && t2 < t) { /* module is likely a normal initrd -> skip */ ++ strcpy(heap, s); ++ heap += strlen(s) + 1; ++ continue; ++ } ++ memmove(heap, s, t - s); ++ heap += t - s; ++ *heap++ = ' '; ++ while(*p && *p != GFX_CMD_SEP) *heap++ = *p++; ++ *heap++ = 0; ++ if(*p == GFX_CMD_SEP) p++; ++ } ++ else { ++ strcpy(heap, s); ++ heap += strlen(s) + 1; ++ } ++ } ++ ++ *heap++ = 0; ++ ++ // hexdump(new_config, heap - new_config); ++ // getkey(); ++ ++ run_script(new_config, heap); ++} ++ ++ + static int + get_line_from_config (char *cmdline, int maxlen, int read_from_file) + { +@@ -1059,9 +1557,12 @@ cmain (void) + } + else + { +- /* Run menu interface. */ +- run_menu (menu_entries, config_entries, num_entries, +- menu_entries + menu_len, default_entry); ++ if (*graphics_file && !password && show_menu && grub_timeout) ++ { ++ run_graphics_menu(menu_entries, config_entries, num_entries,menu_entries + menu_len, default_entry); ++ } ++ /* Run menu interface. */ ++ run_menu (menu_entries, config_entries, num_entries, menu_entries + menu_len, default_entry); + } + } + } diff --git a/sys-boot/grub/files/grub-0.97-uuid.patch b/sys-boot/grub/files/grub-0.97-uuid.patch new file mode 100644 index 0000000..f99670a --- /dev/null +++ b/sys-boot/grub/files/grub-0.97-uuid.patch @@ -0,0 +1,5406 @@ +=== modified file 'Makefile.am' +--- grub-0.97.orig/Makefile.am 2004-04-23 13:39:01 +0000 ++++ grub-0.97/Makefile.am 2008-07-09 17:23:44 +0000 +@@ -1,4 +1,9 @@ + # Do not change this order if you don't know what you are doing. + AUTOMAKE_OPTIONS = 1.7 gnu +-SUBDIRS = netboot stage2 stage1 lib grub util docs ++if UUID_SUPPORT ++SUBDIRS = libvolume_id netboot stage2 stage1 lib grub util docs ++else ++SUBDIRS = netboot stage2 stage1 lib grub util docs ++endif ++ + EXTRA_DIST = BUGS MAINTENANCE + +=== modified file 'configure.ac' +--- grub-0.97.orig/configure.ac 2008-01-28 18:41:45 +0000 ++++ grub-0.97/configure.ac 2008-07-09 17:23:44 +0000 +@@ -605,6 +606,11 @@ + [ --disable-serial disable serial terminal support]) + AM_CONDITIONAL(SERIAL_SUPPORT, test "x$enable_serial" != xno) + ++dnl UUID scanning ++AC_ARG_ENABLE(uuid, ++ [ --disable-uuid disable uuid scanning support]) ++AM_CONDITIONAL(UUID_SUPPORT, test "x$enable_uuid" != xno) ++ + dnl Simulation of the slowness of a serial device. + AC_ARG_ENABLE(serial-speed-simulation, + [ --enable-serial-speed-simulation +@@ -666,5 +672,6 @@ + docs/Makefile lib/Makefile util/Makefile \ + grub/Makefile netboot/Makefile util/grub-image \ + util/grub-install util/grub-md5-crypt \ +- util/grub-terminfo util/grub-set-default]) ++ util/grub-terminfo util/grub-set-default \ ++ libvolume_id/Makefile]) + AC_OUTPUT + +=== modified file 'grub/Makefile.am' +--- grub-0.97.orig/grub/Makefile.am 2005-02-02 20:40:05 +0000 ++++ grub-0.97/grub/Makefile.am 2008-07-09 17:23:44 +0000 +@@ -16,4 +16,9 @@ + AM_CFLAGS = $(GRUB_CFLAGS) + + grub_SOURCES = main.c asmstub.c +-grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS) ++ ++if UUID_SUPPORT ++grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a ../libvolume_id/libvolume_id.a $(GRUB_LIBS) ++else ++grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS) ++endif + +=== added directory 'libvolume_id' +=== added file 'libvolume_id/Makefile.am' +--- grub-0.97.orig/libvolume_id/Makefile.am 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/Makefile.am 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,27 @@ ++noinst_LIBRARIES = libvolume_id.a ++ ++AM_CFLAGS = $(STAGE2_CFLAGS) -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1 ++ ++LIBVOLUME_ID_FS_SUPPORTED = ext.c fat.c hfs.c jfs.c \ ++ luks.c ntfs.c ocfs.c reiserfs.c \ ++ xfs.c ++ ++LIBVOLUME_ID_FS_UNSUPPORTED = cramfs.c gfs.c hpfs.c iso9660.c \ ++ lvm.c minix.c romfs.c squashfs.c \ ++ sysv.c udf.c ufs.c vxfs.c ++ ++LIBVOLUME_ID_RAID_SUPPORTED = ddf_raid.c ++ ++LIBVOLUME_ID_RAID_UNSUPPORTED = adaptec_raid.c highpoint.c isw_raid.c \ ++ jmicron_raid.c linux_raid.c lsi_raid.c \ ++ nvidia_raid.c promise_raid.c silicon_raid.c \ ++ via_raid.c ++ ++LIBVOLUME_ID_MISC_UNSUPPORTED = linux_swap.c netware.c ++ ++libvolume_id_a_SOURCES = $(LIBVOLUME_ID_FS_SUPPORTED) \ ++ $(LIBVOLUME_ID_RAID_SUPPORTED) \ ++ $(LIBVOLUME_ID_FS_UNSUPPORTED) \ ++ $(LIBVOLUME_ID_RAID_UNSUPPORTED) \ ++ volume_id.h volume_id.c util.c util.h misc.c ++ + +=== added file 'libvolume_id/adaptec_raid.c' +--- grub-0.97.orig/libvolume_id/adaptec_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/adaptec_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,107 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct adaptec_meta { ++ uint32_t b0idcode; ++ uint8_t lunsave[8]; ++ uint16_t sdtype; ++ uint16_t ssavecyl; ++ uint8_t ssavehed; ++ uint8_t ssavesec; ++ uint8_t sb0flags; ++ uint8_t jbodEnable; ++ uint8_t lundsave; ++ uint8_t svpdirty; ++ uint16_t biosInfo; ++ uint16_t svwbskip; ++ uint16_t svwbcln; ++ uint16_t svwbmax; ++ uint16_t res3; ++ uint16_t svwbmin; ++ uint16_t res4; ++ uint16_t svrcacth; ++ uint16_t svwcacth; ++ uint16_t svwbdly; ++ uint8_t svsdtime; ++ uint8_t res5; ++ uint16_t firmval; ++ uint16_t firmbln; ++ uint32_t firmblk; ++ uint32_t fstrsvrb; ++ uint16_t svBlockStorageTid; ++ uint16_t svtid; ++ uint8_t svseccfl; ++ uint8_t res6; ++ uint8_t svhbanum; ++ uint8_t resver; ++ uint32_t drivemagic; ++ uint8_t reserved[20]; ++ uint8_t testnum; ++ uint8_t testflags; ++ uint16_t maxErrorCount; ++ uint32_t count; ++ uint32_t startTime; ++ uint32_t interval; ++ uint8_t tstxt0; ++ uint8_t tstxt1; ++ uint8_t serNum[32]; ++ uint8_t res8[102]; ++ uint32_t fwTestMagic; ++ uint32_t fwTestSeqNum; ++ uint8_t fwTestRes[8]; ++ uint8_t smagic[4]; ++ uint32_t raidtbl; ++ uint16_t raidline; ++ uint8_t res9[0xF6]; ++} PACKED; ++ ++int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct adaptec_meta *ad; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-1) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ ad = (struct adaptec_meta *) buf; ++ if (memcmp((char*)ad->smagic, "DPTM", 4) != 0) ++ return -1; ++ ++ if (ad->b0idcode != be32_to_cpu(0x37FC4D1E)) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ sprintf(id->type_version, "%u", ad->resver); ++ id->type = "adaptec_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/cramfs.c' +--- grub-0.97.orig/libvolume_id/cramfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/cramfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,60 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct cramfs_super { ++ uint8_t magic[4]; ++ uint32_t size; ++ uint32_t flags; ++ uint32_t future; ++ uint8_t signature[16]; ++ struct cramfs_info { ++ uint32_t crc; ++ uint32_t edition; ++ uint32_t blocks; ++ uint32_t files; ++ } PACKED info; ++ uint8_t name[16]; ++} PACKED; ++ ++int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct cramfs_super *cs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ cs = (struct cramfs_super *) volume_id_get_buffer(id, off, 0x200); ++ if (cs == NULL) ++ return -1; ++ ++ if (memcmp((char*)cs->magic, "\x45\x3d\xcd\x28", 4) == 0 || memcmp((char*)cs->magic, "\x28\xcd\x3d\x45", 4) == 0) { ++ volume_id_set_label_raw(id, cs->name, 16); ++ volume_id_set_label_string(id, cs->name, 16); ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "cramfs"; ++ return 0; ++ } ++ ++ return -1; ++} + +=== added file 'libvolume_id/ddf_raid.c' +--- grub-0.97.orig/libvolume_id/ddf_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/ddf_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,60 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2007 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++/* http://www.snia.org/standards/home */ ++ ++#define DDF_HEADER 0xDE11DE11 ++#define DDF_GUID_LENGTH 24 ++#define DDF_REV_LENGTH 8 ++ ++static struct ddf_header { ++ uint32_t signature; ++ uint32_t crc; ++ uint8_t guid[DDF_GUID_LENGTH]; ++ uint8_t ddf_rev[DDF_REV_LENGTH]; ++} PACKED *ddf; ++ ++int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ uint64_t ddf_off = ((size / 0x200)-1) * 0x200; ++ const uint8_t *buf; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ if (size < 0x10000) ++ return -1; ++ ++ buf = volume_id_get_buffer(id, off + ddf_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ddf = (struct ddf_header *) buf; ++ ++ if (ddf->signature != cpu_to_be32(DDF_HEADER)) ++ return -1; ++ ++ volume_id_set_uuid(id, ddf->guid, DDF_GUID_LENGTH, UUID_STRING); ++ strcpy(id->type_version, (char*) ddf->ddf_rev); ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "ddf_raid_member"; ++ return 0; ++} + +=== added file 'libvolume_id/ext.c' +--- grub-0.97.orig/libvolume_id/ext.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/ext.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,129 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct ext2_super_block { ++ uint32_t s_inodes_count; ++ uint32_t s_blocks_count; ++ uint32_t s_r_blocks_count; ++ uint32_t s_free_blocks_count; ++ uint32_t s_free_inodes_count; ++ uint32_t s_first_data_block; ++ uint32_t s_log_block_size; ++ uint32_t s_log_frag_size; ++ uint32_t s_blocks_per_group; ++ uint32_t s_frags_per_group; ++ uint32_t s_inodes_per_group; ++ uint32_t s_mtime; ++ uint32_t s_wtime; ++ uint16_t s_mnt_count; ++ uint16_t s_max_mnt_count; ++ uint16_t s_magic; ++ uint16_t s_state; ++ uint16_t s_errors; ++ uint16_t s_minor_rev_level; ++ uint32_t s_lastcheck; ++ uint32_t s_checkinterval; ++ uint32_t s_creator_os; ++ uint32_t s_rev_level; ++ uint16_t s_def_resuid; ++ uint16_t s_def_resgid; ++ uint32_t s_first_ino; ++ uint16_t s_inode_size; ++ uint16_t s_block_group_nr; ++ uint32_t s_feature_compat; ++ uint32_t s_feature_incompat; ++ uint32_t s_feature_ro_compat; ++ uint8_t s_uuid[16]; ++ uint8_t s_volume_name[16]; ++} PACKED; ++ ++#define EXT_SUPER_MAGIC 0xEF53 ++#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 ++#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 ++#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 ++#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 ++#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 ++ ++#define EXT_SUPERBLOCK_OFFSET 0x400 ++ ++#define EXT3_MIN_BLOCK_SIZE 0x400 ++#define EXT3_MAX_BLOCK_SIZE 0x1000 ++ ++int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct ext2_super_block *es; ++ size_t bsize; ++ uint32_t feature_compat; ++ uint32_t feature_incompat; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); ++ if (es == NULL) ++ return -1; ++ ++ if (es->s_magic != cpu_to_le16(EXT_SUPER_MAGIC)) ++ return -1; ++ ++ bsize = 0x400 << le32_to_cpu(es->s_log_block_size); ++ dbg("ext blocksize 0x%zx", bsize); ++ if (bsize < EXT3_MIN_BLOCK_SIZE || bsize > EXT3_MAX_BLOCK_SIZE) { ++ dbg("invalid ext blocksize"); ++ return -1; ++ } ++ ++ volume_id_set_label_raw(id, es->s_volume_name, 16); ++ volume_id_set_label_string(id, es->s_volume_name, 16); ++ volume_id_set_uuid(id, es->s_uuid, 0, UUID_DCE); ++ sprintf(id->type_version, "%u.%u", ++ le32_to_cpu(es->s_rev_level), le16_to_cpu(es->s_minor_rev_level)); ++ ++ feature_compat = le32_to_cpu(es->s_feature_compat); ++ feature_incompat = le32_to_cpu(es->s_feature_incompat); ++ ++ /* check for external journal device */ ++ if ((feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) { ++ volume_id_set_usage(id, VOLUME_ID_OTHER); ++ id->type = "jbd"; ++ goto out; ++ } ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ ++ if ((feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) != 0 || ++ (feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0 || ++ (feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) != 0) { ++ id->type = "ext4"; ++ goto out; ++ } ++ ++ if ((feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { ++ id->type = "ext3"; ++ goto out; ++ } ++ ++ id->type = "ext2"; ++ ++out: ++ return 0; ++} + +=== added file 'libvolume_id/fat.c' +--- grub-0.97.orig/libvolume_id/fat.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/fat.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,482 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004-2007 Kay Sievers <kay.sievers@vrfy.org> ++ * Copyright (C) 2007 Ryan Lortie <desrt@desrt.ca> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define FAT12_MAX 0xff5 ++#define FAT16_MAX 0xfff5 ++#define FAT_ATTR_VOLUME_ID 0x08 ++#define FAT_ATTR_DIR 0x10 ++#define FAT_ATTR_LONG_NAME 0x0f ++#define FAT_ATTR_MASK 0x3f ++#define FAT_ENTRY_FREE 0xe5 ++ ++#define VFAT_LFN_SEQ_MASK 0x3f ++#define VFAT_LFN_SEQ_LAST 0x40 ++#define VFAT_LFN_SEQ_MAX 20 ++#define VFAT_LFN_CHARS_PER_ENTRY (5 + 6 + 2) ++#define VFAT_LOWERCASE_NAME 0x10 ++#define VFAT_LOWERCASE_EXT 0x08 ++ ++struct vfat_super_block { ++ uint8_t boot_jump[3]; ++ uint8_t sysid[8]; ++ uint16_t sector_size; ++ uint8_t sectors_per_cluster; ++ uint16_t reserved; ++ uint8_t fats; ++ uint16_t dir_entries; ++ uint16_t sectors; ++ uint8_t media; ++ uint16_t fat_length; ++ uint16_t secs_track; ++ uint16_t heads; ++ uint32_t hidden; ++ uint32_t total_sect; ++ union { ++ struct fat_super_block { ++ uint8_t unknown[3]; ++ uint8_t serno[4]; ++ uint8_t label[11]; ++ uint8_t magic[8]; ++ uint8_t dummy2[192]; ++ uint8_t pmagic[2]; ++ } PACKED fat; ++ struct fat32_super_block { ++ uint32_t fat32_length; ++ uint16_t flags; ++ uint8_t version[2]; ++ uint32_t root_cluster; ++ uint16_t fsinfo_sector; ++ uint16_t backup_boot; ++ uint16_t reserved2[6]; ++ uint8_t unknown[3]; ++ uint8_t serno[4]; ++ uint8_t label[11]; ++ uint8_t magic[8]; ++ uint8_t dummy2[164]; ++ uint8_t pmagic[2]; ++ } PACKED fat32; ++ } PACKED type; ++} PACKED; ++ ++struct fat32_fsinfo { ++ uint8_t signature1[4]; ++ uint32_t reserved1[120]; ++ uint8_t signature2[4]; ++ uint32_t free_clusters; ++ uint32_t next_cluster; ++ uint32_t reserved2[4]; ++} PACKED; ++ ++struct vfat_dir_entry { ++ uint8_t name[11]; ++ uint8_t attr; ++ uint8_t lowercase; ++ uint8_t fine_time_creat; ++ uint16_t time_creat; ++ uint16_t date_creat; ++ uint16_t date_acc; ++ uint16_t cluster_high; ++ uint16_t time_write; ++ uint16_t date_write; ++ uint16_t cluster_low; ++ uint32_t size; ++} PACKED; ++ ++ ++struct vfat_lfn_entry { ++ uint8_t seq; ++ uint16_t name0[5]; ++ uint8_t attr; ++ uint8_t reserved; ++ uint8_t cksum; ++ uint16_t name1[6]; ++ uint16_t cluster; ++ uint16_t name2[2]; ++} PACKED; ++ ++static uint8_t fat_lfn_checksum(const uint8_t name[11]) ++{ ++ uint8_t cksum = 0; ++ int i; ++ ++ /* http://en.wikipedia.org/wiki/File_Allocation_Table */ ++ for (i = 0; i < 11; i++) ++ cksum = ((cksum & 1) ? 0x80 : 0) + (cksum >> 1) + name[i]; ++ ++ return cksum; ++} ++ ++static size_t fat_read_lfn(uint8_t *filename, size_t fnsize, ++ struct vfat_dir_entry *direntry, ++ struct vfat_dir_entry *entry) ++{ ++ uint8_t buffer[VFAT_LFN_SEQ_MAX * VFAT_LFN_CHARS_PER_ENTRY * 2]; ++ uint8_t expected_seq = 1; ++ uint8_t cksum; ++ size_t len = 0; ++ size_t fnlen = 0; ++ ++ cksum = fat_lfn_checksum(entry->name); ++ ++ while (--entry >= direntry) { ++ struct vfat_lfn_entry *lfn = (struct vfat_lfn_entry *) entry; ++ ++ if (expected_seq > VFAT_LFN_SEQ_MAX) ++ break; ++ ++ if ((lfn->attr & FAT_ATTR_MASK) != FAT_ATTR_LONG_NAME) ++ break; ++ ++ if (lfn->cksum != cksum) ++ break; ++ ++ if ((lfn->seq & VFAT_LFN_SEQ_MASK) != expected_seq++) ++ break; ++ ++ if (lfn->cluster != 0) ++ break; ++ ++ /* extra paranoia -- should never happen */ ++ if (len + sizeof(lfn->name0) + sizeof(lfn->name1) + ++ sizeof(lfn->name2) > sizeof(buffer)) ++ break; ++ ++ memcpy (&buffer[len], lfn->name0, sizeof(lfn->name0)); ++ len += sizeof(lfn->name0); ++ memcpy (&buffer[len], lfn->name1, sizeof(lfn->name1)); ++ len += sizeof(lfn->name1); ++ memcpy (&buffer[len], lfn->name2, sizeof(lfn->name2)); ++ len += sizeof(lfn->name2); ++ ++ if (lfn->seq & VFAT_LFN_SEQ_LAST) { ++ fnlen = volume_id_set_unicode16(filename, fnsize, buffer, LE, len); ++ break; ++ } ++ } ++ ++ return fnlen; ++} ++ ++static size_t fat_read_filename(uint8_t *filename, size_t fnsize, ++ struct vfat_dir_entry *direntry, struct vfat_dir_entry *entry) ++{ ++ size_t len; ++ int i; ++ ++ /* check if maybe we have LFN entries */ ++ len = fat_read_lfn(filename, fnsize, direntry, entry); ++ if (len > 0) ++ goto out; ++ ++ /* else, read the normal 8.3 name */ ++ for (i = 0; i < 11; i++) { ++ if (entry->lowercase & ((i < 8) ? VFAT_LOWERCASE_NAME : VFAT_LOWERCASE_EXT)) ++ filename[i] = tolower(entry->name[i]); ++ else ++ filename[i] = entry->name[i]; ++ } ++ len = 11; ++ ++out: ++ filename[len] = '\0'; ++ return len; ++} ++ ++/* fills filename, returns string length */ ++static size_t get_fat_attr_volume_id(uint8_t *filename, size_t fnsize, ++ struct vfat_dir_entry *direntry, unsigned int count) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < count; i++) { ++ /* end marker */ ++ if (direntry[i].name[0] == 0x00) { ++ dbg("end of dir"); ++ break; ++ } ++ ++ /* empty entry */ ++ if (direntry[i].name[0] == FAT_ENTRY_FREE) ++ continue; ++ ++ /* long name */ ++ if ((direntry[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME) ++ continue; ++ ++ if ((direntry[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { ++ /* labels do not have file data */ ++ if (direntry[i].cluster_high != 0 || direntry[i].cluster_low != 0) ++ continue; ++ ++ dbg("found ATTR_VOLUME_ID id in root dir"); ++ return fat_read_filename(filename, fnsize, direntry, &direntry[i]); ++ } ++ ++ dbg("skip dir entry"); ++ } ++ ++ return 0; ++} ++ ++int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ uint8_t filename[255 * 3]; ++ struct vfat_super_block *vs; ++ struct vfat_dir_entry *direntry; ++ struct fat32_fsinfo *fsinfo; ++ uint16_t sector_size; ++ uint16_t dir_entries; ++ uint32_t sect_count; ++ uint16_t reserved; ++ uint32_t fat_size; ++ uint32_t root_cluster; ++ uint32_t dir_size; ++ uint32_t cluster_count; ++ uint16_t fat_length; ++ uint32_t fat32_length; ++ uint64_t root_start; ++ uint32_t start_data_sect; ++ uint16_t root_dir_entries; ++ uint16_t fsinfo_sect; ++ uint8_t *buf; ++ uint32_t buf_size; ++ uint32_t next; ++ int maxloop; ++ size_t fnlen; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off, 0x400); ++ if (buf == NULL) ++ return -1; ++ ++ /* check signature */ ++ if (buf[510] != 0x55 || buf[511] != 0xaa) ++ return -1; ++ ++ vs = (struct vfat_super_block *) buf; ++ if (memcmp((char*)vs->sysid, "NTFS", 4) == 0) ++ return -1; ++ ++ /* believe only that's fat, don't trust the version */ ++ if (memcmp((char*)vs->type.fat32.magic, "MSWIN", 5) == 0) ++ goto magic; ++ ++ if (memcmp((char*)vs->type.fat32.magic, "FAT32 ", 8) == 0) ++ goto magic; ++ ++ if (memcmp((char*)vs->type.fat.magic, "FAT16 ", 8) == 0) ++ goto magic; ++ ++ if (memcmp((char*)vs->type.fat.magic, "MSDOS", 5) == 0) ++ goto magic; ++ ++ if (memcmp((char*)vs->type.fat.magic, "FAT12 ", 8) == 0) ++ goto magic; ++ ++ /* some old floppies don't have a magic, expect the boot jump address to match */ ++ if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && ++ vs->boot_jump[0] != 0xe9) ++ return -1; ++ ++magic: ++ /* reserverd sector count */ ++ if (!vs->reserved) ++ return -1; ++ ++ /* fat count */ ++ if (!vs->fats) ++ return -1; ++ ++ /* media check */ ++ if (vs->media < 0xf8 && vs->media != 0xf0) ++ return -1; ++ ++ /* cluster size check */ ++ if (vs->sectors_per_cluster == 0 || ++ (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) ++ return -1; ++ ++ /* sector size check */ ++ sector_size = le16_to_cpu(vs->sector_size); ++ if (sector_size == 0 || ((sector_size & (sector_size-1)) != 0)) ++ return -1; ++ ++ dbg("sector_size 0x%x", sector_size); ++ dbg("sectors_per_cluster 0x%x", vs->sectors_per_cluster); ++ ++ dir_entries = le16_to_cpu(vs->dir_entries); ++ reserved = le16_to_cpu(vs->reserved); ++ dbg("reserved 0x%x", reserved); ++ ++ sect_count = le16_to_cpu(vs->sectors); ++ if (sect_count == 0) ++ sect_count = le32_to_cpu(vs->total_sect); ++ dbg("sect_count 0x%x", sect_count); ++ ++ fat_length = le16_to_cpu(vs->fat_length); ++ dbg("fat_length 0x%x", fat_length); ++ fat32_length = le32_to_cpu(vs->type.fat32.fat32_length); ++ dbg("fat32_length 0x%x", fat32_length); ++ ++ if (fat_length) ++ fat_size = fat_length * vs->fats; ++ else if (fat32_length) ++ fat_size = fat32_length * vs->fats; ++ else ++ return -1; ++ dbg("fat_size 0x%x", fat_size); ++ ++ dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + ++ (sector_size-1)) / sector_size; ++ dbg("dir_size 0x%x", dir_size); ++ ++ cluster_count = sect_count - (reserved + fat_size + dir_size); ++ cluster_count /= vs->sectors_per_cluster; ++ dbg("cluster_count 0x%x", cluster_count); ++ ++ /* must be FAT32 */ ++ if (!fat_length && fat32_length) ++ goto fat32; ++ ++ /* cluster_count tells us the format */ ++ if (cluster_count < FAT12_MAX) ++ strcpy(id->type_version, "FAT12"); ++ else if (cluster_count < FAT16_MAX) ++ strcpy(id->type_version, "FAT16"); ++ else ++ goto fat32; ++ ++ /* the label may be an attribute in the root directory */ ++ root_start = (reserved + fat_size) * sector_size; ++ dbg("root dir start 0x%llx", (unsigned long long) root_start); ++ root_dir_entries = le16_to_cpu(vs->dir_entries); ++ dbg("expected entries 0x%x", root_dir_entries); ++ ++ buf_size = root_dir_entries * sizeof(struct vfat_dir_entry); ++ buf = volume_id_get_buffer(id, off + root_start, buf_size); ++ if (buf == NULL) ++ goto found; ++ ++ direntry = (struct vfat_dir_entry*) buf; ++ ++ fnlen = get_fat_attr_volume_id(filename, sizeof(filename), direntry, root_dir_entries); ++ ++ vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); ++ if (vs == NULL) ++ return -1; ++ ++ if (fnlen > 0 && memcmp((char*)filename, "NO NAME ", 11) != 0) { ++ volume_id_set_label_raw(id, filename, fnlen); ++ volume_id_set_label_string(id, filename, fnlen); ++ } else if (memcmp((char*)vs->type.fat.label, "NO NAME ", 11) != 0) { ++ volume_id_set_label_raw(id, vs->type.fat.label, 11); ++ volume_id_set_label_string(id, vs->type.fat.label, 11); ++ } ++ volume_id_set_uuid(id, vs->type.fat.serno, 0, UUID_DOS); ++ goto found; ++ ++fat32: ++ /* FAT32 should have a valid signature in the fsinfo block */ ++ fsinfo_sect = le16_to_cpu(vs->type.fat32.fsinfo_sector); ++ buf = volume_id_get_buffer(id, off + (fsinfo_sect * sector_size), 0x200); ++ if (buf == NULL) ++ return -1; ++ fsinfo = (struct fat32_fsinfo *) buf; ++ if (memcmp((char*)fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0) ++ return -1; ++ if (memcmp((char*)fsinfo->signature2, "\x72\x72\x41\x61", 4) != 0) ++ return -1 ; ++ ++ vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); ++ if (vs == NULL) ++ return -1; ++ ++ strcpy(id->type_version, "FAT32"); ++ ++ /* FAT32 root dir is a cluster chain like any other directory */ ++ buf_size = vs->sectors_per_cluster * sector_size; ++ root_cluster = le32_to_cpu(vs->type.fat32.root_cluster); ++ dbg("root dir cluster %u", root_cluster); ++ start_data_sect = reserved + fat_size; ++ ++ next = root_cluster; ++ maxloop = 100; ++ while (--maxloop) { ++ uint32_t next_sect_off; ++ uint64_t next_off; ++ uint64_t fat_entry_off; ++ int count; ++ ++ dbg("next cluster %u", next); ++ next_sect_off = (next - 2) * vs->sectors_per_cluster; ++ next_off = (start_data_sect + next_sect_off) * sector_size; ++ dbg("cluster offset 0x%llx", (unsigned long long) next_off); ++ ++ /* get cluster */ ++ buf = volume_id_get_buffer(id, off + next_off, buf_size); ++ if (buf == NULL) ++ goto found; ++ ++ direntry = (struct vfat_dir_entry*) buf; ++ count = buf_size / sizeof(struct vfat_dir_entry); ++ dbg("expected entries 0x%x", count); ++ ++ fnlen = get_fat_attr_volume_id(filename, sizeof(filename), direntry, count); ++ if (fnlen > 0) ++ break; ++ ++ /* get FAT entry */ ++ fat_entry_off = (reserved * sector_size) + (next * sizeof(uint32_t)); ++ buf = volume_id_get_buffer(id, off + fat_entry_off, buf_size); ++ if (buf == NULL) ++ goto found; ++ ++ /* set next cluster */ ++ next = le32_to_cpu(*((uint32_t *) buf)) & 0x0fffffff; ++ if (next < 2 || next >= 0x0ffffff0) ++ break; ++ } ++ if (maxloop == 0) ++ dbg("reached maximum follow count of root cluster chain, give up"); ++ ++ vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); ++ if (vs == NULL) ++ return -1; ++ ++ if (fnlen > 0 && memcmp((char*)filename, "NO NAME ", 11) != 0) { ++ volume_id_set_label_raw(id, filename, fnlen); ++ volume_id_set_label_string(id, filename, fnlen); ++ } else if (memcmp((char*)vs->type.fat32.label, "NO NAME ", 11) != 0) { ++ volume_id_set_label_raw(id, vs->type.fat32.label, 11); ++ volume_id_set_label_string(id, vs->type.fat32.label, 11); ++ } ++ volume_id_set_uuid(id, vs->type.fat32.serno, 0, UUID_DOS); ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "vfat"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/gfs.c' +--- grub-0.97.orig/libvolume_id/gfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/gfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,115 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2006 Red Hat, Inc. <redhat.com> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++/* Common gfs/gfs2 constants: */ ++#define GFS_MAGIC 0x01161970 ++#define GFS_DEFAULT_BSIZE 4096 ++#define GFS_SUPERBLOCK_OFFSET (0x10 * GFS_DEFAULT_BSIZE) ++#define GFS_METATYPE_SB 1 ++#define GFS_FORMAT_SB 100 ++#define GFS_LOCKNAME_LEN 64 ++ ++/* gfs1 constants: */ ++#define GFS_FORMAT_FS 1309 ++#define GFS_FORMAT_MULTI 1401 ++/* gfs2 constants: */ ++#define GFS2_FORMAT_FS 1801 ++#define GFS2_FORMAT_MULTI 1900 ++ ++struct gfs2_meta_header { ++ uint32_t mh_magic; ++ uint32_t mh_type; ++ uint64_t __pad0; /* Was generation number in gfs1 */ ++ uint32_t mh_format; ++ uint32_t __pad1; /* Was incarnation number in gfs1 */ ++}; ++ ++struct gfs2_inum { ++ uint64_t no_formal_ino; ++ uint64_t no_addr; ++}; ++ ++struct gfs2_sb { ++ struct gfs2_meta_header sb_header; ++ ++ uint32_t sb_fs_format; ++ uint32_t sb_multihost_format; ++ uint32_t __pad0; /* Was superblock flags in gfs1 */ ++ ++ uint32_t sb_bsize; ++ uint32_t sb_bsize_shift; ++ uint32_t __pad1; /* Was journal segment size in gfs1 */ ++ ++ struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */ ++ struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */ ++ struct gfs2_inum sb_root_dir; ++ ++ char sb_lockproto[GFS_LOCKNAME_LEN]; ++ char sb_locktable[GFS_LOCKNAME_LEN]; ++ /* In gfs1, quota and license dinodes followed */ ++} PACKED; ++ ++static int volume_id_probe_gfs_generic(struct volume_id *id, uint64_t off, int vers) ++{ ++ struct gfs2_sb *sbd; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ sbd = (struct gfs2_sb *) ++ volume_id_get_buffer(id, off + GFS_SUPERBLOCK_OFFSET, sizeof(struct gfs2_sb)); ++ if (sbd == NULL) ++ return -1; ++ ++ if (be32_to_cpu(sbd->sb_header.mh_magic) == GFS_MAGIC && ++ be32_to_cpu(sbd->sb_header.mh_type) == GFS_METATYPE_SB && ++ be32_to_cpu(sbd->sb_header.mh_format) == GFS_FORMAT_SB) { ++ if (vers == 1) { ++ if (be32_to_cpu(sbd->sb_fs_format) != GFS_FORMAT_FS || ++ be32_to_cpu(sbd->sb_multihost_format) != GFS_FORMAT_MULTI) ++ return -1; /* not gfs1 */ ++ id->type = "gfs"; ++ } ++ else if (vers == 2) { ++ if (be32_to_cpu(sbd->sb_fs_format) != GFS2_FORMAT_FS || ++ be32_to_cpu(sbd->sb_multihost_format) != GFS2_FORMAT_MULTI) ++ return -1; /* not gfs2 */ ++ id->type = "gfs2"; ++ } ++ else ++ return -1; ++ strcpy(id->type_version, "1"); ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ return 0; ++ } ++ return -1; ++} ++ ++int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ return volume_id_probe_gfs_generic(id, off, 1); ++} ++ ++int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ return volume_id_probe_gfs_generic(id, off, 2); ++} + +=== added file 'libvolume_id/hfs.c' +--- grub-0.97.orig/libvolume_id/hfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/hfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,318 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct hfs_finder_info{ ++ uint32_t boot_folder; ++ uint32_t start_app; ++ uint32_t open_folder; ++ uint32_t os9_folder; ++ uint32_t reserved; ++ uint32_t osx_folder; ++ uint8_t id[8]; ++} PACKED; ++ ++static struct hfs_mdb { ++ uint8_t signature[2]; ++ uint32_t cr_date; ++ uint32_t ls_Mod; ++ uint16_t atrb; ++ uint16_t nm_fls; ++ uint16_t vbm_st; ++ uint16_t alloc_ptr; ++ uint16_t nm_al_blks; ++ uint32_t al_blk_size; ++ uint32_t clp_size; ++ uint16_t al_bl_st; ++ uint32_t nxt_cnid; ++ uint16_t free_bks; ++ uint8_t label_len; ++ uint8_t label[27]; ++ uint32_t vol_bkup; ++ uint16_t vol_seq_num; ++ uint32_t wr_cnt; ++ uint32_t xt_clump_size; ++ uint32_t ct_clump_size; ++ uint16_t num_root_dirs; ++ uint32_t file_count; ++ uint32_t dir_count; ++ struct hfs_finder_info finder_info; ++ uint8_t embed_sig[2]; ++ uint16_t embed_startblock; ++ uint16_t embed_blockcount; ++} PACKED *hfs; ++ ++struct hfsplus_bnode_descriptor { ++ uint32_t next; ++ uint32_t prev; ++ uint8_t type; ++ uint8_t height; ++ uint16_t num_recs; ++ uint16_t reserved; ++} PACKED; ++ ++struct hfsplus_bheader_record { ++ uint16_t depth; ++ uint32_t root; ++ uint32_t leaf_count; ++ uint32_t leaf_head; ++ uint32_t leaf_tail; ++ uint16_t node_size; ++} PACKED; ++ ++struct hfsplus_catalog_key { ++ uint16_t key_len; ++ uint32_t parent_id; ++ uint16_t unicode_len; ++ uint8_t unicode[255 * 2]; ++} PACKED; ++ ++struct hfsplus_extent { ++ uint32_t start_block; ++ uint32_t block_count; ++} PACKED; ++ ++#define HFSPLUS_EXTENT_COUNT 8 ++struct hfsplus_fork { ++ uint64_t total_size; ++ uint32_t clump_size; ++ uint32_t total_blocks; ++ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; ++} PACKED; ++ ++static struct hfsplus_vol_header { ++ uint8_t signature[2]; ++ uint16_t version; ++ uint32_t attributes; ++ uint32_t last_mount_vers; ++ uint32_t reserved; ++ uint32_t create_date; ++ uint32_t modify_date; ++ uint32_t backup_date; ++ uint32_t checked_date; ++ uint32_t file_count; ++ uint32_t folder_count; ++ uint32_t blocksize; ++ uint32_t total_blocks; ++ uint32_t free_blocks; ++ uint32_t next_alloc; ++ uint32_t rsrc_clump_sz; ++ uint32_t data_clump_sz; ++ uint32_t next_cnid; ++ uint32_t write_count; ++ uint64_t encodings_bmp; ++ struct hfs_finder_info finder_info; ++ struct hfsplus_fork alloc_file; ++ struct hfsplus_fork ext_file; ++ struct hfsplus_fork cat_file; ++ struct hfsplus_fork attr_file; ++ struct hfsplus_fork start_file; ++} PACKED *hfsplus; ++ ++#define HFS_SUPERBLOCK_OFFSET 0x400 ++#define HFS_NODE_LEAF 0xff ++#define HFSPLUS_POR_CNID 1 ++ ++static void hfsid_set_uuid(struct volume_id *id, const uint8_t *hfs_id) ++{ ++#if 0 ++ MD5_CTX md5c; ++ static const uint8_t hash_init[16] = { ++ 0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6, ++ 0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac ++ }; ++ uint8_t uuid[16]; ++ ++ if (*((uint64_t *)hfs_id) == 0) ++ return; ++ ++ MD5_Init(&md5c); ++ MD5_Update(&md5c, &hash_init, 16); ++ MD5_Update(&md5c, hfs_id, 8); ++ MD5_Final(uuid, &md5c); ++ ++ uuid[6] = 0x30 | (uuid[6] & 0x0f); ++ uuid[8] = 0x80 | (uuid[8] & 0x3f); ++ volume_id_set_uuid(id, uuid, UUID_DCE); ++#endif ++ ++ volume_id_set_uuid(id, hfs_id, 0, UUID_64BIT_BE); ++} ++ ++int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ unsigned int blocksize; ++ unsigned int cat_block; ++ unsigned int ext_block_start; ++ unsigned int ext_block_count; ++ int ext; ++ unsigned int leaf_node_head; ++ unsigned int leaf_node_count; ++ unsigned int leaf_node_size; ++ unsigned int leaf_block; ++ uint64_t leaf_off; ++ unsigned int alloc_block_size; ++ unsigned int alloc_first_block; ++ unsigned int embed_first_block; ++ unsigned int record_count; ++ struct hfsplus_bnode_descriptor *descr; ++ struct hfsplus_bheader_record *bnode; ++ struct hfsplus_catalog_key *key; ++ unsigned int label_len; ++ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; ++ const uint8_t *buf; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ hfs = (struct hfs_mdb *) buf; ++ if (memcmp((char *)hfs->signature, "BD", 2) != 0) ++ goto checkplus; ++ ++ /* it may be just a hfs wrapper for hfs+ */ ++ if (memcmp((char *)hfs->embed_sig, "H+", 2) == 0) { ++ alloc_block_size = be32_to_cpu(hfs->al_blk_size); ++ dbg("alloc_block_size 0x%x", alloc_block_size); ++ ++ alloc_first_block = be16_to_cpu(hfs->al_bl_st); ++ dbg("alloc_first_block 0x%x", alloc_first_block); ++ ++ embed_first_block = be16_to_cpu(hfs->embed_startblock); ++ dbg("embed_first_block 0x%x", embed_first_block); ++ ++ off += (alloc_first_block * 512) + ++ (embed_first_block * alloc_block_size); ++ dbg("hfs wrapped hfs+ found at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); ++ if (buf == NULL) ++ return -1; ++ goto checkplus; ++ } ++ ++ if (hfs->label_len > 0 && hfs->label_len < 28) { ++ volume_id_set_label_raw(id, hfs->label, hfs->label_len); ++ volume_id_set_label_string(id, hfs->label, hfs->label_len) ; ++ } ++ ++ hfsid_set_uuid(id, hfs->finder_info.id); ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "hfs"; ++ ++ return 0; ++ ++checkplus: ++ hfsplus = (struct hfsplus_vol_header *) buf; ++ if (memcmp((char *)hfsplus->signature, "H+", 2) == 0) ++ goto hfsplus; ++ if (memcmp((char *)hfsplus->signature, "HX", 2) == 0) ++ goto hfsplus; ++ return -1; ++ ++hfsplus: ++ hfsid_set_uuid(id, hfsplus->finder_info.id); ++ ++ blocksize = be32_to_cpu(hfsplus->blocksize); ++ dbg("blocksize %u", blocksize); ++ ++ memcpy(extents, hfsplus->cat_file.extents, sizeof(extents)); ++ cat_block = be32_to_cpu(extents[0].start_block); ++ dbg("catalog start block 0x%x", cat_block); ++ ++ buf = volume_id_get_buffer(id, off + (cat_block * blocksize), 0x2000); ++ if (buf == NULL) ++ goto found; ++ ++ bnode = (struct hfsplus_bheader_record *) ++ &buf[sizeof(struct hfsplus_bnode_descriptor)]; ++ ++ leaf_node_head = be32_to_cpu(bnode->leaf_head); ++ dbg("catalog leaf node 0x%x", leaf_node_head); ++ ++ leaf_node_size = be16_to_cpu(bnode->node_size); ++ dbg("leaf node size 0x%x", leaf_node_size); ++ ++ leaf_node_count = be32_to_cpu(bnode->leaf_count); ++ dbg("leaf node count 0x%x", leaf_node_count); ++ if (leaf_node_count == 0) ++ goto found; ++ ++ leaf_block = (leaf_node_head * leaf_node_size) / blocksize; ++ ++ /* get physical location */ ++ for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) { ++ ext_block_start = be32_to_cpu(extents[ext].start_block); ++ ext_block_count = be32_to_cpu(extents[ext].block_count); ++ dbg("extent start block 0x%x, count 0x%x", ext_block_start, ext_block_count); ++ ++ if (ext_block_count == 0) ++ goto found; ++ ++ /* this is our extent */ ++ if (leaf_block < ext_block_count) ++ break; ++ ++ leaf_block -= ext_block_count; ++ } ++ if (ext == HFSPLUS_EXTENT_COUNT) ++ goto found; ++ dbg("found block in extent %i", ext); ++ ++ leaf_off = (ext_block_start + leaf_block) * blocksize; ++ ++ buf = volume_id_get_buffer(id, off + leaf_off, leaf_node_size); ++ if (buf == NULL) ++ goto found; ++ ++ descr = (struct hfsplus_bnode_descriptor *) buf; ++ dbg("descriptor type 0x%x", descr->type); ++ ++ record_count = be16_to_cpu(descr->num_recs); ++ dbg("number of records %u", record_count); ++ if (record_count == 0) ++ goto found; ++ ++ if (descr->type != HFS_NODE_LEAF) ++ goto found; ++ ++ key = (struct hfsplus_catalog_key *) ++ &buf[sizeof(struct hfsplus_bnode_descriptor)]; ++ ++ dbg("parent id 0x%x", be32_to_cpu(key->parent_id)); ++ if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID) ++ goto found; ++ ++ label_len = be16_to_cpu(key->unicode_len) * 2; ++ dbg("label unicode16 len %i", label_len); ++ volume_id_set_label_raw(id, key->unicode, label_len); ++ volume_id_set_label_unicode16(id, key->unicode, BE, label_len); ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "hfsplus"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/highpoint.c' +--- grub-0.97.orig/libvolume_id/highpoint.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/highpoint.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,91 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct hpt37x_meta { ++ uint8_t filler1[32]; ++ uint32_t magic; ++} PACKED; ++ ++struct hpt45x_meta { ++ uint32_t magic; ++} PACKED; ++ ++#define HPT37X_CONFIG_OFF 0x1200 ++#define HPT37X_MAGIC_OK 0x5a7816f0 ++#define HPT37X_MAGIC_BAD 0x5a7816fd ++ ++#define HPT45X_MAGIC_OK 0x5a7816f3 ++#define HPT45X_MAGIC_BAD 0x5a7816fd ++ ++ ++int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ struct hpt37x_meta *hpt; ++ uint32_t magic; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ hpt = (struct hpt37x_meta *) buf; ++ magic = le32_to_cpu(hpt->magic); ++ if (magic != HPT37X_MAGIC_OK && magic != HPT37X_MAGIC_BAD) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "highpoint_raid_member"; ++ ++ return 0; ++} ++ ++int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ struct hpt45x_meta *hpt; ++ uint64_t meta_off; ++ uint32_t magic; ++ ++ dbg("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-11) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ hpt = (struct hpt45x_meta *) buf; ++ magic = le32_to_cpu(hpt->magic); ++ if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "highpoint_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/hpfs.c' +--- grub-0.97.orig/libvolume_id/hpfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/hpfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,51 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct hpfs_super ++{ ++ uint8_t magic[4]; ++ uint8_t version; ++} PACKED; ++ ++#define HPFS_SUPERBLOCK_OFFSET 0x2000 ++ ++int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct hpfs_super *hs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ hs = (struct hpfs_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_OFFSET, 0x200); ++ if (hs == NULL) ++ return -1; ++ ++ if (memcmp((char *)hs->magic, "\x49\xe8\x95\xf9", 4) == 0) { ++ sprintf(id->type_version, "%u", hs->version); ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "hpfs"; ++ return 0; ++ } ++ ++ return -1; ++} + +=== added file 'libvolume_id/iso9660.c' +--- grub-0.97.orig/libvolume_id/iso9660.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/iso9660.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,119 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define ISO_SUPERBLOCK_OFFSET 0x8000 ++#define ISO_SECTOR_SIZE 0x800 ++#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE) ++#define ISO_VD_PRIMARY 0x1 ++#define ISO_VD_SUPPLEMENTARY 0x2 ++#define ISO_VD_END 0xff ++#define ISO_VD_MAX 16 ++ ++struct iso_volume_descriptor { ++ uint8_t type; ++ uint8_t id[5]; ++ uint8_t version; ++ uint8_t flags; ++ uint8_t system_id[32]; ++ uint8_t volume_id[32]; ++ uint8_t unused[8]; ++ uint8_t space_size[8]; ++ uint8_t escape_sequences[8]; ++} PACKED; ++ ++struct high_sierra_volume_descriptor { ++ uint8_t foo[8]; ++ uint8_t type; ++ uint8_t id[5]; ++ uint8_t version; ++} PACKED; ++ ++int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ uint8_t *buf; ++ struct iso_volume_descriptor *is; ++ struct high_sierra_volume_descriptor *hs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ is = (struct iso_volume_descriptor *) buf; ++ ++ if (memcmp((char*)is->id, "CD001", 5) == 0) { ++ int vd_offset; ++ int i; ++ ++ dbg("read label from PVD"); ++ volume_id_set_label_raw(id, is->volume_id, 32); ++ volume_id_set_label_string(id, is->volume_id, 32); ++ ++ dbg("looking for SVDs"); ++ vd_offset = ISO_VD_OFFSET; ++ for (i = 0; i < ISO_VD_MAX; i++) { ++ uint8_t svd_label[64]; ++ ++ is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200); ++ if (is == NULL || is->type == ISO_VD_END) ++ break; ++ if (is->type != ISO_VD_SUPPLEMENTARY) ++ continue; ++ ++ dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset)); ++ if (memcmp((char *)is->escape_sequences, "%/@", 3) == 0|| ++ memcmp((char *)is->escape_sequences, "%/C", 3) == 0|| ++ memcmp((char *)is->escape_sequences, "%/E", 3) == 0) { ++ dbg("Joliet extension found"); ++ volume_id_set_unicode16(svd_label, sizeof(svd_label), is->volume_id, BE, 32); ++ if (memcmp((char *)id->label, (char *)svd_label, 16) == 0) { ++ dbg("SVD label is identical, use the possibly longer PVD one"); ++ break; ++ } ++ ++ volume_id_set_label_raw(id, is->volume_id, 32); ++ volume_id_set_label_string(id, svd_label, 32); ++ strcpy(id->type_version, "Joliet Extension"); ++ goto found; ++ } ++ vd_offset += ISO_SECTOR_SIZE; ++ } ++ goto found; ++ } ++ ++ hs = (struct high_sierra_volume_descriptor *) buf; ++ ++ if (memcmp((char *)hs->id, "CDROM", 5) == 0) { ++ strcpy(id->type_version, "High Sierra"); ++ goto found; ++ } ++ ++ return -1; ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "iso9660"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/isw_raid.c' +--- grub-0.97.orig/libvolume_id/isw_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/isw_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,61 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct isw_meta { ++ uint8_t sig[32]; ++ uint32_t check_sum; ++ uint32_t mpb_size; ++ uint32_t family_num; ++ uint32_t generation_num; ++} PACKED; ++ ++#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " ++ ++ ++int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct isw_meta *isw; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-2) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ isw = (struct isw_meta *) buf; ++ if (memcmp((char *)isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ memcpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); ++ id->type = "isw_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/jfs.c' +--- grub-0.97.orig/libvolume_id/jfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/jfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,60 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct jfs_super_block { ++ uint8_t magic[4]; ++ uint32_t version; ++ uint64_t size; ++ uint32_t bsize; ++ uint32_t dummy1; ++ uint32_t pbsize; ++ uint32_t dummy2[27]; ++ uint8_t uuid[16]; ++ uint8_t label[16]; ++ uint8_t loguuid[16]; ++} PACKED; ++ ++#define JFS_SUPERBLOCK_OFFSET 0x8000 ++ ++int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct jfs_super_block *js; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); ++ if (js == NULL) ++ return -1; ++ ++ if (memcmp((char *)js->magic, "JFS1", 4) != 0) ++ return -1; ++ ++ volume_id_set_label_raw(id, js->label, 16); ++ volume_id_set_label_string(id, js->label, 16); ++ volume_id_set_uuid(id, js->uuid, 0, UUID_DCE); ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "jfs"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/jmicron_raid.c' +--- grub-0.97.orig/libvolume_id/jmicron_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/jmicron_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,57 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct jmicron_meta { ++ int8_t signature[2]; ++ uint8_t minor_version; ++ uint8_t major_version; ++ uint16_t checksum; ++} PACKED; ++ ++int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct jmicron_meta *jm; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-1) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ jm = (struct jmicron_meta *) buf; ++ if (memcmp((char *)jm->signature, "JM", 2) != 0) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ sprintf(id->type_version, "%u.%u", jm->major_version, jm->minor_version); ++ id->type = "jmicron_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/linux_raid.c' +--- grub-0.97.orig/libvolume_id/linux_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/linux_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,160 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++static struct mdp0_super_block { ++ uint32_t md_magic; ++ uint32_t major_version; ++ uint32_t minor_version; ++ uint32_t patch_version; ++ uint32_t gvalid_words; ++ uint32_t set_uuid0; ++ uint32_t ctime; ++ uint32_t level; ++ uint32_t size; ++ uint32_t nr_disks; ++ uint32_t raid_disks; ++ uint32_t md_minor; ++ uint32_t not_persistent; ++ uint32_t set_uuid1; ++ uint32_t set_uuid2; ++ uint32_t set_uuid3; ++} PACKED *mdp0; ++ ++struct mdp1_super_block { ++ uint32_t magic; ++ uint32_t major_version; ++ uint32_t feature_map; ++ uint32_t pad0; ++ uint8_t set_uuid[16]; ++ uint8_t set_name[32]; ++} PACKED *mdp1; ++ ++#define MD_RESERVED_BYTES 0x10000 ++#define MD_SB_MAGIC 0xa92b4efc ++ ++static int volume_id_probe_linux_raid0(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ union { ++ uint32_t ints[4]; ++ uint8_t bytes[16]; ++ } uuid; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ if (size < 0x10000) ++ return -1; ++ ++ buf = volume_id_get_buffer(id, off, 0x800); ++ if (buf == NULL) ++ return -1; ++ mdp0 = (struct mdp0_super_block *) buf; ++ ++ if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { ++ uuid.ints[0] = bswap_32(mdp0->set_uuid0); ++ if (le32_to_cpu(mdp0->minor_version >= 90)) { ++ uuid.ints[1] = bswap_32(mdp0->set_uuid1); ++ uuid.ints[2] = bswap_32(mdp0->set_uuid2); ++ uuid.ints[3] = bswap_32(mdp0->set_uuid3); ++ } else { ++ uuid.ints[1] = 0; ++ uuid.ints[2] = 0; ++ uuid.ints[3] = 0; ++ } ++ volume_id_set_uuid(id, uuid.bytes, 0, UUID_FOURINT); ++ sprintf(id->type_version, "%u.%u.%u", ++ le32_to_cpu(mdp0->major_version), ++ le32_to_cpu(mdp0->minor_version), ++ le32_to_cpu(mdp0->patch_version)); ++ } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { ++ uuid.ints[0] = mdp0->set_uuid0; ++ if (be32_to_cpu(mdp0->minor_version >= 90)) { ++ uuid.ints[1] = mdp0->set_uuid1; ++ uuid.ints[2] = mdp0->set_uuid2; ++ uuid.ints[3] = mdp0->set_uuid3; ++ } else { ++ uuid.ints[1] = 0; ++ uuid.ints[2] = 0; ++ uuid.ints[3] = 0; ++ } ++ volume_id_set_uuid(id, uuid.bytes, 0, UUID_FOURINT); ++ sprintf(id->type_version, "%u.%u.%u", ++ be32_to_cpu(mdp0->major_version), ++ be32_to_cpu(mdp0->minor_version), ++ be32_to_cpu(mdp0->patch_version)); ++ } else ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "linux_raid_member"; ++ return 0; ++} ++ ++static int volume_id_probe_linux_raid1(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ buf = volume_id_get_buffer(id, off, 0x800); ++ if (buf == NULL) ++ return -1; ++ mdp1 = (struct mdp1_super_block *) buf; ++ ++ if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC) ++ return -1; ++ ++ volume_id_set_uuid(id, mdp1->set_uuid, 0, UUID_FOURINT); ++ volume_id_set_label_raw(id, mdp1->set_name, 32); ++ volume_id_set_label_string(id, mdp1->set_name, 32); ++ sprintf(id->type_version, "%u", le32_to_cpu(mdp1->major_version)); ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "linux_raid_member"; ++ return 0; ++} ++ ++int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ uint64_t sboff; ++ ++ /* version 0 at the end of the device */ ++ sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; ++ if (volume_id_probe_linux_raid0(id, off + sboff, size) == 0) ++ return 0; ++ ++ /* version 1.0 at the end of the device */ ++ sboff = (size & ~(0x1000 - 1)) - 0x2000; ++ if (volume_id_probe_linux_raid1(id, off + sboff, size) == 0) ++ return 0; ++ ++ /* version 1.1 at the start of the device */ ++ if (volume_id_probe_linux_raid1(id, off, size) == 0) ++ return 0; ++ ++ /* version 1.2 at 4k offset from the start */ ++ if (volume_id_probe_linux_raid1(id, off + 0x1000, size) == 0) ++ return 0; ++ ++ return -1; ++} + +=== added file 'libvolume_id/linux_swap.c' +--- grub-0.97.orig/libvolume_id/linux_swap.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/linux_swap.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,85 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct swap_header_v1_2 { ++ uint8_t bootbits[1024]; ++ uint32_t version; ++ uint32_t last_page; ++ uint32_t nr_badpages; ++ uint8_t uuid[16]; ++ uint8_t volume_name[16]; ++} PACKED; ++ ++#define LARGEST_PAGESIZE 0x4000 ++ ++int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ unsigned int page; ++ struct swap_header_v1_2 *sw; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ /* eek, the swap signature is at the end of the PAGE_SIZE */ ++ for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { ++ buf = volume_id_get_buffer(id, off + page-10, 10); ++ if (buf == NULL) ++ return -1; ++ ++ if (memcmp((char *)buf, "SWAP-SPACE", 10) == 0) { ++ strcpy(id->type_version, "1"); ++ goto found; ++ } ++ ++ if (memcmp((char *)buf, "SWAPSPACE2", 10) == 0) { ++ id->type = "swap"; ++ strcpy(id->type_version, "2"); ++ goto found_label; ++ } ++ ++ if (memcmp((char *)buf, "S1SUSPEND", 9) == 0) { ++ id->type = "suspend"; ++ strcpy(id->type_version, "s1suspend"); ++ goto found_label; ++ } ++ ++ if (memcmp((char *)buf, "ULSUSPEND", 9) == 0) { ++ id->type = "suspend"; ++ strcpy(id->type_version, "ulsuspend"); ++ goto found_label; ++ } ++ } ++ return -1; ++ ++found_label: ++ sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); ++ if (sw != NULL) { ++ volume_id_set_label_raw(id, sw->volume_name, 16); ++ volume_id_set_label_string(id, sw->volume_name, 16); ++ volume_id_set_uuid(id, sw->uuid, 0, UUID_DCE); ++ } ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_OTHER); ++ return 0; ++} + +=== added file 'libvolume_id/lsi_raid.c' +--- grub-0.97.orig/libvolume_id/lsi_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/lsi_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,55 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct lsi_meta { ++ uint8_t sig[6]; ++} PACKED; ++ ++#define LSI_SIGNATURE "$XIDE$" ++ ++int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct lsi_meta *lsi; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-1) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ lsi = (struct lsi_meta *) buf; ++ if (memcmp((char *)lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "lsi_mega_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/luks.c' +--- grub-0.97.orig/libvolume_id/luks.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/luks.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,76 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 W. Michael Petullo <mike@flyn.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define LUKS_SECTOR_SHIFT 9 ++#define LUKS_SECTOR_SIZE (1 << LUKS_SECTOR_SHIFT) ++ ++#define LUKS_CIPHERNAME_L 32 ++#define LUKS_CIPHERMODE_L 32 ++#define LUKS_HASHSPEC_L 32 ++#define LUKS_DIGESTSIZE 20 ++#define LUKS_SALTSIZE 32 ++#define LUKS_NUMKEYS 8 ++ ++#define LUKS_MAGIC_L 6 ++#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/LUKS_SECTOR_SIZE+1) ++#define UUID_STRING_L 40 ++static const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; ++ ++struct luks_phdr { ++ uint8_t magic[LUKS_MAGIC_L]; ++ uint16_t version; ++ uint8_t cipherName[LUKS_CIPHERNAME_L]; ++ uint8_t cipherMode[LUKS_CIPHERMODE_L]; ++ uint8_t hashSpec[LUKS_HASHSPEC_L]; ++ uint32_t payloadOffset; ++ uint32_t keyBytes; ++ uint8_t mkDigest[LUKS_DIGESTSIZE]; ++ uint8_t mkDigestSalt[LUKS_SALTSIZE]; ++ uint32_t mkDigestIterations; ++ uint8_t uuid[UUID_STRING_L]; ++ struct { ++ uint32_t active; ++ uint32_t passwordIterations; ++ uint8_t passwordSalt[LUKS_SALTSIZE]; ++ uint32_t keyMaterialOffset; ++ uint32_t stripes; ++ } keyblock[LUKS_NUMKEYS]; ++}; ++ ++int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct luks_phdr *header; ++ ++ header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE); ++ if (header == NULL) ++ return -1; ++ ++ if (memcmp((char *)header->magic, (char *)LUKS_MAGIC, LUKS_MAGIC_L)) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_CRYPTO); ++ volume_id_set_uuid(id, header->uuid, 36, UUID_HEX_STRING); ++ sprintf(id->type_version, "%u", le16_to_cpu(header->version)); ++ id->type = "crypto_LUKS"; ++ return 0; ++} + +=== added file 'libvolume_id/lvm.c' +--- grub-0.97.orig/libvolume_id/lvm.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/lvm.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,92 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct lvm1_super_block { ++ uint8_t id[2]; ++} PACKED; ++ ++struct lvm2_super_block { ++ uint8_t id[8]; ++ uint64_t sector_xl; ++ uint32_t crc_xl; ++ uint32_t offset_xl; ++ uint8_t type[8]; ++} PACKED; ++ ++#define LVM1_SB_OFF 0x400 ++#define LVM1_MAGIC "HM" ++ ++int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ struct lvm1_super_block *lvm; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); ++ if (buf == NULL) ++ return -1; ++ ++ lvm = (struct lvm1_super_block *) buf; ++ ++ if (memcmp((char *)lvm->id, LVM1_MAGIC, 2) != 0) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "LVM1_member"; ++ ++ return 0; ++} ++ ++#define LVM2_LABEL_ID "LABELONE" ++#define LVM2LABEL_SCAN_SECTORS 4 ++ ++int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ unsigned int soff; ++ struct lvm2_super_block *lvm; ++ ++ dbg("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ ++ for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { ++ lvm = (struct lvm2_super_block *) &buf[soff]; ++ ++ if (memcmp((char *)lvm->id, LVM2_LABEL_ID, 8) == 0) ++ goto found; ++ } ++ ++ return -1; ++ ++found: ++ memcpy(id->type_version, lvm->type, 8); ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "LVM2_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/minix.c' +--- grub-0.97.orig/libvolume_id/minix.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/minix.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,112 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define MINIX_SUPERBLOCK_OFFSET 0x400 ++ ++#define MINIX_SUPER_MAGIC 0x137F ++#define MINIX_SUPER_MAGIC2 0x138F ++#define MINIX2_SUPER_MAGIC 0x2468 ++#define MINIX2_SUPER_MAGIC2 0x2478 ++#define MINIX3_SUPER_MAGIC 0x4d5a ++ ++struct minix_super_block ++{ ++ uint16_t s_ninodes; ++ uint16_t s_nzones; ++ uint16_t s_imap_blocks; ++ uint16_t s_zmap_blocks; ++ uint16_t s_firstdatazone; ++ uint16_t s_log_zone_size; ++ uint32_t s_max_size; ++ uint16_t s_magic; ++ uint16_t s_state; ++ uint32_t s_zones; ++} PACKED; ++ ++struct minix3_super_block { ++ uint32_t s_ninodes; ++ uint16_t s_pad0; ++ uint16_t s_imap_blocks; ++ uint16_t s_zmap_blocks; ++ uint16_t s_firstdatazone; ++ uint16_t s_log_zone_size; ++ uint16_t s_pad1; ++ uint32_t s_max_size; ++ uint32_t s_zones; ++ uint16_t s_magic; ++ uint16_t s_pad2; ++ uint16_t s_blocksize; ++ uint8_t s_disk_version; ++} PACKED; ++ ++int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ uint8_t *buf; ++ struct minix_super_block *ms; ++ struct minix3_super_block *m3s; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ ms = (struct minix_super_block *) buf; ++ ++ if (ms->s_magic == MINIX_SUPER_MAGIC || ++ ms->s_magic == bswap_16(MINIX_SUPER_MAGIC)) { ++ strcpy(id->type_version, "1"); ++ goto found; ++ } ++ if (ms->s_magic == MINIX_SUPER_MAGIC2 || ++ ms->s_magic == bswap_16(MINIX_SUPER_MAGIC2)) { ++ strcpy(id->type_version, "1"); ++ goto found; ++ } ++ if (ms->s_magic == MINIX2_SUPER_MAGIC || ++ ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC)) { ++ strcpy(id->type_version, "2"); ++ goto found; ++ } ++ if (ms->s_magic == MINIX2_SUPER_MAGIC2 || ++ ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC2)) { ++ strcpy(id->type_version, "2"); ++ goto found; ++ } ++ ++ m3s = (struct minix3_super_block *) buf; ++ if (m3s->s_magic == MINIX3_SUPER_MAGIC || ++ m3s->s_magic == bswap_16(MINIX3_SUPER_MAGIC)) { ++ strcpy(id->type_version, "3"); ++ goto found; ++ } ++ goto exit; ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "minix"; ++ return 0; ++ ++exit: ++ return -1; ++} + +=== added file 'libvolume_id/misc.c' +--- grub-0.97.orig/libvolume_id/misc.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/misc.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,34 @@ ++/* ++ * volume_id/misc.c ++ * ++ * Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++#define _GNU_SOURCE ++#include <string.h> ++ ++/* ++ * Misc auxiliary functions required for volume_id inside grub ++ */ ++size_t strnlen(const char *s, size_t limit) ++{ ++ size_t length = 0; ++ while ( (length < limit) && (*s++) ) ++ length++; ++ ++ return length; ++} ++ ++char *strchr (const char *s, int c) ++{ ++ do { ++ if ( *s == c ) { ++ return (char*)s; ++ } ++ } while ( *s++ ); ++ ++ return 0; ++} + +=== added file 'libvolume_id/netware.c' +--- grub-0.97.orig/libvolume_id/netware.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/netware.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,98 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define NW_SUPERBLOCK_OFFSET 0x1000 ++ ++struct netware_super_block { ++ uint8_t SBH_Signature[4]; ++ uint16_t SBH_VersionMajor; ++ uint16_t SBH_VersionMinor; ++ uint16_t SBH_VersionMediaMajor; ++ uint16_t SBH_VersionMediaMinor; ++ uint32_t SBH_ItemsMoved; ++ uint8_t SBH_InternalID[16]; ++ uint32_t SBH_PackedSize; ++ uint32_t SBH_Checksum; ++ uint32_t supersyncid; ++ int64_t superlocation[4]; ++ uint32_t physSizeUsed; ++ uint32_t sizeUsed; ++ uint32_t superTimeStamp; ++ uint32_t reserved0[1]; ++ int64_t SBH_LoggedPoolDataBlk; ++ int64_t SBH_PoolDataBlk; ++ uint8_t SBH_OldInternalID[16]; ++ uint32_t SBH_PoolToLVStartUTC; ++ uint32_t SBH_PoolToLVEndUTC; ++ uint16_t SBH_VersionMediaMajorCreate; ++ uint16_t SBH_VersionMediaMinorCreate; ++ uint32_t SBH_BlocksMoved; ++ uint32_t SBH_TempBTSpBlk; ++ uint32_t SBH_TempFTSpBlk; ++ uint32_t SBH_TempFTSpBlk1; ++ uint32_t SBH_TempFTSpBlk2; ++ uint32_t nssMagicNumber; ++ uint32_t poolClassID; ++ uint32_t poolID; ++ uint32_t createTime; ++ int64_t SBH_LoggedVolumeDataBlk; ++ int64_t SBH_VolumeDataBlk; ++ int64_t SBH_SystemBeastBlkNum; ++ uint64_t totalblocks; ++ uint16_t SBH_Name[64]; ++ uint8_t SBH_VolumeID[16]; ++ uint8_t SBH_PoolID[16]; ++ uint8_t SBH_PoolInternalID[16]; ++ uint64_t SBH_Lsn; ++ uint32_t SBH_SS_Enabled; ++ uint32_t SBH_SS_CreateTime; ++ uint8_t SBH_SS_OriginalPoolID[16]; ++ uint8_t SBH_SS_OriginalVolumeID[16]; ++ uint8_t SBH_SS_Guid[16]; ++ uint16_t SBH_SS_OriginalName[64]; ++ uint32_t reserved2[64-(2+46)]; ++} PACKED; ++ ++int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct netware_super_block *nw; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ nw = (struct netware_super_block *) volume_id_get_buffer(id, off + NW_SUPERBLOCK_OFFSET, 0x200); ++ if (nw == NULL) ++ return -1; ++ ++ if (memcmp((char *)nw->SBH_Signature, "SPB5", 4) != 0) ++ return -1; ++ ++ volume_id_set_uuid(id, nw->SBH_PoolID, 0, UUID_DCE); ++ ++ sprintf(id->type_version, "%u.%02u", ++ le16_to_cpu(nw->SBH_VersionMediaMajor), le16_to_cpu(nw->SBH_VersionMediaMinor)); ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "nss"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/ntfs.c' +--- grub-0.97.orig/libvolume_id/ntfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/ntfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,192 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++static struct ntfs_super_block { ++ uint8_t jump[3]; ++ uint8_t oem_id[8]; ++ uint16_t bytes_per_sector; ++ uint8_t sectors_per_cluster; ++ uint16_t reserved_sectors; ++ uint8_t fats; ++ uint16_t root_entries; ++ uint16_t sectors; ++ uint8_t media_type; ++ uint16_t sectors_per_fat; ++ uint16_t sectors_per_track; ++ uint16_t heads; ++ uint32_t hidden_sectors; ++ uint32_t large_sectors; ++ uint16_t unused[2]; ++ uint64_t number_of_sectors; ++ uint64_t mft_cluster_location; ++ uint64_t mft_mirror_cluster_location; ++ int8_t cluster_per_mft_record; ++ uint8_t reserved1[3]; ++ int8_t cluster_per_index_record; ++ uint8_t reserved2[3]; ++ uint8_t volume_serial[8]; ++ uint16_t checksum; ++} PACKED *ns; ++ ++static struct master_file_table_record { ++ uint8_t magic[4]; ++ uint16_t usa_ofs; ++ uint16_t usa_count; ++ uint64_t lsn; ++ uint16_t sequence_number; ++ uint16_t link_count; ++ uint16_t attrs_offset; ++ uint16_t flags; ++ uint32_t bytes_in_use; ++ uint32_t bytes_allocated; ++} PACKED *mftr; ++ ++static struct file_attribute { ++ uint32_t type; ++ uint32_t len; ++ uint8_t non_resident; ++ uint8_t name_len; ++ uint16_t name_offset; ++ uint16_t flags; ++ uint16_t instance; ++ uint32_t value_len; ++ uint16_t value_offset; ++} PACKED *attr; ++ ++static struct volume_info { ++ uint64_t reserved; ++ uint8_t major_ver; ++ uint8_t minor_ver; ++} PACKED *info; ++ ++#define MFT_RECORD_VOLUME 3 ++#define MFT_RECORD_ATTR_VOLUME_NAME 0x60 ++#define MFT_RECORD_ATTR_VOLUME_INFO 0x70 ++#define MFT_RECORD_ATTR_OBJECT_ID 0x40 ++#define MFT_RECORD_ATTR_END 0xffffffffu ++ ++#undef debug ++#define debug grub_printf ++ ++int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ unsigned int sector_size; ++ unsigned int cluster_size; ++ uint64_t mft_cluster; ++ uint64_t mft_off; ++ unsigned int mft_record_size; ++ unsigned int attr_type; ++ unsigned int attr_off; ++ unsigned int attr_len; ++ unsigned int val_off; ++ unsigned int val_len; ++ const uint8_t *buf; ++ const uint8_t *val; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200); ++ if (ns == NULL) ++ return -1; ++ ++ if (memcmp((char *)ns->oem_id, "NTFS", 4) != 0) ++ return -1; ++ ++ volume_id_set_uuid(id, ns->volume_serial, 0, UUID_64BIT_LE); ++ ++ sector_size = le16_to_cpu(ns->bytes_per_sector); ++ if (sector_size < 0x200) ++ return -1; ++ ++ cluster_size = ns->sectors_per_cluster * sector_size; ++ mft_cluster = le64_to_cpu(ns->mft_cluster_location); ++ mft_off = mft_cluster * cluster_size; ++ ++ if (ns->cluster_per_mft_record < 0) ++ /* size = -log2(mft_record_size); normally 1024 Bytes */ ++ mft_record_size = 1 << -ns->cluster_per_mft_record; ++ else ++ mft_record_size = ns->cluster_per_mft_record * cluster_size; ++ ++ dbg("sectorsize 0x%x", sector_size); ++ dbg("clustersize 0x%x", cluster_size); ++ dbg("mftcluster %llu", (unsigned long long) mft_cluster); ++ dbg("mftoffset 0x%llx", (unsigned long long) mft_off); ++ dbg("cluster per mft_record %i", ns->cluster_per_mft_record); ++ dbg("mft record size %i", mft_record_size); ++ ++ buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size), ++ mft_record_size); ++ if (buf == NULL) ++ return -1; ++ ++ mftr = (struct master_file_table_record*) buf; ++ dbg("mftr->magic '%c%c%c%c'", mftr->magic[0], mftr->magic[1], mftr->magic[2], mftr->magic[3]); ++ if (memcmp((char *)mftr->magic, "FILE", 4) != 0) ++ return -1; ++ ++ attr_off = le16_to_cpu(mftr->attrs_offset); ++ dbg("file $Volume's attributes are at offset %i", attr_off); ++ ++ while (1) { ++ attr = (struct file_attribute*) &buf[attr_off]; ++ attr_type = le32_to_cpu(attr->type); ++ attr_len = le16_to_cpu(attr->len); ++ val_off = le16_to_cpu(attr->value_offset); ++ val_len = le32_to_cpu(attr->value_len); ++ attr_off += attr_len; ++ ++ if (attr_len == 0) ++ break; ++ ++ if (attr_off >= mft_record_size) ++ break; ++ ++ if (attr_type == MFT_RECORD_ATTR_END) ++ break; ++ ++ dbg("found attribute type 0x%x, len %i, at offset %i", ++ attr_type, attr_len, attr_off); ++ ++ if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { ++ dbg("found info, len %i", val_len); ++ info = (struct volume_info*) (((uint8_t *) attr) + val_off); ++ sprintf(id->type_version, "%u.%u", info->major_ver, info->minor_ver); ++ } ++ ++ if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { ++ dbg("found label, len %i", val_len); ++ if (val_len > VOLUME_ID_LABEL_SIZE) ++ val_len = VOLUME_ID_LABEL_SIZE; ++ ++ val = ((uint8_t *) attr) + val_off; ++ volume_id_set_label_raw(id, val, val_len); ++ volume_id_set_label_unicode16(id, val, LE, val_len); ++ } ++ } ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "ntfs"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/nvidia_raid.c' +--- grub-0.97.orig/libvolume_id/nvidia_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/nvidia_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,59 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct nvidia_meta { ++ uint8_t vendor[8]; ++ uint32_t size; ++ uint32_t chksum; ++ uint16_t version; ++} PACKED; ++ ++#define NVIDIA_SIGNATURE "NVIDIA" ++ ++int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct nvidia_meta *nv; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-2) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ nv = (struct nvidia_meta *) buf; ++ if (memcmp((char *)nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ sprintf(id->type_version, "%u", le16_to_cpu(nv->version)); ++ id->type = "nvidia_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/ocfs.c' +--- grub-0.97.orig/libvolume_id/ocfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/ocfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,186 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Andre Masella <andre@masella.no-ip.org> ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct ocfs1_super_block_header { ++ uint32_t minor_version; ++ uint32_t major_version; ++ uint8_t signature[128]; ++ uint8_t mount_point[128]; ++ uint64_t serial_num; ++ uint64_t device_size; ++ uint64_t start_off; ++ uint64_t bitmap_off; ++ uint64_t publ_off; ++ uint64_t vote_off; ++ uint64_t root_bitmap_off; ++ uint64_t data_start_off; ++ uint64_t root_bitmap_size; ++ uint64_t root_off; ++ uint64_t root_size; ++ uint64_t cluster_size; ++ uint64_t num_nodes; ++ uint64_t num_clusters; ++ uint64_t dir_node_size; ++ uint64_t file_node_size; ++ uint64_t internal_off; ++ uint64_t node_cfg_off; ++ uint64_t node_cfg_size; ++ uint64_t new_cfg_off; ++ uint32_t prot_bits; ++ int32_t excl_mount; ++} PACKED; ++ ++struct ocfs1_super_block_label { ++ struct ocfs1_disk_lock { ++ uint32_t curr_master; ++ uint8_t file_lock; ++ uint8_t compat_pad[3]; ++ uint64_t last_write_time; ++ uint64_t last_read_time; ++ uint32_t writer_node_num; ++ uint32_t reader_node_num; ++ uint64_t oin_node_map; ++ uint64_t dlock_seq_num; ++ } PACKED disk_lock; ++ uint8_t label[64]; ++ uint16_t label_len; ++ uint8_t vol_id[16]; ++ uint16_t vol_id_len; ++ uint8_t cluster_name[64]; ++ uint16_t cluster_name_len; ++} PACKED; ++ ++struct ocfs2_super_block { ++ uint8_t i_signature[8]; ++ uint32_t i_generation; ++ int16_t i_suballoc_slot; ++ uint16_t i_suballoc_bit; ++ uint32_t i_reserved0; ++ uint32_t i_clusters; ++ uint32_t i_uid; ++ uint32_t i_gid; ++ uint64_t i_size; ++ uint16_t i_mode; ++ uint16_t i_links_count; ++ uint32_t i_flags; ++ uint64_t i_atime; ++ uint64_t i_ctime; ++ uint64_t i_mtime; ++ uint64_t i_dtime; ++ uint64_t i_blkno; ++ uint64_t i_last_eb_blk; ++ uint32_t i_fs_generation; ++ uint32_t i_atime_nsec; ++ uint32_t i_ctime_nsec; ++ uint32_t i_mtime_nsec; ++ uint64_t i_reserved1[9]; ++ uint64_t i_pad1; ++ uint16_t s_major_rev_level; ++ uint16_t s_minor_rev_level; ++ uint16_t s_mnt_count; ++ int16_t s_max_mnt_count; ++ uint16_t s_state; ++ uint16_t s_errors; ++ uint32_t s_checkinterval; ++ uint64_t s_lastcheck; ++ uint32_t s_creator_os; ++ uint32_t s_feature_compat; ++ uint32_t s_feature_incompat; ++ uint32_t s_feature_ro_compat; ++ uint64_t s_root_blkno; ++ uint64_t s_system_dir_blkno; ++ uint32_t s_blocksize_bits; ++ uint32_t s_clustersize_bits; ++ uint16_t s_max_slots; ++ uint16_t s_reserved1; ++ uint32_t s_reserved2; ++ uint64_t s_first_cluster_group; ++ uint8_t s_label[64]; ++ uint8_t s_uuid[16]; ++} PACKED; ++ ++int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ struct ocfs1_super_block_header *osh; ++ struct ocfs1_super_block_label *osl; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ osh = (struct ocfs1_super_block_header *) buf; ++ if (memcmp((char *)osh->signature, "OracleCFS", 9) != 0) ++ return -1; ++ sprintf(id->type_version, "%u.%u", osh->major_version, osh->minor_version); ++ ++ dbg("found OracleCFS signature, now reading label"); ++ buf = volume_id_get_buffer(id, off + 0x200, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ osl = (struct ocfs1_super_block_label *) buf; ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ if (osl->label_len <= 64) { ++ volume_id_set_label_raw(id, osl->label, 64); ++ volume_id_set_label_string(id, osl->label, 64); ++ } ++ if (osl->vol_id_len == 16) ++ volume_id_set_uuid(id, osl->vol_id, 0, UUID_DCE); ++ id->type = "ocfs"; ++ return 0; ++} ++ ++#define OCFS2_MAX_BLOCKSIZE 0x1000 ++#define OCFS2_SUPER_BLOCK_BLKNO 2 ++ ++int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ struct ocfs2_super_block *os; ++ size_t blksize; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ for (blksize = 0x200; blksize <= OCFS2_MAX_BLOCKSIZE; blksize <<= 1) { ++ buf = volume_id_get_buffer(id, off + OCFS2_SUPER_BLOCK_BLKNO * blksize, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ os = (struct ocfs2_super_block *) buf; ++ if (memcmp((char *)os->i_signature, "OCFSV2", 6) != 0) ++ continue; ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ volume_id_set_label_raw(id, os->s_label, 64); ++ volume_id_set_label_string(id, os->s_label, 64); ++ volume_id_set_uuid(id, os->s_uuid, 0, UUID_DCE); ++ sprintf(id->type_version, "%u.%u", os->s_major_rev_level, os->s_minor_rev_level); ++ id->type = "ocfs2"; ++ return 0; ++ } ++ return -1; ++} + +=== added file 'libvolume_id/promise_raid.c' +--- grub-0.97.orig/libvolume_id/promise_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/promise_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,65 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct promise_meta { ++ uint8_t sig[24]; ++} PACKED; ++ ++#define PDC_CONFIG_OFF 0x1200 ++#define PDC_SIGNATURE "Promise Technology, Inc." ++ ++int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ struct promise_meta *pdc; ++ unsigned int i; ++ static unsigned int sectors[] = { ++ 63, 255, 256, 16, 399, 0 ++ }; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x40000) ++ return -1; ++ ++ for (i = 0; sectors[i] != 0; i++) { ++ uint64_t meta_off; ++ ++ meta_off = ((size / 0x200) - sectors[i]) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ pdc = (struct promise_meta *) buf; ++ if (memcmp((char *)pdc->sig, PDC_SIGNATURE, sizeof(PDC_SIGNATURE)-1) == 0) ++ goto found; ++ } ++ return -1; ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ id->type = "promise_fasttrack_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/reiserfs.c' +--- grub-0.97.orig/libvolume_id/reiserfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/reiserfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,113 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Copyright (C) 2005 Tobias Klauser <tklauser@access.unizh.ch> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct reiserfs_super_block { ++ uint32_t blocks_count; ++ uint32_t free_blocks; ++ uint32_t root_block; ++ uint32_t journal_block; ++ uint32_t journal_dev; ++ uint32_t orig_journal_size; ++ uint32_t dummy2[5]; ++ uint16_t blocksize; ++ uint16_t dummy3[3]; ++ uint8_t magic[12]; ++ uint32_t dummy4[5]; ++ uint8_t uuid[16]; ++ uint8_t label[16]; ++} PACKED; ++ ++struct reiser4_super_block { ++ uint8_t magic[16]; ++ uint16_t dummy[2]; ++ uint8_t uuid[16]; ++ uint8_t label[16]; ++ uint64_t dummy2; ++} PACKED; ++ ++#define REISERFS1_SUPERBLOCK_OFFSET 0x2000 ++#define REISERFS_SUPERBLOCK_OFFSET 0x10000 ++ ++int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct reiserfs_super_block *rs; ++ struct reiser4_super_block *rs4; ++ uint8_t *buf; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ buf = volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ rs = (struct reiserfs_super_block *) buf; ++ if (memcmp((char *)rs->magic, "ReIsErFs", 8) == 0) { ++ strcpy(id->type_version, "3.5"); ++ id->type = "reiserfs"; ++ goto found; ++ } ++ if (memcmp((char *)rs->magic, "ReIsEr2Fs", 9) == 0) { ++ strcpy(id->type_version, "3.6"); ++ id->type = "reiserfs"; ++ goto found_label; ++ } ++ if (memcmp((char *)rs->magic, "ReIsEr3Fs", 9) == 0) { ++ strcpy(id->type_version, "JR"); ++ id->type = "reiserfs"; ++ goto found_label; ++ } ++ ++ rs4 = (struct reiser4_super_block *) buf; ++ if (memcmp((char *)rs4->magic, "ReIsEr4", 7) == 0) { ++ strcpy(id->type_version, "4"); ++ volume_id_set_label_raw(id, rs4->label, 16); ++ volume_id_set_label_string(id, rs4->label, 16); ++ volume_id_set_uuid(id, rs4->uuid, 0, UUID_DCE); ++ id->type = "reiser4"; ++ goto found; ++ } ++ ++ buf = volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ rs = (struct reiserfs_super_block *) buf; ++ if (memcmp((char *)rs->magic, "ReIsErFs", 8) == 0) { ++ strcpy(id->type_version, "3.5"); ++ id->type = "reiserfs"; ++ goto found; ++ } ++ ++ return -1; ++ ++found_label: ++ volume_id_set_label_raw(id, rs->label, 16); ++ volume_id_set_label_string(id, rs->label, 16); ++ volume_id_set_uuid(id, rs->uuid, 0, UUID_DCE); ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ ++ return 0; ++} + +=== added file 'libvolume_id/romfs.c' +--- grub-0.97.orig/libvolume_id/romfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/romfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,55 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct romfs_super { ++ uint8_t magic[8]; ++ uint32_t size; ++ uint32_t checksum; ++ uint8_t name[0]; ++} PACKED; ++ ++int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct romfs_super *rfs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ rfs = (struct romfs_super *) volume_id_get_buffer(id, off, 0x200); ++ if (rfs == NULL) ++ return -1; ++ ++ if (memcmp((char *)rfs->magic, "-rom1fs-", 4) == 0) { ++ size_t len = strlen((char *)rfs->name); ++ ++ if (len) { ++ volume_id_set_label_raw(id, rfs->name, len); ++ volume_id_set_label_string(id, rfs->name, len); ++ } ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "romfs"; ++ return 0; ++ } ++ ++ return -1; ++} + +=== added file 'libvolume_id/silicon_raid.c' +--- grub-0.97.orig/libvolume_id/silicon_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/silicon_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,71 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct silicon_meta { ++ uint8_t unknown0[0x2E]; ++ uint8_t ascii_version[0x36 - 0x2E]; ++ uint8_t diskname[0x56 - 0x36]; ++ uint8_t unknown1[0x60 - 0x56]; ++ uint32_t magic; ++ uint32_t unknown1a[0x6C - 0x64]; ++ uint32_t array_sectors_low; ++ uint32_t array_sectors_high; ++ uint8_t unknown2[0x78 - 0x74]; ++ uint32_t thisdisk_sectors; ++ uint8_t unknown3[0x100 - 0x7C]; ++ uint8_t unknown4[0x104 - 0x100]; ++ uint16_t product_id; ++ uint16_t vendor_id; ++ uint16_t minor_ver; ++ uint16_t major_ver; ++} PACKED; ++ ++#define SILICON_MAGIC 0x2F000000 ++ ++int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct silicon_meta *sil; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-1) * 0x200; ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ sil = (struct silicon_meta *) buf; ++ if (le32_to_cpu(sil->magic) != SILICON_MAGIC) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ sprintf(id->type_version, "%u.%u", le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); ++ id->type = "silicon_medley_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/squashfs.c' +--- grub-0.97.orig/libvolume_id/squashfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/squashfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,63 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define SQUASHFS_MAGIC 0x73717368 ++ ++struct squashfs_super { ++ uint32_t s_magic; ++ uint32_t inodes; ++ uint32_t bytes_used_2; ++ uint32_t uid_start_2; ++ uint32_t guid_start_2; ++ uint32_t inode_table_start_2; ++ uint32_t directory_table_start_2; ++ uint16_t s_major; ++ uint16_t s_minor; ++} PACKED; ++ ++int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct squashfs_super *sqs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ sqs = (struct squashfs_super *) volume_id_get_buffer(id, off, 0x200); ++ if (sqs == NULL) ++ return -1; ++ ++ if (sqs->s_magic == SQUASHFS_MAGIC) { ++ sprintf(id->type_version, "%u.%u", sqs->s_major, sqs->s_minor); ++ goto found; ++ } ++ if (sqs->s_magic == bswap_32(SQUASHFS_MAGIC)) { ++ sprintf(id->type_version, "%u.%u", bswap_16(sqs->s_major), bswap_16(sqs->s_minor)); ++ goto found; ++ } ++ ++ return -1; ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "squashfs"; ++ return 0; ++} + +=== added file 'libvolume_id/strfuncs.h' +--- grub-0.97.orig/libvolume_id/strfuncs.h 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/strfuncs.h 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,5 @@ ++ ++#include <stdlib.h> ++ ++size_t strnlen(const char *s, size_t limit); ++char *strchr (const char *s, int c); + +=== added file 'libvolume_id/sysv.c' +--- grub-0.97.orig/libvolume_id/sysv.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/sysv.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,128 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define SYSV_NICINOD 100 ++#define SYSV_NICFREE 50 ++ ++struct sysv_super ++{ ++ uint16_t s_isize; ++ uint16_t s_pad0; ++ uint32_t s_fsize; ++ uint16_t s_nfree; ++ uint16_t s_pad1; ++ uint32_t s_free[SYSV_NICFREE]; ++ uint16_t s_ninode; ++ uint16_t s_pad2; ++ uint16_t s_inode[SYSV_NICINOD]; ++ uint8_t s_flock; ++ uint8_t s_ilock; ++ uint8_t s_fmod; ++ uint8_t s_ronly; ++ uint32_t s_time; ++ uint16_t s_dinfo[4]; ++ uint32_t s_tfree; ++ uint16_t s_tinode; ++ uint16_t s_pad3; ++ uint8_t s_fname[6]; ++ uint8_t s_fpack[6]; ++ uint32_t s_fill[12]; ++ uint32_t s_state; ++ uint32_t s_magic; ++ uint32_t s_type; ++} PACKED; ++ ++#define XENIX_NICINOD 100 ++#define XENIX_NICFREE 100 ++ ++struct xenix_super { ++ uint16_t s_isize; ++ uint32_t s_fsize; ++ uint16_t s_nfree; ++ uint32_t s_free[XENIX_NICFREE]; ++ uint16_t s_ninode; ++ uint16_t s_inode[XENIX_NICINOD]; ++ uint8_t s_flock; ++ uint8_t s_ilock; ++ uint8_t s_fmod; ++ uint8_t s_ronly; ++ uint32_t s_time; ++ uint32_t s_tfree; ++ uint16_t s_tinode; ++ uint16_t s_dinfo[4]; ++ uint8_t s_fname[6]; ++ uint8_t s_fpack[6]; ++ uint8_t s_clean; ++ uint8_t s_fill[371]; ++ uint32_t s_magic; ++ uint32_t s_type; ++} PACKED; ++ ++#define SYSV_SUPERBLOCK_BLOCK 0x01 ++#define SYSV_MAGIC 0xfd187e20 ++#define XENIX_SUPERBLOCK_BLOCK 0x18 ++#define XENIX_MAGIC 0x2b5544 ++#define SYSV_MAX_BLOCKSIZE 0x800 ++ ++int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct sysv_super *vs; ++ struct xenix_super *xs; ++ unsigned int boff; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { ++ vs = (struct sysv_super *) ++ volume_id_get_buffer(id, off + (boff * SYSV_SUPERBLOCK_BLOCK), 0x200); ++ if (vs == NULL) ++ return -1; ++ ++ if (vs->s_magic == cpu_to_le32(SYSV_MAGIC) || vs->s_magic == cpu_to_be32(SYSV_MAGIC)) { ++ volume_id_set_label_raw(id, vs->s_fname, 6); ++ volume_id_set_label_string(id, vs->s_fname, 6); ++ id->type = "sysv"; ++ goto found; ++ } ++ } ++ ++ for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { ++ xs = (struct xenix_super *) ++ volume_id_get_buffer(id, off + (boff + XENIX_SUPERBLOCK_BLOCK), 0x200); ++ if (xs == NULL) ++ return -1; ++ ++ if (xs->s_magic == cpu_to_le32(XENIX_MAGIC) || xs->s_magic == cpu_to_be32(XENIX_MAGIC)) { ++ volume_id_set_label_raw(id, xs->s_fname, 6); ++ volume_id_set_label_string(id, xs->s_fname, 6); ++ id->type = "xenix"; ++ goto found; ++ } ++ } ++ ++ return -1; ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ return 0; ++} + +=== added file 'libvolume_id/udf.c' +--- grub-0.97.orig/libvolume_id/udf.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/udf.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,173 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct volume_descriptor { ++ struct descriptor_tag { ++ uint16_t id; ++ uint16_t version; ++ uint8_t checksum; ++ uint8_t reserved; ++ uint16_t serial; ++ uint16_t crc; ++ uint16_t crc_len; ++ uint32_t location; ++ } PACKED tag; ++ union { ++ struct anchor_descriptor { ++ uint32_t length; ++ uint32_t location; ++ } PACKED anchor; ++ struct primary_descriptor { ++ uint32_t seq_num; ++ uint32_t desc_num; ++ struct dstring { ++ uint8_t clen; ++ uint8_t c[31]; ++ } PACKED ident; ++ } PACKED primary; ++ } PACKED type; ++} PACKED; ++ ++struct volume_structure_descriptor { ++ uint8_t type; ++ uint8_t id[5]; ++ uint8_t version; ++} PACKED; ++ ++#define UDF_VSD_OFFSET 0x8000 ++ ++int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct volume_descriptor *vd; ++ struct volume_structure_descriptor *vsd; ++ unsigned int bs; ++ unsigned int b; ++ unsigned int type; ++ unsigned int count; ++ unsigned int loc; ++ unsigned int clen; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200); ++ if (vsd == NULL) ++ return -1; ++ ++ if (memcmp((char *)vsd->id, "NSR02", 5) == 0) ++ goto blocksize; ++ if (memcmp((char *)vsd->id, "NSR03", 5) == 0) ++ goto blocksize; ++ if (memcmp((char *)vsd->id, "BEA01", 5) == 0) ++ goto blocksize; ++ if (memcmp((char *)vsd->id, "BOOT2", 5) == 0) ++ goto blocksize; ++ if (memcmp((char *)vsd->id, "CD001", 5) == 0) ++ goto blocksize; ++ if (memcmp((char *)vsd->id, "CDW02", 5) == 0) ++ goto blocksize; ++ if (memcmp((char *)vsd->id, "TEA03", 5) == 0) ++ goto blocksize; ++ return -1; ++ ++blocksize: ++ /* search the next VSD to get the logical block size of the volume */ ++ for (bs = 0x800; bs < 0x8000; bs += 0x800) { ++ vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800); ++ if (vsd == NULL) ++ return -1; ++ dbg("test for blocksize: 0x%x", bs); ++ if (vsd->id[0] != '\0') ++ goto nsr; ++ } ++ return -1; ++ ++nsr: ++ /* search the list of VSDs for a NSR descriptor */ ++ for (b = 0; b < 64; b++) { ++ vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800); ++ if (vsd == NULL) ++ return -1; ++ ++ dbg("vsd: %c%c%c%c%c", ++ vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]); ++ ++ if (vsd->id[0] == '\0') ++ return -1; ++ if (memcmp((char *)vsd->id, "NSR02", 5) == 0) ++ goto anchor; ++ if (memcmp((char *)vsd->id, "NSR03", 5) == 0) ++ goto anchor; ++ } ++ return -1; ++ ++anchor: ++ /* read anchor volume descriptor */ ++ vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + (256 * bs), 0x200); ++ if (vd == NULL) ++ return -1; ++ ++ type = le16_to_cpu(vd->tag.id); ++ if (type != 2) /* TAG_ID_AVDP */ ++ goto found; ++ ++ /* get desriptor list address and block count */ ++ count = le32_to_cpu(vd->type.anchor.length) / bs; ++ loc = le32_to_cpu(vd->type.anchor.location); ++ dbg("0x%x descriptors starting at logical secor 0x%x", count, loc); ++ ++ /* pick the primary descriptor from the list */ ++ for (b = 0; b < count; b++) { ++ vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + ((loc + b) * bs), 0x200); ++ if (vd == NULL) ++ return -1; ++ ++ type = le16_to_cpu(vd->tag.id); ++ dbg("descriptor type %i", type); ++ ++ /* check validity */ ++ if (type == 0) ++ goto found; ++ if (le32_to_cpu(vd->tag.location) != loc + b) ++ goto found; ++ ++ if (type == 1) /* TAG_ID_PVD */ ++ goto pvd; ++ } ++ goto found; ++ ++pvd: ++ volume_id_set_label_raw(id, &(vd->type.primary.ident.clen), 32); ++ ++ clen = vd->type.primary.ident.clen; ++ dbg("label string charsize=%i bit", clen); ++ if (clen == 8) ++ volume_id_set_label_string(id, vd->type.primary.ident.c, 31); ++ else if (clen == 16) ++ volume_id_set_label_unicode16(id, vd->type.primary.ident.c, BE,31); ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "udf"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/ufs.c' +--- grub-0.97.orig/libvolume_id/ufs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/ufs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,217 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct ufs_super_block { ++ uint32_t fs_link; ++ uint32_t fs_rlink; ++ uint32_t fs_sblkno; ++ uint32_t fs_cblkno; ++ uint32_t fs_iblkno; ++ uint32_t fs_dblkno; ++ uint32_t fs_cgoffset; ++ uint32_t fs_cgmask; ++ uint32_t fs_time; ++ uint32_t fs_size; ++ uint32_t fs_dsize; ++ uint32_t fs_ncg; ++ uint32_t fs_bsize; ++ uint32_t fs_fsize; ++ uint32_t fs_frag; ++ uint32_t fs_minfree; ++ uint32_t fs_rotdelay; ++ uint32_t fs_rps; ++ uint32_t fs_bmask; ++ uint32_t fs_fmask; ++ uint32_t fs_bshift; ++ uint32_t fs_fshift; ++ uint32_t fs_maxcontig; ++ uint32_t fs_maxbpg; ++ uint32_t fs_fragshift; ++ uint32_t fs_fsbtodb; ++ uint32_t fs_sbsize; ++ uint32_t fs_csmask; ++ uint32_t fs_csshift; ++ uint32_t fs_nindir; ++ uint32_t fs_inopb; ++ uint32_t fs_nspf; ++ uint32_t fs_optim; ++ uint32_t fs_npsect_state; ++ uint32_t fs_interleave; ++ uint32_t fs_trackskew; ++ uint32_t fs_id[2]; ++ uint32_t fs_csaddr; ++ uint32_t fs_cssize; ++ uint32_t fs_cgsize; ++ uint32_t fs_ntrak; ++ uint32_t fs_nsect; ++ uint32_t fs_spc; ++ uint32_t fs_ncyl; ++ uint32_t fs_cpg; ++ uint32_t fs_ipg; ++ uint32_t fs_fpg; ++ struct ufs_csum { ++ uint32_t cs_ndir; ++ uint32_t cs_nbfree; ++ uint32_t cs_nifree; ++ uint32_t cs_nffree; ++ } PACKED fs_cstotal; ++ int8_t fs_fmod; ++ int8_t fs_clean; ++ int8_t fs_ronly; ++ int8_t fs_flags; ++ union { ++ struct { ++ int8_t fs_fsmnt[512]; ++ uint32_t fs_cgrotor; ++ uint32_t fs_csp[31]; ++ uint32_t fs_maxcluster; ++ uint32_t fs_cpc; ++ uint16_t fs_opostbl[16][8]; ++ } PACKED fs_u1; ++ struct { ++ int8_t fs_fsmnt[468]; ++ uint8_t fs_volname[32]; ++ uint64_t fs_swuid; ++ int32_t fs_pad; ++ uint32_t fs_cgrotor; ++ uint32_t fs_ocsp[28]; ++ uint32_t fs_contigdirs; ++ uint32_t fs_csp; ++ uint32_t fs_maxcluster; ++ uint32_t fs_active; ++ int32_t fs_old_cpc; ++ int32_t fs_maxbsize; ++ int64_t fs_sparecon64[17]; ++ int64_t fs_sblockloc; ++ struct ufs2_csum_total { ++ uint64_t cs_ndir; ++ uint64_t cs_nbfree; ++ uint64_t cs_nifree; ++ uint64_t cs_nffree; ++ uint64_t cs_numclusters; ++ uint64_t cs_spare[3]; ++ } PACKED fs_cstotal; ++ struct ufs_timeval { ++ int32_t tv_sec; ++ int32_t tv_usec; ++ } PACKED fs_time; ++ int64_t fs_size; ++ int64_t fs_dsize; ++ uint64_t fs_csaddr; ++ int64_t fs_pendingblocks; ++ int32_t fs_pendinginodes; ++ } PACKED fs_u2; ++ } fs_u11; ++ union { ++ struct { ++ int32_t fs_sparecon[53]; ++ int32_t fs_reclaim; ++ int32_t fs_sparecon2[1]; ++ int32_t fs_state; ++ uint32_t fs_qbmask[2]; ++ uint32_t fs_qfmask[2]; ++ } PACKED fs_sun; ++ struct { ++ int32_t fs_sparecon[53]; ++ int32_t fs_reclaim; ++ int32_t fs_sparecon2[1]; ++ uint32_t fs_npsect; ++ uint32_t fs_qbmask[2]; ++ uint32_t fs_qfmask[2]; ++ } PACKED fs_sunx86; ++ struct { ++ int32_t fs_sparecon[50]; ++ int32_t fs_contigsumsize; ++ int32_t fs_maxsymlinklen; ++ int32_t fs_inodefmt; ++ uint32_t fs_maxfilesize[2]; ++ uint32_t fs_qbmask[2]; ++ uint32_t fs_qfmask[2]; ++ int32_t fs_state; ++ } PACKED fs_44; ++ } fs_u2; ++ int32_t fs_postblformat; ++ int32_t fs_nrpos; ++ int32_t fs_postbloff; ++ int32_t fs_rotbloff; ++ uint32_t fs_magic; ++ uint8_t fs_space[1]; ++} PACKED; ++ ++#define UFS_MAGIC 0x00011954 ++#define UFS2_MAGIC 0x19540119 ++#define UFS_MAGIC_FEA 0x00195612 ++#define UFS_MAGIC_LFN 0x00095014 ++ ++int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ uint32_t magic; ++ int i; ++ struct ufs_super_block *ufs; ++ int offsets[] = {0, 8, 64, 256, -1}; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ for (i = 0; offsets[i] >= 0; i++) { ++ ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800); ++ if (ufs == NULL) ++ return -1; ++ ++ dbg("offset 0x%x", offsets[i] * 0x400); ++ magic = be32_to_cpu(ufs->fs_magic); ++ if ((magic == UFS_MAGIC) || ++ (magic == UFS2_MAGIC) || ++ (magic == UFS_MAGIC_FEA) || ++ (magic == UFS_MAGIC_LFN)) { ++ dbg("magic 0x%08x(be)", magic); ++ goto found; ++ } ++ magic = le32_to_cpu(ufs->fs_magic); ++ if ((magic == UFS_MAGIC) || ++ (magic == UFS2_MAGIC) || ++ (magic == UFS_MAGIC_FEA) || ++ (magic == UFS_MAGIC_LFN)) { ++ dbg("magic 0x%08x(le)", magic); ++ goto found; ++ } ++ } ++ return -1; ++ ++found: ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "ufs"; ++ switch (magic) { ++ case UFS_MAGIC: ++ strcpy(id->type_version, "1"); ++ break; ++ case UFS2_MAGIC: ++ strcpy(id->type_version, "2"); ++ volume_id_set_label_raw(id, ufs->fs_u11.fs_u2.fs_volname, 32); ++ volume_id_set_label_string(id, ufs->fs_u11.fs_u2.fs_volname, 32); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} + +=== added file 'libvolume_id/util.c' +--- grub-0.97.orig/libvolume_id/util.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/util.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,472 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include <stdlib.h> ++ ++#include "strfuncs.h" ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++static char hex[] = "0123456789abcdef"; ++ ++#define hexhi(val) hex[val >> 4] ++#define hexlo(val) hex[val & 0xf] ++ ++/* count of characters used to encode one unicode char */ ++static int utf8_encoded_expected_len(const char *str) ++{ ++ unsigned char c = (unsigned char)str[0]; ++ ++ if (c < 0x80) ++ return 1; ++ if ((c & 0xe0) == 0xc0) ++ return 2; ++ if ((c & 0xf0) == 0xe0) ++ return 3; ++ if ((c & 0xf8) == 0xf0) ++ return 4; ++ if ((c & 0xfc) == 0xf8) ++ return 5; ++ if ((c & 0xfe) == 0xfc) ++ return 6; ++ return 0; ++} ++ ++/* decode one unicode char */ ++static int utf8_encoded_to_unichar(const char *str) ++{ ++ int unichar; ++ int len; ++ int i; ++ ++ len = utf8_encoded_expected_len(str); ++ switch (len) { ++ case 1: ++ return (int)str[0]; ++ case 2: ++ unichar = str[0] & 0x1f; ++ break; ++ case 3: ++ unichar = (int)str[0] & 0x0f; ++ break; ++ case 4: ++ unichar = (int)str[0] & 0x07; ++ break; ++ case 5: ++ unichar = (int)str[0] & 0x03; ++ break; ++ case 6: ++ unichar = (int)str[0] & 0x01; ++ break; ++ default: ++ return -1; ++ } ++ ++ for (i = 1; i < len; i++) { ++ if (((int)str[i] & 0xc0) != 0x80) ++ return -1; ++ unichar <<= 6; ++ unichar |= (int)str[i] & 0x3f; ++ } ++ ++ return unichar; ++} ++ ++/* expected size used to encode one unicode char */ ++static int utf8_unichar_to_encoded_len(int unichar) ++{ ++ if (unichar < 0x80) ++ return 1; ++ if (unichar < 0x800) ++ return 2; ++ if (unichar < 0x10000) ++ return 3; ++ if (unichar < 0x200000) ++ return 4; ++ if (unichar < 0x4000000) ++ return 5; ++ return 6; ++} ++ ++/* check if unicode char has a valid numeric range */ ++static int utf8_unichar_valid_range(int unichar) ++{ ++ if (unichar > 0x10ffff) ++ return 0; ++ if ((unichar & 0xfffff800) == 0xd800) ++ return 0; ++ if ((unichar > 0xfdcf) && (unichar < 0xfdf0)) ++ return 0; ++ if ((unichar & 0xffff) == 0xffff) ++ return 0; ++ return 1; ++} ++ ++/* validate one encoded unicode char and return its length */ ++int volume_id_utf8_encoded_valid_unichar(const char *str) ++{ ++ int len; ++ int unichar; ++ int i; ++ ++ len = utf8_encoded_expected_len(str); ++ if (len == 0) ++ return -1; ++ ++ /* ascii is valid */ ++ if (len == 1) ++ return 1; ++ ++ /* check if expected encoded chars are available */ ++ for (i = 0; i < len; i++) ++ if ((str[i] & 0x80) != 0x80) ++ return -1; ++ ++ unichar = utf8_encoded_to_unichar(str); ++ ++ /* check if encoded length matches encoded value */ ++ if (utf8_unichar_to_encoded_len(unichar) != len) ++ return -1; ++ ++ /* check if value has valid range */ ++ if (!utf8_unichar_valid_range(unichar)) ++ return -1; ++ ++ return len; ++} ++ ++size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count) ++{ ++ size_t i, j; ++ uint16_t c; ++ ++ j = 0; ++ for (i = 0; i + 2 <= count; i += 2) { ++ if (endianess == LE) ++ c = (buf[i+1] << 8) | buf[i]; ++ else ++ c = (buf[i] << 8) | buf[i+1]; ++ if (c == 0) { ++ str[j] = '\0'; ++ break; ++ } else if (c < 0x80) { ++ if (j+1 >= len) ++ break; ++ str[j++] = (uint8_t) c; ++ } else if (c < 0x800) { ++ if (j+2 >= len) ++ break; ++ str[j++] = (uint8_t) (0xc0 | (c >> 6)); ++ str[j++] = (uint8_t) (0x80 | (c & 0x3f)); ++ } else { ++ if (j+3 >= len) ++ break; ++ str[j++] = (uint8_t) (0xe0 | (c >> 12)); ++ str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); ++ str[j++] = (uint8_t) (0x80 | (c & 0x3f)); ++ } ++ } ++ str[j] = '\0'; ++ return j; ++} ++ ++static char *usage_to_string(enum volume_id_usage usage_id) ++{ ++ switch (usage_id) { ++ case VOLUME_ID_FILESYSTEM: ++ return "filesystem"; ++ case VOLUME_ID_OTHER: ++ return "other"; ++ case VOLUME_ID_RAID: ++ return "raid"; ++ case VOLUME_ID_DISKLABEL: ++ return "disklabel"; ++ case VOLUME_ID_CRYPTO: ++ return "crypto"; ++ case VOLUME_ID_UNPROBED: ++ return "unprobed"; ++ case VOLUME_ID_UNUSED: ++ return "unused"; ++ } ++ return NULL; ++} ++ ++void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id) ++{ ++ id->usage_id = usage_id; ++ id->usage = usage_to_string(usage_id); ++} ++ ++void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count) ++{ ++ if (count > sizeof(id->label)) ++ count = sizeof(id->label); ++ ++ memcpy(id->label_raw, buf, count); ++ id->label_raw_len = count; ++} ++ ++void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count) ++{ ++ size_t i; ++ ++ if (count >= sizeof(id->label)) ++ count = sizeof(id->label)-1; ++ ++ memcpy(id->label, buf, count); ++ id->label[count] = '\0'; ++ ++ /* remove trailing whitespace */ ++ i = strnlen(id->label, count); ++ while (i--) { ++ if (!isspace(id->label[i])) ++ break; ++ } ++ id->label[i+1] = '\0'; ++} ++ ++void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count) ++{ ++ if (count >= sizeof(id->label)) ++ count = sizeof(id->label)-1; ++ ++ volume_id_set_unicode16((uint8_t *)id->label, sizeof(id->label), buf, endianess, count); ++} ++ ++void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format) ++{ ++ unsigned int i; ++ unsigned int count = 0; ++ char *uuid; ++ ++ if (len > sizeof(id->uuid_raw)) ++ len = sizeof(id->uuid_raw); ++ ++ switch(format) { ++ case UUID_STRING: ++ count = len; ++ break; ++ case UUID_HEX_STRING: ++ count = len; ++ break; ++ case UUID_DOS: ++ count = 4; ++ break; ++ case UUID_64BIT_LE: ++ case UUID_64BIT_BE: ++ count = 8; ++ break; ++ case UUID_DCE: ++ count = 16; ++ break; ++ case UUID_FOURINT: ++ count = 35; ++ break; ++ } ++ memcpy(id->uuid_raw, buf, count); ++ id->uuid_raw_len = count; ++ ++ /* if set, create string in the same format, the native platform uses */ ++ for (i = 0; i < count; i++) ++ if (buf[i] != 0) ++ goto set; ++ return; ++ ++set: ++ uuid = id->uuid; ++ switch(format) { ++ case UUID_DOS: ++ *uuid++ = hexhi(buf[3]); ++ *uuid++ = hexlo(buf[3]); ++ *uuid++ = hexhi(buf[2]); ++ *uuid++ = hexlo(buf[2]); ++ *uuid++ = '-'; ++ *uuid++ = hexhi(buf[1]); ++ *uuid++ = hexlo(buf[1]); ++ *uuid++ = hexhi(buf[0]); ++ *uuid++ = hexlo(buf[0]); ++ *uuid = '\0'; ++ break; ++ case UUID_64BIT_LE: ++ *uuid++ = hexhi(buf[7]); ++ *uuid++ = hexlo(buf[7]); ++ *uuid++ = hexhi(buf[6]); ++ *uuid++ = hexlo(buf[6]); ++ *uuid++ = hexhi(buf[5]); ++ *uuid++ = hexlo(buf[5]); ++ *uuid++ = hexhi(buf[4]); ++ *uuid++ = hexlo(buf[4]); ++ *uuid++ = hexhi(buf[3]); ++ *uuid++ = hexlo(buf[3]); ++ *uuid++ = hexhi(buf[2]); ++ *uuid++ = hexlo(buf[2]); ++ *uuid++ = hexhi(buf[1]); ++ *uuid++ = hexlo(buf[1]); ++ *uuid++ = hexhi(buf[0]); ++ *uuid++ = hexlo(buf[0]); ++ *uuid = '\0'; ++ break; ++ case UUID_64BIT_BE: ++ *uuid++ = hexhi(buf[0]); ++ *uuid++ = hexlo(buf[0]); ++ *uuid++ = hexhi(buf[1]); ++ *uuid++ = hexlo(buf[1]); ++ *uuid++ = hexhi(buf[2]); ++ *uuid++ = hexlo(buf[2]); ++ *uuid++ = hexhi(buf[3]); ++ *uuid++ = hexlo(buf[3]); ++ *uuid++ = hexhi(buf[4]); ++ *uuid++ = hexlo(buf[4]); ++ *uuid++ = hexhi(buf[5]); ++ *uuid++ = hexlo(buf[5]); ++ *uuid++ = hexhi(buf[6]); ++ *uuid++ = hexlo(buf[6]); ++ *uuid++ = hexhi(buf[7]); ++ *uuid++ = hexlo(buf[7]); ++ *uuid = '\0'; ++ break; ++ case UUID_DCE: ++ *uuid++ = hexhi(buf[0]); ++ *uuid++ = hexlo(buf[0]); ++ *uuid++ = hexhi(buf[1]); ++ *uuid++ = hexlo(buf[1]); ++ *uuid++ = hexhi(buf[2]); ++ *uuid++ = hexlo(buf[2]); ++ *uuid++ = hexhi(buf[3]); ++ *uuid++ = hexlo(buf[3]); ++ *uuid++ = '-'; ++ *uuid++ = hexhi(buf[4]); ++ *uuid++ = hexlo(buf[4]); ++ *uuid++ = hexhi(buf[5]); ++ *uuid++ = hexlo(buf[5]); ++ *uuid++ = '-'; ++ *uuid++ = hexhi(buf[6]); ++ *uuid++ = hexlo(buf[6]); ++ *uuid++ = hexhi(buf[7]); ++ *uuid++ = hexlo(buf[7]); ++ *uuid++ = '-'; ++ *uuid++ = hexhi(buf[8]); ++ *uuid++ = hexlo(buf[8]); ++ *uuid++ = hexhi(buf[9]); ++ *uuid++ = hexlo(buf[9]); ++ *uuid++ = '-'; ++ *uuid++ = hexhi(buf[10]); ++ *uuid++ = hexlo(buf[10]); ++ *uuid++ = hexhi(buf[11]); ++ *uuid++ = hexlo(buf[11]); ++ *uuid++ = hexhi(buf[12]); ++ *uuid++ = hexlo(buf[12]); ++ *uuid++ = hexhi(buf[13]); ++ *uuid++ = hexlo(buf[13]); ++ *uuid++ = hexhi(buf[14]); ++ *uuid++ = hexlo(buf[14]); ++ *uuid++ = hexhi(buf[15]); ++ *uuid++ = hexlo(buf[15]); ++ *uuid = '\0'; ++ break; ++ case UUID_HEX_STRING: ++ /* translate A..F to a..f */ ++ memcpy(id->uuid, buf, count); ++ for (i = 0; i < count; i++) ++ if (id->uuid[i] >= 'A' && id->uuid[i] <= 'F') ++ id->uuid[i] = (id->uuid[i] - 'A') + 'a'; ++ id->uuid[count] = '\0'; ++ break; ++ case UUID_STRING: ++ memcpy(id->uuid, buf, count); ++ id->uuid[count] = '\0'; ++ break; ++ case UUID_FOURINT: ++ *uuid++ = hexhi(buf[0]); ++ *uuid++ = hexlo(buf[0]); ++ *uuid++ = hexhi(buf[1]); ++ *uuid++ = hexlo(buf[1]); ++ *uuid++ = hexhi(buf[2]); ++ *uuid++ = hexlo(buf[2]); ++ *uuid++ = hexhi(buf[3]); ++ *uuid++ = hexlo(buf[3]); ++ *uuid++ = ':'; ++ *uuid++ = hexhi(buf[4]); ++ *uuid++ = hexlo(buf[4]); ++ *uuid++ = hexhi(buf[5]); ++ *uuid++ = hexlo(buf[5]); ++ *uuid++ = hexhi(buf[6]); ++ *uuid++ = hexlo(buf[6]); ++ *uuid++ = hexhi(buf[7]); ++ *uuid++ = hexlo(buf[7]); ++ *uuid++ = ':'; ++ *uuid++ = hexhi(buf[8]); ++ *uuid++ = hexlo(buf[8]); ++ *uuid++ = hexhi(buf[9]); ++ *uuid++ = hexlo(buf[9]); ++ *uuid++ = hexhi(buf[10]); ++ *uuid++ = hexlo(buf[10]); ++ *uuid++ = hexhi(buf[11]); ++ *uuid++ = hexlo(buf[11]); ++ *uuid++ = ':'; ++ *uuid++ = hexhi(buf[12]); ++ *uuid++ = hexlo(buf[12]); ++ *uuid++ = hexhi(buf[13]); ++ *uuid++ = hexlo(buf[13]); ++ *uuid++ = hexhi(buf[14]); ++ *uuid++ = hexlo(buf[14]); ++ *uuid++ = hexhi(buf[15]); ++ *uuid++ = hexlo(buf[15]); ++ *uuid = '\0'; ++ break; ++ default: ++ *uuid = '\0'; ++ break; ++ } ++} ++ ++uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) ++{ ++ info("get buffer off 0x%llx(%llu), len 0x%zx", (unsigned long long) off, (unsigned long long) off, len); ++ /* check if requested area fits in superblock buffer */ ++ if (off + len <= SB_BUFFER_SIZE) { ++ /* check if we need to read */ ++ if ((off + len) > id->sbbuf_len) { ++ if (devread (0, 0, off + len, (char*)id->sbbuf) == 0) ++ { ++ return NULL; ++ } ++ id->sbbuf_len = off + len; ++ } ++ return &(id->sbbuf[off]); ++ } else { ++ if (len > SEEK_BUFFER_SIZE) { ++ dbg("seek buffer too small %d", SEEK_BUFFER_SIZE); ++ return NULL; ++ } ++ ++ /* check if we need to read */ ++ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { ++ info("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); ++ if (devread(off >> 9, off & 0x1ff, len, (char*)id->seekbuf) == 0) ++ { ++ return NULL; ++ } ++ id->seekbuf_off = off; ++ id->seekbuf_len = len; ++ } ++ return &(id->seekbuf[off - id->seekbuf_off]); ++ } ++} + +=== added file 'libvolume_id/util.h' +--- grub-0.97.orig/libvolume_id/util.h 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/util.h 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,98 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005-2006 Kay Sievers <kay.sievers@vrfy.org> ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _VOLUME_ID_UTIL_ ++#define _VOLUME_ID_UTIL_ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include <endian.h> ++#include <byteswap.h> ++#include <syslog.h> ++ ++#define ALLOWED_CHARS "#+-.:=@_" ++ ++#ifndef PACKED ++#define PACKED __attribute__((packed)) ++#endif ++ ++#define err(format, arg...) volume_id_log_fn(LOG_ERR, __FILE__, __LINE__, format, ##arg) ++#ifdef INFO ++#define info(format, arg...) volume_id_log_fn(LOG_INFO, __FILE__, __LINE__, format, ##arg) ++#else ++#define info(format, arg...) do { } while (0) ++#endif ++ ++#ifdef DEBUG ++#define dbg(format, arg...) volume_id_log_fn(LOG_DEBUG, __FILE__, __LINE__, format, ##arg) ++#else ++#define dbg(format, arg...) do { } while (0) ++#endif ++ ++/* size of superblock buffer, reiserfs block is at 64k */ ++#define SB_BUFFER_SIZE 0x11000 ++/* size of seek buffer, FAT cluster is 32k max */ ++#define SEEK_BUFFER_SIZE 0x10000 ++ ++#ifdef __BYTE_ORDER ++#if (__BYTE_ORDER == __LITTLE_ENDIAN) ++#define le16_to_cpu(x) (x) ++#define le32_to_cpu(x) (x) ++#define le64_to_cpu(x) (x) ++#define be16_to_cpu(x) bswap_16(x) ++#define be32_to_cpu(x) bswap_32(x) ++#define cpu_to_le16(x) (x) ++#define cpu_to_le32(x) (x) ++#define cpu_to_be32(x) bswap_32(x) ++#elif (__BYTE_ORDER == __BIG_ENDIAN) ++#define le16_to_cpu(x) bswap_16(x) ++#define le32_to_cpu(x) bswap_32(x) ++#define le64_to_cpu(x) bswap_64(x) ++#define be16_to_cpu(x) (x) ++#define be32_to_cpu(x) (x) ++#define cpu_to_le16(x) bswap_16(x) ++#define cpu_to_le32(x) bswap_32(x) ++#define cpu_to_be32(x) (x) ++#endif ++#endif /* __BYTE_ORDER */ ++ ++enum uuid_format { ++ UUID_STRING, ++ UUID_HEX_STRING, ++ UUID_DCE, ++ UUID_DOS, ++ UUID_64BIT_LE, ++ UUID_64BIT_BE, ++ UUID_FOURINT, ++}; ++ ++enum endian { ++ LE = 0, ++ BE = 1 ++}; ++ ++extern int volume_id_utf8_encoded_valid_unichar(const char *str); ++extern size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count); ++extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id); ++extern void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count); ++extern void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count); ++extern void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count); ++extern void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format); ++extern uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len); ++extern void volume_id_free_buffer(struct volume_id *id); ++ ++#endif /* _VOLUME_ID_UTIL_ */ ++ + +=== added file 'libvolume_id/via_raid.c' +--- grub-0.97.orig/libvolume_id/via_raid.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/via_raid.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,88 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * Based on information taken from dmraid: ++ * Copyright (C) 2004-2006 Heinz Mauelshagen, Red Hat GmbH ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct via_meta { ++ uint16_t signature; ++ uint8_t version_number; ++ struct via_array { ++ uint16_t disk_bit_mask; ++ uint8_t disk_array_ex; ++ uint32_t capacity_low; ++ uint32_t capacity_high; ++ uint32_t serial_checksum; ++ } PACKED array; ++ uint32_t serial_checksum[8]; ++ uint8_t checksum; ++} PACKED; ++ ++#define VIA_SIGNATURE 0xAA55 ++ ++/* 8 bit checksum on first 50 bytes of metadata. */ ++static uint8_t meta_checksum(struct via_meta *via) ++{ ++ uint8_t i = 50, sum = 0; ++ ++ while (i--) ++ sum += ((uint8_t*) via)[i]; ++ ++ return sum == via->checksum; ++} ++ ++ ++int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ const uint8_t *buf; ++ uint64_t meta_off; ++ struct via_meta *via; ++ ++ dbg("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ if (size < 0x10000) ++ return -1; ++ ++ meta_off = ((size / 0x200)-1) * 0x200; ++ ++ buf = volume_id_get_buffer(id, off + meta_off, 0x200); ++ if (buf == NULL) ++ return -1; ++ ++ via = (struct via_meta *) buf; ++ if (le16_to_cpu(via->signature) != VIA_SIGNATURE) ++ return -1; ++ ++ if (via->version_number > 1) ++ return -1; ++ ++ if (!meta_checksum(via)) ++ return -1; ++ ++ volume_id_set_usage(id, VOLUME_ID_RAID); ++ sprintf(id->type_version, "%u", via->version_number); ++ id->type = "via_raid_member"; ++ ++ return 0; ++} + +=== added file 'libvolume_id/volume_id.c' +--- grub-0.97.orig/libvolume_id/volume_id.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/volume_id.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,222 @@ ++/* ++ * volume_id - reads volume label and uuid ++ * ++ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> ++ * Grub Port, Copyright (C) 2008 Canonical Ltd. ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include <fcntl.h> ++#include <sys/stat.h> ++ ++#include "volume_id.h" ++#include "util.h" ++#include "strfuncs.h" ++#include "shared.h" ++ ++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++ ++struct prober { ++ volume_id_probe_fn_t prober; ++ const char *name[4]; ++}; ++ ++#define NOT_SUPPORTED(x) ++#define SUPPORTED(x) x ++ ++static const struct prober prober_raid[] = { ++ { volume_id_probe_ddf_raid, { "ddf_raid", } }, ++ ++ /* { volume_id_probe_linux_raid, { "linux_raid", } }, */ ++ /* { volume_id_probe_intel_software_raid, { "isw_raid", } }, */ ++ /* { volume_id_probe_lsi_mega_raid, { "lsi_mega_raid", } }, */ ++ /* { volume_id_probe_via_raid, { "via_raid", } }, */ ++ /* { volume_id_probe_silicon_medley_raid, { "silicon_medley_raid", } }, */ ++ /* { volume_id_probe_nvidia_raid, { "nvidia_raid", } }, */ ++ /* { volume_id_probe_promise_fasttrack_raid, { "promise_fasttrack_raid", } }, */ ++ /* { volume_id_probe_highpoint_45x_raid, { "highpoint_raid", } }, */ ++ /* { volume_id_probe_adaptec_raid, { "adaptec_raid", } }, */ ++ /* { volume_id_probe_jmicron_raid, { "jmicron_raid", } }, */ ++ /* { volume_id_probe_lvm1, { "lvm1", } }, */ ++ /* { volume_id_probe_lvm2, { "lvm2", } }, */ ++ /* { volume_id_probe_highpoint_37x_raid, { "highpoint_raid", } }, */ ++}; ++ ++static const struct prober prober_filesystem[] = { ++ { volume_id_probe_vfat, { "vfat", } }, ++ { volume_id_probe_luks, { "luks", } }, ++ { volume_id_probe_xfs, { "xfs", } }, ++ { volume_id_probe_ext, { "ext2", "ext3", "jbd", } }, ++ { volume_id_probe_reiserfs, { "reiserfs", "reiser4", } }, ++ { volume_id_probe_jfs, { "jfs", } }, ++ { volume_id_probe_hfs_hfsplus, { "hfs", "hfsplus", } }, ++ { volume_id_probe_ntfs, { "ntfs", } }, ++ { volume_id_probe_ocfs1, { "ocfs1", } }, ++ { volume_id_probe_ocfs2, { "ocfs2", } }, ++ ++ /* { volume_id_probe_linux_swap, { "swap", } }, */ ++ /* { volume_id_probe_udf, { "udf", } }, */ ++ /* { volume_id_probe_iso9660, { "iso9660", } }, */ ++ /* { volume_id_probe_ufs, { "ufs", } }, */ ++ /* { volume_id_probe_cramfs, { "cramfs", } }, */ ++ /* { volume_id_probe_romfs, { "romfs", } }, */ ++ /* { volume_id_probe_hpfs, { "hpfs", } }, */ ++ /* { volume_id_probe_sysv, { "sysv", "xenix", } }, */ ++ /* { volume_id_probe_minix, { "minix", } }, */ ++ /* { volume_id_probe_vxfs, { "vxfs", } }, */ ++ /* { volume_id_probe_squashfs, { "squashfs", } }, */ ++ /* { volume_id_probe_netware, { "netware", } }, */ ++}; ++ ++/* the user can overwrite this log function */ ++static void default_log(int priority, const char *file, int line, const char *format, ...) ++{ ++ return; ++} ++ ++volume_id_log_fn_t volume_id_log_fn = default_log; ++ ++/** ++ * volume_id_get_type: ++ * @id: Probing context ++ * @type: Type string. Must not be freed by the caller. ++ * ++ * Get the type string after a successful probe. ++ * ++ * Returns: 1 if the value was set, 0 otherwise. ++ **/ ++int volume_id_get_type(struct volume_id *id, const char **type) ++{ ++ if (id == NULL) ++ return 0; ++ if (type == NULL) ++ return 0; ++ if (id->usage_id == VOLUME_ID_UNUSED) ++ return 0; ++ ++ *type = id->type; ++ return 1; ++} ++ ++ ++/** ++ * volume_id_get_uuid: ++ * @id: Probing context. ++ * @uuid: UUID string. Must not be freed by the caller. ++ * ++ * Get the raw UUID string after a successful probe. ++ * ++ * Returns: 1 if the value was set, 0 otherwise. ++ **/ ++int volume_id_get_uuid(struct volume_id *id, const char **uuid) ++{ ++ if (id == NULL) ++ return 0; ++ if (uuid == NULL) ++ return 0; ++ if (id->usage_id == VOLUME_ID_UNUSED) ++ return 0; ++ ++ *uuid = id->uuid; ++ return 1; ++} ++ ++/** ++ * volume_id_probe_raid: ++ * @id: Probing context. ++ * @off: Probing offset relative to the start of the device. ++ * @size: Total size of the device. ++ * ++ * Probe device for all known raid signatures. ++ * ++ * Returns: 0 on successful probe, otherwise negative value. ++ **/ ++int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ unsigned int i; ++ ++ if (id == NULL) ++ return -1; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ for (i = 0; i < ARRAY_SIZE(prober_raid); i++) ++ if (prober_raid[i].prober(id, off, size) == 0) ++ goto found; ++ return -1; ++ ++found: ++ return 0; ++} ++ ++/** ++ * volume_id_probe_filesystem: ++ * @id: Probing context. ++ * @off: Probing offset relative to the start of the device. ++ * @size: Total size of the device. ++ * ++ * Probe device for all known filesystem signatures. ++ * ++ * Returns: 0 on successful probe, otherwise negative value. ++ **/ ++int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ unsigned int i; ++ ++ if (id == NULL) ++ return -1; ++ ++ info("probing at offset 0x%llx, size 0x%llx", ++ (unsigned long long) off, (unsigned long long) size); ++ ++ for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) ++ if (prober_filesystem[i].prober(id, off, size) == 0) ++ goto found; ++ return -1; ++ ++found: ++ return 0; ++} ++ ++/** ++ * volume_id_probe_raid: ++ * @all_probers_fn: prober function to called for all known probing routines. ++ * @id: Context passed to prober function. ++ * @off: Offset value passed to prober function. ++ * @size: Size value passed to prober function. ++ * @data: Arbitrary data passed to the prober function. ++ * ++ * Run a custom function for all known probing routines. ++ **/ ++void volume_id_all_probers(all_probers_fn_t all_probers_fn, ++ struct volume_id *id, uint64_t off, uint64_t size, ++ void *data) ++{ ++ unsigned int i; ++ ++ if (all_probers_fn == NULL) ++ return; ++ ++ for (i = 0; i < ARRAY_SIZE(prober_raid); i++) { ++ if (all_probers_fn(prober_raid[i].prober, id, off, size, data) != 0) ++ goto out; ++ } ++ for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) { ++ if (all_probers_fn(prober_filesystem[i].prober, id, off, size, data) != 0) ++ goto out; ++ } ++out: ++ return; ++} + +=== added file 'libvolume_id/volume_id.h' +--- grub-0.97.orig/libvolume_id/volume_id.h 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/volume_id.h 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,137 @@ ++/* ++ * volume_id - reads volume label and uuid ++ * ++ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _LIBVOLUME_ID_H_ ++#define _LIBVOLUME_ID_H_ ++ ++#include <stdint.h> ++#include <stddef.h> ++ ++typedef void (*volume_id_log_fn_t)(int priority, const char *file, int line, const char *format, ...) ; ++ ++extern volume_id_log_fn_t volume_id_log_fn; ++ ++struct volume_id; ++typedef int (*volume_id_probe_fn_t)(struct volume_id *id, uint64_t off, uint64_t size); ++typedef int (*all_probers_fn_t)(volume_id_probe_fn_t probe_fn, ++ struct volume_id *id, uint64_t off, uint64_t size, ++ void *data); ++ ++extern struct volume_id *volume_id_open_fd(int fd); ++extern void volume_id_close(struct volume_id *id); ++extern int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); ++extern const volume_id_probe_fn_t *volume_id_get_prober_by_type(const char *type); ++extern void volume_id_all_probers(all_probers_fn_t all_probers_fn, ++ struct volume_id *id, uint64_t off, uint64_t size, ++ void *data); ++extern int volume_id_get_label(struct volume_id *id, const char **label); ++extern int volume_id_get_label_raw(struct volume_id *id, const uint8_t **label, size_t *len); ++extern int volume_id_get_uuid(struct volume_id *id, const char **uuid); ++extern int volume_id_get_uuid_raw(struct volume_id *id, const uint8_t **uuid, size_t *len); ++extern int volume_id_get_usage(struct volume_id *id, const char **usage); ++extern int volume_id_get_type(struct volume_id *id, const char **type); ++extern int volume_id_get_type_version(struct volume_id *id, const char **type_version); ++extern int volume_id_encode_string(const char *str, char *str_enc, size_t len); ++ ++/* ++ * Note: everything below will be made private or removed from ++ * a future version, and a new major release of libvolume_id ++ */ ++ ++extern struct volume_id *volume_id_open_node(const char *path); ++ ++#define VOLUME_ID_LABEL_SIZE 64 ++#define VOLUME_ID_UUID_SIZE 36 ++#define VOLUME_ID_FORMAT_SIZE 32 ++#define VOLUME_ID_PATH_MAX 256 ++#define VOLUME_ID_PARTITIONS_MAX 256 ++ ++enum volume_id_usage { ++ VOLUME_ID_UNUSED, ++ VOLUME_ID_UNPROBED, ++ VOLUME_ID_OTHER, ++ VOLUME_ID_FILESYSTEM, ++ VOLUME_ID_RAID, ++ VOLUME_ID_DISKLABEL, ++ VOLUME_ID_CRYPTO, ++}; ++ ++#include <util.h> ++ ++struct volume_id { ++ uint8_t label_raw[VOLUME_ID_LABEL_SIZE]; ++ size_t label_raw_len; ++ char label[VOLUME_ID_LABEL_SIZE+1]; ++ uint8_t uuid_raw[VOLUME_ID_UUID_SIZE]; ++ size_t uuid_raw_len; ++ char uuid[VOLUME_ID_UUID_SIZE+1]; ++ enum volume_id_usage usage_id; ++ char *usage; ++ char *type; ++ char type_version[VOLUME_ID_FORMAT_SIZE]; ++ ++ int fd; ++ uint8_t sbbuf[SB_BUFFER_SIZE]; ++ size_t sbbuf_len; ++ uint8_t seekbuf[SEEK_BUFFER_SIZE]; ++ uint64_t seekbuf_off; ++ size_t seekbuf_len; ++ int fd_close:1; ++}; ++ ++/* filesystems */ ++extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size); ++ ++/* special formats */ ++extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size); ++ ++/* raid */ ++extern int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size); ++ ++/* bios raid */ ++extern int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size); ++extern int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size); ++ ++#endif + +=== added file 'libvolume_id/vxfs.c' +--- grub-0.97.orig/libvolume_id/vxfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/vxfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,49 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++#define VXFS_SUPER_MAGIC 0xa501FCF5 ++ ++struct vxfs_super { ++ uint32_t vs_magic; ++ int32_t vs_version; ++} PACKED; ++ ++int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct vxfs_super *vxs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ vxs = (struct vxfs_super *) volume_id_get_buffer(id, off + 0x200, 0x200); ++ if (vxs == NULL) ++ return -1; ++ ++ if (vxs->vs_magic == cpu_to_le32(VXFS_SUPER_MAGIC)) { ++ sprintf(id->type_version, "%u", (unsigned int) vxs->vs_version); ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "vxfs"; ++ return 0; ++ } ++ ++ return -1; ++} + +=== added file 'libvolume_id/xfs.c' +--- grub-0.97.orig/libvolume_id/xfs.c 1970-01-01 00:00:00 +0000 ++++ grub-0.97/libvolume_id/xfs.c 2008-07-15 12:31:43 +0000 +@@ -0,0 +1,59 @@ ++/* ++ * volume_id - reads filesystem label and uuid ++ * ++ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> ++ * ++ * 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 version 2 of the License. ++ */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "volume_id.h" ++#include "util.h" ++#include "shared.h" ++ ++struct xfs_super_block { ++ uint8_t magic[4]; ++ uint32_t blocksize; ++ uint64_t dblocks; ++ uint64_t rblocks; ++ uint32_t dummy1[2]; ++ uint8_t uuid[16]; ++ uint32_t dummy2[15]; ++ uint8_t fname[12]; ++ uint32_t dummy3[2]; ++ uint64_t icount; ++ uint64_t ifree; ++ uint64_t fdblocks; ++} PACKED; ++ ++int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size) ++{ ++ struct xfs_super_block *xs; ++ ++ info("probing at offset 0x%llx", (unsigned long long) off); ++ ++ xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200); ++ if (xs == NULL) ++ return -1; ++ ++ if (memcmp((char *)xs->magic, "XFSB", 4) != 0) ++ return -1; ++ ++ volume_id_set_label_raw(id, xs->fname, 12); ++ volume_id_set_label_string(id, xs->fname, 12); ++ volume_id_set_uuid(id, xs->uuid, 0, UUID_DCE); ++ ++ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); ++ id->type = "xfs"; ++ ++ return 0; ++} + +=== modified file 'stage2/Makefile.am' +--- grub-0.97.orig/stage2/Makefile.am 2005-02-02 20:40:05 +0000 ++++ grub-0.97/stage2/Makefile.am 2008-07-09 17:23:44 +0000 +@@ -13,6 +13,10 @@ + # For <stage1.h>. + INCLUDES = -I$(top_srcdir)/stage1 + ++if UUID_SUPPORT ++INCLUDES += -I$(top_srcdir)/libvolume_id ++endif ++ + # The library for /sbin/grub. + noinst_LIBRARIES = libgrub.a + libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \ +@@ -61,6 +65,12 @@ + PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 + START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 + ++if UUID_SUPPORT ++UUID_FLAGS = -DSUPPORT_UUID=1 ++else ++UUID_FLAGS = ++endif ++ + if NETBOOT_SUPPORT + NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1 + else +@@ -82,6 +92,8 @@ + STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ + $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) + ++STAGE2_COMPILE += $(UUID_FLAGS) ++ + STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 + STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 + +@@ -97,7 +109,12 @@ + + if NETBOOT_SUPPORT + pre_stage2_exec_LDADD = ../netboot/libdrivers.a +-endif ++else ++if UUID_SUPPORT ++pre_stage2_exec_LDADD = ../libvolume_id/libvolume_id.a ++endif ++endif ++ + + if DISKLESS_SUPPORT + BUILT_SOURCES = stage2_size.h diskless_size.h + +=== modified file 'stage2/builtins.c' +--- grub-0.97.orig/stage2/builtins.c 2008-01-28 18:15:31 +0000 ++++ grub-0.97/stage2/builtins.c 2008-07-09 17:23:44 +0000 +@@ -49,6 +49,10 @@ + # include <md5.h> + #endif + ++#ifdef SUPPORT_UUID ++#include <volume_id.h> ++#endif ++ + /* The type of kernel loaded. */ + kernel_t kernel_type; + /* The boot device. */ +@@ -4790,6 +4794,168 @@ + "Probe VBE information. If the mode number MODE is specified, show only" + " the information about only the mode." + }; ++ ++ ++ ++#ifdef SUPPORT_UUID ++ ++struct uuid_callback_data ++{ ++ int found; /* 1 if uuid matches */ ++ char *uuid; /* uuid to look for */ ++}; ++ ++static void uuid_info_print(struct volume_id *id, const char *uuid) ++{ ++ const char *type; ++ int i; ++ ++ volume_id_get_type(id, &type); ++ grub_printf("(hd%d", current_drive - 0x80); ++ if ((current_partition & 0xFF0000) != 0xFF0000) ++ { ++ grub_printf (",%d", (current_partition >> 16) & 0xFF); ++ } ++ if ((current_partition & 0x00FF00) != 0x00FF00) ++ { ++ grub_printf (",%c", 'a' + ((current_partition >> 8) & 0xFF)); ++ } ++ grub_printf(") %s",type); ++ for (i=0;i<6-strlen(type);i++) ++ { ++ grub_putchar(' '); ++ } ++ grub_printf(" %s\n",uuid); ++} ++ ++static int uuid_all_probers(volume_id_probe_fn_t probe_fn, ++ struct volume_id *id, ++ uint64_t off, ++ uint64_t size, ++ void *data) ++{ ++ struct uuid_callback_data *uc_data = (struct uuid_callback_data*)data; ++ ++ if (probe_fn(id, off, size) == 0) ++ { ++ const char *volume_uuid; ++ if (volume_id_get_uuid(id, &volume_uuid)) ++ { ++ if (!*(uc_data->uuid)) ++ { ++ uuid_info_print(id, volume_uuid); ++ } ++ else ++ { ++ if (strcmp(volume_uuid, uc_data->uuid) == 0) ++ { ++ grub_printf("Boot from "); ++ uuid_info_print(id, volume_uuid); ++ uc_data->found = 1; ++ return 1; ++ } ++ } ++ } ++ } ++ return 0; ++} ++ ++/* uuid find */ ++/* Search for the uuid arg in all of partitions. */ ++static int ++uuid_func(char *arg, int flag) ++{ ++ unsigned long drive; ++ unsigned long tmp_drive = saved_drive; ++ unsigned long tmp_partition = saved_partition; ++ struct uuid_callback_data uc_data; ++ ++ uc_data.uuid = arg; ++ uc_data.found = 0; ++ ++ /* Just hard disks and USB drives supported by BIOS */ ++ for (drive = 0x80; drive < 0x88; drive++) ++ { ++ unsigned long part = 0xFFFFFF; ++ unsigned long start, len, offset, ext_offset, gpt_offset; ++ int type, entry, gpt_count, gpt_size; ++ char *buf = (char *) RAW_ADDR(0x100000); ++ struct volume_id *vol_id = (struct volume_id *) RAW_ADDR (0x100000 + SECTOR_SIZE); ++ ++ current_drive = drive; ++ while (next_partition (drive, 0xFFFFFF, &part, &type, ++ &start, &len, &offset, &entry, ++ &ext_offset, &gpt_offset, ++ &gpt_count, &gpt_size, buf)) ++ { ++ if (type != PC_SLICE_TYPE_NONE ++ && ! IS_PC_SLICE_TYPE_BSD (type) ++ && ! IS_PC_SLICE_TYPE_EXTENDED (type)) ++ { ++ current_partition = part; ++ errnum = ERR_NONE; ++ /* Attempt to open device, conventional way */ ++ if (! open_device ()) ++ { ++ errnum = ERR_NONE; ++ /* Failed, like NTFS or FAT filesystems, so try the rootnoverify way */ ++ if (open_partition ()) ++ { ++ set_bootdev (0); ++ if (errnum) ++ { ++ /* Give up */ ++ errnum = ERR_NONE; ++ continue; ++ } ++ } ++ } ++ ++ /* And probe for uuid across all fs types */ ++ saved_drive = current_drive; ++ saved_partition = current_partition; ++ ++ grub_memset(vol_id, 0, sizeof(struct volume_id) ); ++ volume_id_all_probers(uuid_all_probers, vol_id, 0, len, (void*)&uc_data); ++ if (uc_data.found) ++ { ++ /* Success! */ ++ errnum = ERR_NONE; ++ return 0; ++ } ++ } ++ /* We want to ignore any error here. */ ++ errnum = ERR_NONE; ++ } ++ ++ /* next_partition always sets ERRNUM in the last call, so clear it. */ ++ errnum = ERR_NONE; ++ } ++ ++ saved_drive = tmp_drive; ++ saved_partition = tmp_partition; ++ current_drive = GRUB_INVALID_DRIVE; ++ current_partition = 0xFFFFFF; ++ errnum = ERR_FILE_NOT_FOUND; ++ ++ if (!*arg) ++ { ++ errnum = ERR_NONE; ++ return 0; ++ } ++ return 1; ++} ++ ++static struct builtin builtin_uuid = ++{ ++ "uuid", ++ uuid_func, ++ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, ++ "uuid UUID", ++ "Set the current \"root device\" to the device with the uuid UUID," ++ " then attempt to mount it" ++}; ++#endif + + + /* The table of builtin commands. Sorted in dictionary order. */ +@@ -4879,6 +5045,9 @@ + &builtin_title, + &builtin_unhide, + &builtin_uppermem, ++#ifdef SUPPORT_UUID ++ &builtin_uuid, ++#endif + &builtin_vbeprobe, + 0 + }; + diff --git a/sys-boot/grub/files/grub-0.97-uuid_doc.patch b/sys-boot/grub/files/grub-0.97-uuid_doc.patch new file mode 100644 index 0000000..06bfbde --- /dev/null +++ b/sys-boot/grub/files/grub-0.97-uuid_doc.patch @@ -0,0 +1,38 @@ +--- grub-0.97.orig/docs/grub.texi 2008-07-17 11:07:25.000000000 +0100 ++++ grub-0.97/docs/grub.texi 2008-07-17 10:57:41.000000000 +0100 +@@ -2707,6 +2707,7 @@ + * testload:: Load a file for testing a filesystem + * testvbe:: Test VESA BIOS EXTENSION + * uppermem:: Set the upper memory size ++* uuid:: Set GRUB's root device using UUID + * vbeprobe:: Probe VESA BIOS EXTENSION + @end menu + +@@ -3266,6 +3267,27 @@ + also be used for debugging purposes to lie to an OS. + @end deffn + ++@node uuid ++@subsection uuid ++ ++@deffn Command uuid [UUID] ++Set the current @dfn{root device} to the device with the universally ++unique identifier @var{UUID}, then attempt to mount it. This is ++equivalent to the @ref{root} command, but allows one to select a ++filesystem by UUID rather than by device. ++ ++The command recognises ext2, ext3, fat, hfs, jfs, ntfs, ocfs, reiserfs ++and xfs filesystems. ++ ++@strong{Note:} grub detects and recognises fat UUIDs in lower case ++whereas examining /dev/disk/by-uuid on Linux will report fat UUIDs ++in upper case. ++ ++By not specifying @var{UUID}, the command will scan partitions on ++attached devices and will display the device, partition type and ++UUID for each recognised filesystem. ++@end deffn ++ + + @node vbeprobe + @subsection vbeprobe diff --git a/sys-boot/grub/files/grub-1.96-genkernel.patch b/sys-boot/grub/files/grub-1.96-genkernel.patch new file mode 100644 index 0000000..e06f383 --- /dev/null +++ b/sys-boot/grub/files/grub-1.96-genkernel.patch @@ -0,0 +1,19 @@ +--- util/grub.d/10_linux.in ++++ util/grub.d/10_linux.in +@@ -61,7 +61,7 @@ + EOF + } + +-list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do ++list=`for i in /boot/kernel-* /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` + +@@ -78,6 +78,7 @@ + initrd= + for i in "initrd.img-${version}" "initrd-${version}.img" \ + "initrd-${version}" "initrd.img-${alt_version}" \ ++ "initramfs-genkernel-${version}" "initramfs-genkernel-${alt_version}" \ + "initrd-${alt_version}.img" "initrd-${alt_version}"; do + if test -e "${dirname}/${i}" ; then + initrd="$i" diff --git a/sys-boot/grub/files/grub-1.97-genkernel.patch b/sys-boot/grub/files/grub-1.97-genkernel.patch new file mode 100644 index 0000000..ae64ae4 --- /dev/null +++ b/sys-boot/grub/files/grub-1.97-genkernel.patch @@ -0,0 +1,28 @@ +--- grub-1.97.2.orig/util/grub.d/10_linux.in ++++ grub-1.97.2/util/grub.d/10_linux.in +@@ -49,7 +49,7 @@ menuentry "$1" { + EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF +- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro $2 ++ linux ${rel_dirname}/${basename} ro $2 + EOF + if test -n "${initrd}" ; then + cat << EOF +@@ -61,7 +61,7 @@ EOF + EOF + } + +-list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do ++list=`for i in /boot/kernel-* /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` + +@@ -78,6 +78,7 @@ while [ "x$list" != "x" ] ; do + initrd= + for i in "initrd.img-${version}" "initrd-${version}.img" \ + "initrd-${version}" "initrd.img-${alt_version}" \ ++ "initramfs-genkernel-${version}" "initramfs-genkernel-${alt_version}" \ + "initrd-${alt_version}.img" "initrd-${alt_version}"; do + if test -e "${dirname}/${i}" ; then + initrd="$i" diff --git a/sys-boot/grub/files/grub-1.97-hostdisk.patch b/sys-boot/grub/files/grub-1.97-hostdisk.patch new file mode 100644 index 0000000..6eb7fe4 --- /dev/null +++ b/sys-boot/grub/files/grub-1.97-hostdisk.patch @@ -0,0 +1,60 @@ +--- util/hostdisk.c 2010-01-25 17:04:22 +0000 ++++ util/hostdisk.c 2010-01-31 11:52:27 +0000 +@@ -336,7 +336,8 @@ + char dev[PATH_MAX]; + + strcpy (dev, map[disk->id].device); +- if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0) ++ if (disk->partition && sector >= disk->partition->start ++ && strncmp (map[disk->id].device, "/dev/", 5) == 0) + is_partition = linux_find_partition (dev, disk->partition->start); + + /* Open the partition. */ +@@ -490,6 +491,23 @@ + { + int fd; + ++ /* Split pre-partition and partition reads. */ ++ if (disk->partition && sector < disk->partition->start ++ && sector + size > disk->partition->start) ++ { ++ grub_err_t err; ++ err = grub_util_biosdisk_read (disk, sector, ++ disk->partition->start - sector, ++ buf); ++ if (err) ++ return err; ++ ++ return grub_util_biosdisk_read (disk, disk->partition->start, ++ size - (disk->partition->start - sector), ++ buf + ((disk->partition->start - sector) ++ << GRUB_DISK_SECTOR_BITS)); ++ } ++ + fd = open_device (disk, sector, O_RDONLY); + if (fd < 0) + return grub_errno; +@@ -527,6 +545,23 @@ + { + int fd; + ++ /* Split pre-partition and partition writes. */ ++ if (disk->partition && sector < disk->partition->start ++ && sector + size > disk->partition->start) ++ { ++ grub_err_t err; ++ err = grub_util_biosdisk_write (disk, sector, ++ disk->partition->start - sector, ++ buf); ++ if (err) ++ return err; ++ ++ return grub_util_biosdisk_write (disk, disk->partition->start, ++ size - (disk->partition->start - sector), ++ buf + ((disk->partition->start - sector) ++ << GRUB_DISK_SECTOR_BITS)); ++ } ++ + fd = open_device (disk, sector, O_WRONLY); + if (fd < 0) + return grub_errno; diff --git a/sys-boot/grub/files/grub-1.97-vga-deprecated.patch b/sys-boot/grub/files/grub-1.97-vga-deprecated.patch new file mode 100644 index 0000000..16b2ef7 --- /dev/null +++ b/sys-boot/grub/files/grub-1.97-vga-deprecated.patch @@ -0,0 +1,12 @@ +--- grub-1.97.2.orig/util/grub.d/00_header.in ++++ grub-1.97.2/util/grub.d/00_header.in +@@ -76,6 +76,9 @@ case x${GRUB_TERMINAL_OUTPUT} in + cat << EOF + if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then + set gfxmode=${GRUB_GFXMODE} ++ # vga= is deprecated, grub2 handles this just fine ++ # making grub2 res == linux fb res ++ set gfxpayload=keep + insmod gfxterm + insmod ${GRUB_VIDEO_BACKEND} + if terminal_output gfxterm ; then true ; else diff --git a/sys-boot/grub/files/grub-1.97-wallpaper-settings-support.patch b/sys-boot/grub/files/grub-1.97-wallpaper-settings-support.patch new file mode 100644 index 0000000..3bf4ffa --- /dev/null +++ b/sys-boot/grub/files/grub-1.97-wallpaper-settings-support.patch @@ -0,0 +1,15 @@ +diff -Nurp grub-1.97.2.orig/util/grub-mkconfig.in grub-1.97.2/util/grub-mkconfig.in +--- grub-1.97.2.orig/util/grub-mkconfig.in 2010-01-24 19:13:30.000000000 +0100 ++++ grub-1.97.2/util/grub-mkconfig.in 2010-02-17 21:01:08.762963506 +0100 +@@ -224,7 +224,10 @@ export GRUB_DEFAULT \ + GRUB_DISABLE_LINUX_UUID \ + GRUB_DISABLE_LINUX_RECOVERY \ + GRUB_GFXMODE \ +- GRUB_DISABLE_OS_PROBER ++ GRUB_DISABLE_OS_PROBER \ ++ GRUB_WALLPAPER \ ++ GRUB_COLOR_NORMAL \ ++ GRUB_COLOR_HIGHLIGHT + + if test "x${grub_cfg}" != "x"; then + rm -f ${grub_cfg}.new diff --git a/sys-boot/grub/files/grub-1.98-add-legacy-rootfs-detection.patch b/sys-boot/grub/files/grub-1.98-add-legacy-rootfs-detection.patch new file mode 100644 index 0000000..1fadd46 --- /dev/null +++ b/sys-boot/grub/files/grub-1.98-add-legacy-rootfs-detection.patch @@ -0,0 +1,83 @@ +diff -ur grub2-orig/util/grub-mkconfig.in grub2-new/util/grub-mkconfig.in +--- grub2-orig/util/grub-mkconfig.in 2010-01-28 15:01:46.746567396 +0100 ++++ grub2-new/util/grub-mkconfig.in 2010-01-28 15:38:48.560587115 +0100 +@@ -119,8 +119,8 @@ + fi + + # Device containing our userland. Typically used for root= parameter. +-GRUB_DEVICE="`${grub_probe} --target=device /`" +-GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true ++GRUB_DEVICE="`${grub_probe} --target=device /`" || GRUB_DEVICE="`legacy_find_root_device`" ++GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || GRUB_DEVICE_UUID="`legacy_convert_to_uuid ${GRUB_DEVICE}`" + + # Device containing our /boot partition. Usually the same as GRUB_DEVICE. + GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" +diff -ur grub2-orig/util/grub-mkconfig_lib.in grub2-new/util/grub-mkconfig_lib.in +--- grub2-orig/util/grub-mkconfig_lib.in 2010-01-28 15:01:46.740383831 +0100 ++++ grub2-new/util/grub-mkconfig_lib.in 2010-01-28 15:38:10.474013430 +0100 +@@ -188,3 +188,65 @@ + done + echo "$a" + } ++ ++legacy_find_root_device () ++{ ++ mount_point=$1 ++ ++ # Autodetect current root device ++ device= ++ if [ -f /etc/fstab ] ; then ++ device="`awk '$1!~/^#/{ ++ if ($2 ~ "^/+$") { $2 = "/"; } else { sub("/*$", "", $2); } ++ if ($2 == "'"$mount_point"'"){ ++ print $1; ++ } ++ }' /etc/fstab | tail -n 1`" ++ fi ++ ++ if [ -n "$device" ] ; then ++ case "$device" in ++ LABEL=* | UUID=*) ++ device="`findfs $device`" ++ device="`readlink -f "$device"`" ++ ;; ++ *) ++ device=`readlink -f "$device"` ++ ;; ++ esac ++ fi ++ ++ echo $device ++} ++ ++legacy_convert_to_uuid() ++{ ++ echo "Cannot determine uuid of root device. Trying legacy probe method" >&2 ++ local dev; dev="$1" ++ ++ convert=false ++ case "$dev" in ++ /dev/disk/*) ++ ;; ++ /dev/mapper/*) ++ ;; ++ /dev/evms/[hs]d[a-z][0-9]*) ++ convert=: ++ ;; ++ /dev/evms/*) ++ ;; ++ /dev/md[0-9]*) ++ ;; ++ /dev/*) ++ convert=: ++ ;; ++ esac ++ if $convert; then ++ if [ -b "$dev" ]; then ++ uuid="`blkid -o value -s UUID "$dev" || true`" ++ fi ++ fi ++ ++ echo "$uuid" ++} ++ diff --git a/sys-boot/grub/files/grub-1.98-follow-dev-mapper-symlinks.patch b/sys-boot/grub/files/grub-1.98-follow-dev-mapper-symlinks.patch new file mode 100644 index 0000000..aead475 --- /dev/null +++ b/sys-boot/grub/files/grub-1.98-follow-dev-mapper-symlinks.patch @@ -0,0 +1,25 @@ +--- a/util/getroot.c 2010-03-06 20:51:37.000000000 +0000 ++++ b/util/getroot.c 2010-05-28 19:21:57.592307313 +0100 +@@ -222,9 +222,20 @@ find_root_device (const char *dir, dev_t + /* Ignore any error. */ + continue; + +- if (S_ISLNK (st.st_mode)) +- /* Don't follow symbolic links. */ ++ if (S_ISLNK (st.st_mode)) { ++#ifdef __linux__ ++ if (strcmp (dir, "mapper") == 0) { ++ /* Follow symbolic links under /dev/mapper/; the canonical name ++ may be something like /dev/dm-0, but the names under ++ /dev/mapper/ are more human-readable and so we prefer them if ++ we can get them. */ ++ if (stat (ent->d_name, &st) < 0) ++ continue; ++ } else ++#endif /* __linux__ */ ++ /* Don't follow other symbolic links. */ + continue; ++ } + + if (S_ISDIR (st.st_mode)) + { diff --git a/sys-boot/grub/files/grub-1.98-genkernel-initramfs-single.patch b/sys-boot/grub/files/grub-1.98-genkernel-initramfs-single.patch new file mode 100644 index 0000000..a79a3af --- /dev/null +++ b/sys-boot/grub/files/grub-1.98-genkernel-initramfs-single.patch @@ -0,0 +1,11 @@ +--- grub-1.98.orig/util/grub.d/10_linux.in ++++ grub-1.98/util/grub.d/10_linux.in +@@ -139,7 +139,7 @@ while [ "x$list" != "x" ] ; do + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" + if [ "x${GRUB_DISABLE_LINUX_RECOVERY}" != "xtrue" ]; then + linux_entry "${OS}" "${version}" true \ +- "single ${GRUB_CMDLINE_LINUX}" ++ "single init_opts=single ${GRUB_CMDLINE_LINUX}" + fi + + list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` diff --git a/sys-boot/grub/files/grub-1.98-genkernel.patch b/sys-boot/grub/files/grub-1.98-genkernel.patch new file mode 100644 index 0000000..8fbf39a --- /dev/null +++ b/sys-boot/grub/files/grub-1.98-genkernel.patch @@ -0,0 +1,28 @@ +--- grub-1.98.orig/util/grub.d/10_linux.in 2010-03-06 21:51:37.000000000 +0100 ++++ grub-1.98/util/grub.d/10_linux.in 2010-04-12 11:25:51.982167950 +0200 +@@ -84,7 +84,7 @@ EOF + printf '%s\n' "${prepare_boot_cache}" + cat << EOF + echo $(printf "$(gettext "Loading Linux %s ...")" ${version}) +- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} ++ linux ${rel_dirname}/${basename} ro ${args} + EOF + if test -n "${initrd}" ; then + cat << EOF +@@ -97,7 +97,7 @@ EOF + EOF + } + +-list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do ++list=`for i in /boot/kernel-* /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` + prepare_boot_cache= +@@ -114,6 +114,7 @@ while [ "x$list" != "x" ] ; do + + initrd= + for i in "initrd.img-${version}" "initrd-${version}.img" \ ++ "initramfs-genkernel-${version}" "initramfs-genkernel-${alt_version}" \ + "initrd-${version}" "initrd.img-${alt_version}" \ + "initrd-${alt_version}.img" "initrd-${alt_version}"; do + if test -e "${dirname}/${i}" ; then diff --git a/sys-boot/grub/files/grub-1.98-wallpaper-settings-support.patch b/sys-boot/grub/files/grub-1.98-wallpaper-settings-support.patch new file mode 100644 index 0000000..f34f393 --- /dev/null +++ b/sys-boot/grub/files/grub-1.98-wallpaper-settings-support.patch @@ -0,0 +1,15 @@ +diff -Nurp grub-1.98.orig/util/grub-mkconfig.in grub-1.98/util/grub-mkconfig.in +--- grub-1.98.orig/util/grub-mkconfig.in 2010-03-06 21:51:37.000000000 +0100 ++++ grub-1.98/util/grub-mkconfig.in 2010-04-12 11:29:28.396075050 +0200 +@@ -224,7 +224,10 @@ export GRUB_DEFAULT \ + GRUB_GFXPAYLOAD_LINUX \ + GRUB_DISABLE_OS_PROBER \ + GRUB_INIT_TUNE \ +- GRUB_SAVEDEFAULT ++ GRUB_SAVEDEFAULT \ ++ GRUB_WALLPAPER \ ++ GRUB_COLOR_NORMAL \ ++ GRUB_COLOR_HIGHLIGHT + + if test "x${grub_cfg}" != "x"; then + rm -f ${grub_cfg}.new diff --git a/sys-boot/grub/files/grub-1.99-disable-floppies.patch b/sys-boot/grub/files/grub-1.99-disable-floppies.patch new file mode 100644 index 0000000..6bb2862 --- /dev/null +++ b/sys-boot/grub/files/grub-1.99-disable-floppies.patch @@ -0,0 +1,28 @@ + +Author: Robert Millan + +An ugly kludge. Should this be merged upstream? + +Index: b/grub-core/kern/emu/hostdisk.c +=================================================================== +--- a/grub-core/kern/emu/hostdisk.c ++++ b/grub-core/kern/emu/hostdisk.c +@@ -1077,6 +1077,18 @@ + continue; + } + ++ if (! strncmp (p, "/dev/fd", sizeof ("/dev/fd") - 1)) ++ { ++ char *q = p + sizeof ("/dev/fd") - 1; ++ if (*q >= '0' && *q <= '9') ++ { ++ free (map[drive].drive); ++ map[drive].drive = NULL; ++ grub_util_info ("`%s' looks like a floppy drive, skipping", p); ++ continue; ++ } ++ } ++ + #ifdef __linux__ + /* On Linux, the devfs uses symbolic links horribly, and that + confuses the interface very much, so use realpath to expand diff --git a/sys-boot/grub/files/grub-1.99-genkernel.patch b/sys-boot/grub/files/grub-1.99-genkernel.patch new file mode 100644 index 0000000..433e583 --- /dev/null +++ b/sys-boot/grub/files/grub-1.99-genkernel.patch @@ -0,0 +1,11 @@ +--- grub-1.99.orig/util/grub.d/10_linux.in ++++ grub-1.99/util/grub.d/10_linux.in +@@ -116,7 +116,7 @@ EOF + message="$(gettext_printf "Loading Linux %s ..." ${version})" + cat << EOF + echo '$message' +- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} ++ linux ${rel_dirname}/${basename} ro ${args} + EOF + if test -n "${initrd}" ; then + message="$(gettext_printf "Loading initial ramdisk ...")" diff --git a/sys-boot/grub/files/grub-1.99-vga-deprecated-not-yet.patch b/sys-boot/grub/files/grub-1.99-vga-deprecated-not-yet.patch new file mode 100644 index 0000000..d850c17 --- /dev/null +++ b/sys-boot/grub/files/grub-1.99-vga-deprecated-not-yet.patch @@ -0,0 +1,14 @@ +diff -Nurp grub-1.99.orig/grub-core/loader/i386/linux.c grub-1.99/grub-core/loader/i386/linux.c +--- grub-1.99.orig/grub-core/loader/i386/linux.c 2011-06-11 10:49:46.975998646 +0200 ++++ grub-1.99/grub-core/loader/i386/linux.c 2011-06-11 11:52:14.419996325 +0200 +@@ -821,10 +821,6 @@ grub_cmd_linux (grub_command_t cmd __att + if (! buf) + goto fail; + +- grub_printf ("%s is deprecated. " +- "Use set gfxpayload=%s before " +- "linux command instead.\n", +- argv[i], buf); + err = grub_env_set ("gfxpayload", buf); + grub_free (buf); + if (err) diff --git a/sys-boot/grub/files/grub-1.99-vga-deprecated.patch b/sys-boot/grub/files/grub-1.99-vga-deprecated.patch new file mode 100644 index 0000000..20ea6d8 --- /dev/null +++ b/sys-boot/grub/files/grub-1.99-vga-deprecated.patch @@ -0,0 +1,12 @@ +--- grub-1.99~rc1.orig/util/grub.d/00_header.in ++++ grub-1.99~rc1/util/grub.d/00_header.in +@@ -131,6 +131,9 @@ if [ "x$gfxterm" = x1 ]; then + if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT_PATH}"` ; then + set gfxmode=${GRUB_GFXMODE} + load_video ++ # vga= is deprecated, grub2 handles this just fine ++ # making grub2 res == linux fb res ++ set gfxpayload=keep + insmod gfxterm + fi + EOF diff --git a/sys-boot/grub/files/grub-1.99-wallpaper-settings-support.patch b/sys-boot/grub/files/grub-1.99-wallpaper-settings-support.patch new file mode 100644 index 0000000..6f3f374 --- /dev/null +++ b/sys-boot/grub/files/grub-1.99-wallpaper-settings-support.patch @@ -0,0 +1,15 @@ +diff -Nurp grub-1.99~rc1.orig/util/grub-mkconfig.in grub-1.99~rc1/util/grub-mkconfig.in +--- grub-1.99~rc1.orig/util/grub-mkconfig.in 2010-12-01 15:45:43.000000000 +0100 ++++ grub-1.99~rc1/util/grub-mkconfig.in 2011-06-08 14:37:02.209761705 +0200 +@@ -254,7 +254,10 @@ export GRUB_DEFAULT \ + GRUB_DISABLE_OS_PROBER \ + GRUB_INIT_TUNE \ + GRUB_SAVEDEFAULT \ +- GRUB_BADRAM ++ GRUB_BADRAM \ ++ GRUB_WALLPAPER \ ++ GRUB_COLOR_NORMAL \ ++ GRUB_COLOR_HIGHLIGHT + + if test "x${grub_cfg}" != "x"; then + rm -f ${grub_cfg}.new diff --git a/sys-boot/grub/files/grub-1.99-workaround-raid-bios-bug.patch b/sys-boot/grub/files/grub-1.99-workaround-raid-bios-bug.patch new file mode 100644 index 0000000..391c40a --- /dev/null +++ b/sys-boot/grub/files/grub-1.99-workaround-raid-bios-bug.patch @@ -0,0 +1,17 @@ +diff -Nurp grub-1.99.orig/grub-core/disk/raid.c grub-1.99/grub-core/disk/raid.c +--- grub-1.99.orig/grub-core/disk/raid.c 2011-04-18 23:16:16.000000000 +0200 ++++ grub-1.99/grub-core/disk/raid.c 2011-06-11 10:48:16.606998702 +0200 +@@ -562,13 +562,6 @@ insert_array (grub_disk_t disk, struct g + "superfluous RAID member (%d found)", + array->total_devs); + +- if (array->members[new_array->index].device != NULL) +- /* We found multiple devices with the same number. Again, +- this shouldn't happen. */ +- return grub_error (GRUB_ERR_BAD_DEVICE, +- "found two disks with the index %d for RAID %s", +- new_array->index, array->name); +- + if (new_array->disk_size < array->disk_size) + array->disk_size = new_array->disk_size; + break; diff --git a/sys-boot/grub/files/grub.conf.gentoo b/sys-boot/grub/files/grub.conf.gentoo new file mode 100644 index 0000000..0027099 --- /dev/null +++ b/sys-boot/grub/files/grub.conf.gentoo @@ -0,0 +1,16 @@ +# This is a sample grub.conf for use with Genkernel, per the Gentoo handbook +# http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&chap=10#doc_chap2 +# If you are not using Genkernel and you need help creating this file, you +# should consult the handbook. Alternatively, consult the grub.conf.sample that +# is included with the Grub documentation. + +default 0 +timeout 30 +#splashimage=(hd0,0)/boot/grub/splash.xpm.gz + +#title Gentoo Linux 2.6.24-r5 +#root (hd0,0) +#kernel /boot/kernel-genkernel-x86-2.6.24-gentoo-r5 root=/dev/ram0 real_root=/dev/sda3 +#initrd /boot/initramfs-genkernel-x86-2.6.24-gentoo-r5 + +# vim:ft=conf: diff --git a/sys-boot/grub/files/grub2-default b/sys-boot/grub/files/grub2-default new file mode 100644 index 0000000..7f16ccc --- /dev/null +++ b/sys-boot/grub/files/grub2-default @@ -0,0 +1,62 @@ +# /etc/default/grub +# If you change this file, run 'grub-mkconfig -o /boot/grub/grub.cfg' afterwards to update +# /boot/grub/grub.cfg. + +GRUB_DEFAULT=saved +GRUB_DISTRIBUTOR="Sabayon" +GRUB_HIDDEN_TIMEOUT=0 +GRUB_HIDDEN_TIMEOUT_QUIET=true +GRUB_TIMEOUT=5 + +# Add your extra parameters here below +# Dear user, put your boot flags here ;-) +GRUB_CMDLINE_LINUX_DEFAULT="" +# ATTENTION ATTENTION ATTENTION +# DO NOT EDIT THIS MANUALLY NOR SET IT TO EMPTY IF IT'S ALREADY FILLED WITH +# SOMETHING (DONE BY THE INSTALLER). REALLY, DON'T ! +GRUB_CMDLINE_LINUX="" +# ATTENTION ATTENTION ATTENTION + +# Uncomment to disable graphical terminal (grub-pc only) +# GRUB_TERMINAL=console + +# The resolution used on graphical terminal +# note that you can use only modes which your graphic card supports via VBE +# you can see them in real GRUB with the command `vbeinfo' +GRUB_GFXMODE=1024x768 + +# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux +#GRUB_DISABLE_LINUX_UUID=true + +# Uncomment to disable generation of recovery mode menu entrys +# GRUB_DISABLE_LINUX_RECOVERY="false" + +# Default wallpaper image path +GRUB_WALLPAPER="/boot/grub/default-splash.png" + +# Boot menu option normal color +GRUB_COLOR_NORMAL="white/black" + +# Boot menu option "highlight" color +GRUB_COLOR_HIGHLIGHT="magenta/black" + +if [ -f "/etc/default/sabayon-grub" ]; then + # this file is placed by the Sabayon Installer and contains + # custom GRUB_CMDLINE_LINUX parameters created at install + # time. + source /etc/default/sabayon-grub +fi + +# DO NOT REMOVE THIS IF YOUR GRUB_CMDLINE_LINUX IS EMPTY (BACKWARD COMPAT) +if [ -z "${GRUB_CMDLINE_LINUX}" ]; then + if [ ! -e "/proc/cmdline" ]; then + echo "ATTENTION ATTENTION ATTENTION" >&2 + echo "GRUB_CMDLINE_LINUX is not set inside /etc/default/grub" >&2 + echo " cannot generate a bootable configuration." >&2 + else + echo "ATTENTION ATTENTION ATTENTION" >&2 + echo "GRUB_CMDLINE_LINUX is not set inside /etc/default/grub" >&2 + echo " grub is going to use your /proc/cmdline content" >&2 + GRUB_CMDLINE_LINUX="`cat /proc/cmdline | sed -e 's#BOOT_IMAGE=.* ro ##g'`" + fi +fi diff --git a/sys-boot/grub/files/grub2-default-1.99 b/sys-boot/grub/files/grub2-default-1.99 new file mode 100644 index 0000000..9bc0775 --- /dev/null +++ b/sys-boot/grub/files/grub2-default-1.99 @@ -0,0 +1,63 @@ +# /etc/default/grub +# If you change this file, run 'grub-mkconfig -o /boot/grub/grub.cfg' afterwards to update +# /boot/grub/grub.cfg. + +GRUB_DEFAULT=saved +GRUB_DISTRIBUTOR="Sabayon" +GRUB_HIDDEN_TIMEOUT=0 +GRUB_HIDDEN_TIMEOUT_QUIET=true +GRUB_TIMEOUT=5 +GRUB_DISABLE_LINUX_UUID=true + +# Add your extra parameters here below +# Dear user, put your boot flags here ;-) +GRUB_CMDLINE_LINUX_DEFAULT="" +# ATTENTION ATTENTION ATTENTION +# DO NOT EDIT THIS MANUALLY NOR SET IT TO EMPTY IF IT'S ALREADY FILLED WITH +# SOMETHING (DONE BY THE INSTALLER). REALLY, DON'T ! +GRUB_CMDLINE_LINUX="" +# ATTENTION ATTENTION ATTENTION + +# Uncomment to disable graphical terminal (grub-pc only) +# GRUB_TERMINAL=console + +# The resolution used on graphical terminal +# note that you can use only modes which your graphic card supports via VBE +# you can see them in real GRUB with the command `vbeinfo' +GRUB_GFXMODE=1024x768 + +# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux +#GRUB_DISABLE_LINUX_UUID=true + +# Uncomment to disable generation of recovery mode menu entrys +# GRUB_DISABLE_LINUX_RECOVERY="false" + +# Default wallpaper image path +GRUB_WALLPAPER="/boot/grub/default-splash.png" + +# Boot menu option normal color +GRUB_COLOR_NORMAL="white/black" + +# Boot menu option "highlight" color +GRUB_COLOR_HIGHLIGHT="magenta/black" + +if [ -f "/etc/default/sabayon-grub" ]; then + # this file is placed by the Sabayon Installer and contains + # custom GRUB_CMDLINE_LINUX parameters created at install + # time. + source /etc/default/sabayon-grub +fi + +# DO NOT REMOVE THIS IF YOUR GRUB_CMDLINE_LINUX IS EMPTY (BACKWARD COMPAT) +if [ -z "${GRUB_CMDLINE_LINUX}" ]; then + if [ ! -e "/proc/cmdline" ]; then + echo "ATTENTION ATTENTION ATTENTION" >&2 + echo "GRUB_CMDLINE_LINUX is not set inside /etc/default/grub" >&2 + echo " cannot generate a bootable configuration." >&2 + else + echo "ATTENTION ATTENTION ATTENTION" >&2 + echo "GRUB_CMDLINE_LINUX is not set inside /etc/default/grub" >&2 + echo " grub is going to use your /proc/cmdline content" >&2 + GRUB_CMDLINE_LINUX="`cat /proc/cmdline | sed -e 's#BOOT_IMAGE=.* ro ##g'`" + fi +fi diff --git a/sys-boot/grub/files/splash.xpm.gz b/sys-boot/grub/files/splash.xpm.gz Binary files differnew file mode 100644 index 0000000..f6836bd --- /dev/null +++ b/sys-boot/grub/files/splash.xpm.gz diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/01_uuids_and_lvm_dont_play_along_nicely.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/01_uuids_and_lvm_dont_play_along_nicely.diff new file mode 100644 index 0000000..c997b84 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/01_uuids_and_lvm_dont_play_along_nicely.diff @@ -0,0 +1,14 @@ +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index c2da413..cbd9d6b 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -36,7 +36,8 @@ case ${GRUB_DEVICE} in + esac + + if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ +- || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then ++ || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ ++ || [ "`grub-probe -t abstraction --device ${GRUB_DEVICE} | sed -e 's,.*\(lvm\).*,\1,'`" = "lvm" ] ; then + LINUX_ROOT_DEVICE=${GRUB_DEVICE} + else + LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/902_boot_blocklist_hack.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/902_boot_blocklist_hack.diff new file mode 100644 index 0000000..63caf45 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/902_boot_blocklist_hack.diff @@ -0,0 +1,20 @@ +Index: util/i386/pc/grub-setup.c +=================================================================== +--- util/i386/pc/grub-setup.c (revision 1836) ++++ util/i386/pc/grub-setup.c (working copy) +@@ -383,6 +383,15 @@ + grub_disk_cache_invalidate_all (); + + file = grub_file_open (core_path_dev); ++ ++ if (grub_errno == GRUB_ERR_FILE_NOT_FOUND) ++ { ++ /* Clean the previous grub_errno */ ++ grub_errno = GRUB_ERR_NONE; ++ strcpy (core_path_dev, "/grub/core.img"); ++ file = grub_file_open (core_path_dev); ++ } ++ + if (file) + { + if (grub_file_size (file) != core_size) diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/904_disable_floppies.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/904_disable_floppies.diff new file mode 100644 index 0000000..66a41cd --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/904_disable_floppies.diff @@ -0,0 +1,28 @@ + +Author: Robert Millan + +An ugly kludge. Should this be merged upstream? + +Index: util/hostdisk.c +=================================================================== +--- util/hostdisk.c (revision 1832) ++++ util/hostdisk.c (working copy) +@@ -544,6 +544,18 @@ + continue; + } + ++ if (! strncmp (p, "/dev/fd", sizeof ("/dev/fd") - 1)) ++ { ++ char *q = p + sizeof ("/dev/fd") - 1; ++ if (*q >= '0' && *q <= '9') ++ { ++ free (map[drive].drive); ++ map[drive].drive = NULL; ++ grub_util_info ("`%s' looks like a floppy drive, skipping", p); ++ continue; ++ } ++ } ++ + #ifdef __linux__ + /* On Linux, the devfs uses symbolic links horribly, and that + confuses the interface very much, so use realpath to expand diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/956_loopback_root.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/956_loopback_root.diff new file mode 100644 index 0000000..ce54872 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/956_loopback_root.diff @@ -0,0 +1,139 @@ +Upstream: http://lists.gnu.org/archive/html/grub-devel/2009-09/msg00210.html +Description: If you set root after running loopback, any attempts to open + files on the loopback device resolve the loopback file name relative to the + *new* root, not the root at the time loopback was invoked, and so the above + recurses until it runs out of stack. This causes problems for Wubi. I think + it's fairly clear that only the root that was in place when you ran + loopback should be relevant to the loopback file name. + +diff -Nur -x '*.orig' -x '*~' grub2-1.97~beta2/disk/loopback.c grub2-1.97~beta2.new/disk/loopback.c +--- grub2-1.97~beta2/disk/loopback.c 2009-06-10 22:04:23.000000000 +0100 ++++ grub2-1.97~beta2.new/disk/loopback.c 2009-09-10 21:42:56.000000000 +0100 +@@ -28,6 +28,7 @@ + { + char *devname; + char *filename; ++ grub_file_t file; + int has_partitions; + struct grub_loopback *next; + }; +@@ -61,6 +62,7 @@ + /* Remove the device from the list. */ + *prev = dev->next; + ++ grub_file_close (dev->file); + grub_free (dev->devname); + grub_free (dev->filename); + grub_free (dev); +@@ -90,9 +92,6 @@ + if (! file) + return grub_errno; + +- /* Close the file, the only reason for opening it is validation. */ +- grub_file_close (file); +- + /* First try to replace the old device. */ + for (newdev = loopback_list; newdev; newdev = newdev->next) + if (grub_strcmp (newdev->devname, args[0]) == 0) +@@ -102,10 +101,12 @@ + { + char *newname = grub_strdup (args[1]); + if (! newname) +- return grub_errno; ++ goto fail; + + grub_free (newdev->filename); + newdev->filename = newname; ++ grub_file_close (newdev->file); ++ newdev->file = file; + + /* Set has_partitions when `--partitions' was used. */ + newdev->has_partitions = state[1].set; +@@ -116,13 +117,13 @@ + /* Unable to replace it, make a new entry. */ + newdev = grub_malloc (sizeof (struct grub_loopback)); + if (! newdev) +- return grub_errno; ++ goto fail; + + newdev->devname = grub_strdup (args[0]); + if (! newdev->devname) + { + grub_free (newdev); +- return grub_errno; ++ goto fail; + } + + newdev->filename = grub_strdup (args[1]); +@@ -130,9 +131,11 @@ + { + grub_free (newdev->devname); + grub_free (newdev); +- return grub_errno; ++ goto fail; + } + ++ newdev->file = file; ++ + /* Set has_partitions when `--partitions' was used. */ + newdev->has_partitions = state[1].set; + +@@ -141,6 +144,10 @@ + loopback_list = newdev; + + return 0; ++ ++fail: ++ grub_file_close (file); ++ return grub_errno; + } + + +@@ -159,7 +166,6 @@ + static grub_err_t + grub_loopback_open (const char *name, grub_disk_t disk) + { +- grub_file_t file; + struct grub_loopback *dev; + + for (dev = loopback_list; dev; dev = dev->next) +@@ -169,29 +175,17 @@ + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + +- file = grub_file_open (dev->filename); +- if (! file) +- return grub_errno; +- + /* Use the filesize for the disk size, round up to a complete sector. */ +- disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1) ++ disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1) + / GRUB_DISK_SECTOR_SIZE); + disk->id = (unsigned long) dev; + + disk->has_partitions = dev->has_partitions; +- disk->data = file; ++ disk->data = dev->file; + + return 0; + } + +-static void +-grub_loopback_close (grub_disk_t disk) +-{ +- grub_file_t file = (grub_file_t) disk->data; +- +- grub_file_close (file); +-} +- + static grub_err_t + grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +@@ -233,7 +227,6 @@ + .id = GRUB_DISK_DEVICE_LOOPBACK_ID, + .iterate = grub_loopback_iterate, + .open = grub_loopback_open, +- .close = grub_loopback_close, + .read = grub_loopback_read, + .write = grub_loopback_write, + .next = 0 diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/957_handle_loopback.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/957_handle_loopback.diff new file mode 100644 index 0000000..0ee868f --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/957_handle_loopback.diff @@ -0,0 +1,45 @@ +Ubuntu: needed for Wubi +Description: Change prepare_grub_to_access_device to handle filesystems + loop-mounted on file images. +UbuntuSpecific: Not inherently. losetup and /proc/mounts are Linux-specific, + though, so we might need to refine this before sending it upstream. + +diff -Nur -x '*.orig' -x '*~' grub2-1.97~beta3/util/grub-mkconfig_lib.in grub2-1.97~beta3.new/util/grub-mkconfig_lib.in +--- grub2-1.97~beta3/util/grub-mkconfig_lib.in 2009-09-15 00:23:50.000000000 +0100 ++++ grub2-1.97~beta3.new/util/grub-mkconfig_lib.in 2009-09-15 00:31:31.000000000 +0100 +@@ -142,6 +142,20 @@ + { + device=$1 + ++ loop_file= ++ case ${device} in ++ /dev/loop/*|/dev/loop[0-9]) ++ loop_file=`losetup ${device} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` ++ case $loop_file in ++ /dev/*) ;; ++ *) ++ loop_device=${device} ++ device=`${grub_probe} --target=device "${loop_file}"` ++ ;; ++ esac ++ ;; ++ esac ++ + # Abstraction modules aren't auto-loaded. + abstraction="`${grub_probe} --device ${device} --target=abstraction`" + for module in ${abstraction} ; do +@@ -159,6 +173,14 @@ + if fs_uuid="`${grub_probe} --device ${device} --target=fs_uuid 2> /dev/null`" ; then + echo "search --no-floppy --fs-uuid --set ${fs_uuid}" + fi ++ ++ if [ "x${loop_file}" != x ]; then ++ loop_mountpoint="$(awk '"'${loop_file}'" ~ "^"$2 && $2 != "/" { print $2 }' /proc/mounts | tail -n1)" ++ if [ "x${loop_mountpoint}" != x ]; then ++ echo "loopback loop0 ${loop_file#$loop_mountpoint}" ++ echo "set root=(loop0)" ++ fi ++ fi + } + + grub_file_is_not_garbage () diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/958_linux_no_loopmount.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/958_linux_no_loopmount.diff new file mode 100644 index 0000000..9e0dfda --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/958_linux_no_loopmount.diff @@ -0,0 +1,20 @@ +Ubuntu: needed for Wubi +Description: Ignore devices loop-mounted from files in 10_linux. +UbuntuSpecific: Not inherently, but perhaps we should integrate 10_lupin + properly instead. + +diff -Nur -x '*.orig' -x '*~' grub2-1.97~beta3/util/grub.d/10_linux.in grub2-1.97~beta3.new/util/grub.d/10_linux.in +--- grub2-1.97~beta3/util/grub.d/10_linux.in 2009-09-16 17:41:06.000000000 +0100 ++++ grub2-1.97~beta3.new/util/grub.d/10_linux.in 2009-09-16 17:44:52.000000000 +0100 +@@ -32,6 +32,11 @@ + case ${GRUB_DEVICE} in + /dev/loop/*|/dev/loop[0-9]) + GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` ++ # We can't cope with devices loop-mounted from files here. ++ case ${GRUB_DEVICE} in ++ /dev/*) ;; ++ *) exit 0 ;; ++ esac + ;; + esac + diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/960_raid_virtio.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/960_raid_virtio.diff new file mode 100644 index 0000000..3b060ba --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/960_raid_virtio.diff @@ -0,0 +1,158 @@ +diff -Nur -x '*.orig' -x '*~' grub2/include/grub/util/getroot.h grub2.new/include/grub/util/getroot.h +--- grub2/include/grub/util/getroot.h 2009-11-29 18:42:14.000000000 -0800 ++++ grub2.new/include/grub/util/getroot.h 2010-02-03 14:38:02.000000000 -0800 +@@ -19,12 +19,15 @@ + #ifndef GRUB_UTIL_GETROOT_HEADER + #define GRUB_UTIL_GETROOT_HEADER 1 + ++#include <sys/types.h> ++ + enum grub_dev_abstraction_types { + GRUB_DEV_ABSTRACTION_NONE, + GRUB_DEV_ABSTRACTION_LVM, + GRUB_DEV_ABSTRACTION_RAID, + }; + ++char *grub_find_device (const char *dir, dev_t dev); + char *grub_guess_root_device (const char *dir); + char *grub_get_prefix (const char *dir); + int grub_util_get_dev_abstraction (const char *os_dev); +diff -Nur -x '*.orig' -x '*~' grub2/util/getroot.c grub2.new/util/getroot.c +--- grub2/util/getroot.c 2010-02-01 14:33:16.000000000 -0800 ++++ grub2.new/util/getroot.c 2010-02-03 14:38:02.000000000 -0800 +@@ -178,8 +178,8 @@ + + #ifdef __MINGW32__ + +-static char * +-find_root_device (const char *dir __attribute__ ((unused)), ++char * ++grub_find_device (const char *dir __attribute__ ((unused)), + dev_t dev __attribute__ ((unused))) + { + return 0; +@@ -187,13 +187,22 @@ + + #elif ! defined(__CYGWIN__) + +-static char * +-find_root_device (const char *dir, dev_t dev) ++char * ++grub_find_device (const char *dir, dev_t dev) + { + DIR *dp; + char *saved_cwd; + struct dirent *ent; + ++ if (! dir) ++ { ++#ifdef __CYGWIN__ ++ return NULL; ++#else ++ dir = "/dev"; ++#endif ++ } ++ + dp = opendir (dir); + if (! dp) + return 0; +@@ -231,7 +240,7 @@ + /* Find it recursively. */ + char *res; + +- res = find_root_device (ent->d_name, dev); ++ res = grub_find_device (ent->d_name, dev); + + if (res) + { +@@ -334,8 +343,8 @@ + return serial; + } + +-static char * +-find_cygwin_root_device (const char *path, dev_t dev) ++char * ++grub_find_device (const char *path, dev_t dev) + { + /* No root device for /cygdrive. */ + if (dev == (DEV_CYGDRIVE_MAJOR << 16)) +@@ -356,7 +365,7 @@ + + /* Cygwin returns the partition serial number in stat.st_dev. + This is never identical to the device number of the emulated +- /dev/sdXN device, so above find_root_device () does not work. ++ /dev/sdXN device, so above grub_find_device () does not work. + Search the partition with the same serial in boot sector instead. */ + char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */ + int d; +@@ -449,12 +458,12 @@ + + #ifdef __CYGWIN__ + /* Cygwin specific function. */ +- os_dev = find_cygwin_root_device (dir, st.st_dev); ++ os_dev = grub_find_device (dir, st.st_dev); + + #else + + /* This might be truly slow, but is there any better way? */ +- os_dev = find_root_device ("/dev", st.st_dev); ++ os_dev = grub_find_device ("/dev", st.st_dev); + #endif + #endif /* !__GNU__ */ + +diff -Nur -x '*.orig' -x '*~' grub2/util/raid.c grub2.new/util/raid.c +--- grub2/util/raid.c 2010-02-01 14:33:15.000000000 -0800 ++++ grub2.new/util/raid.c 2010-02-03 14:39:38.000000000 -0800 +@@ -21,40 +21,19 @@ + #ifdef __linux__ + #include <grub/util/misc.h> + #include <grub/util/raid.h> ++#include <grub/util/getroot.h> + + #include <string.h> + #include <fcntl.h> + #include <sys/ioctl.h> + #include <errno.h> ++#include <sys/types.h> + + #include <linux/types.h> + #include <linux/major.h> + #include <linux/raid/md_p.h> + #include <linux/raid/md_u.h> + +-static char * +-grub_util_getdiskname (int major, int minor) +-{ +- char *name = xmalloc (15); +- +- if (major == LOOP_MAJOR) +- sprintf (name, "/dev/loop%d", minor); +- else if (major == IDE0_MAJOR) +- sprintf (name, "/dev/hd%c", 'a' + minor / 64); +- else if (major == IDE1_MAJOR) +- sprintf (name, "/dev/hd%c", 'c' + minor / 64); +- else if (major == IDE2_MAJOR) +- sprintf (name, "/dev/hd%c", 'e' + minor / 64); +- else if (major == IDE3_MAJOR) +- sprintf (name, "/dev/hd%c", 'g' + minor / 64); +- else if (major == SCSI_DISK0_MAJOR) +- sprintf (name, "/dev/sd%c", 'a' + minor / 16); +- else +- grub_util_error ("unknown device number: %d, %d", major, minor); +- +- return name; +-} +- + char ** + grub_util_raid_getmembers (char *name) + { +@@ -99,7 +78,8 @@ + + if (disk.state & (1 << MD_DISK_ACTIVE)) + { +- devicelist[j] = grub_util_getdiskname (disk.major, disk.minor); ++ devicelist[j] = grub_find_device (NULL, ++ makedev (disk.major, disk.minor)); + j++; + } + } diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/961_dmraid_probe.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/961_dmraid_probe.diff new file mode 100644 index 0000000..8bc9470 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/961_dmraid_probe.diff @@ -0,0 +1,650 @@ +Description: Add DM-RAID probing support. +Upstream: Maintained in an upstream branch, + sftp://bzr.sv.gnu.org/srv/bzr/grub/branches/dmraid-probe/; see + http://lists.gnu.org/archive/html/grub-devel/2010-01/msg00345.html + +diff -Nur -x '*.orig' -x '*~' grub2/ChangeLog.dmraid-probe grub2.new/ChangeLog.dmraid-probe +--- grub2/ChangeLog.dmraid-probe 1969-12-31 16:00:00.000000000 -0800 ++++ grub2.new/ChangeLog.dmraid-probe 2010-02-06 10:33:54.000000000 -0800 +@@ -0,0 +1,26 @@ ++2010-01-31 Colin Watson <cjwatson@ubuntu.com> ++ ++ * configure.ac: Check for Linux device-mapper support. ++ ++ * util/hostdisk.c (device_is_mapped): New function. ++ (find_partition_start): New function, partly broken out from ++ linux_find_partition and grub_util_biosdisk_get_grub_dev but with ++ device-mapper support added. ++ (linux_find_partition): Use find_partition_start. ++ (convert_system_partition_to_system_disk): Add `st' argument. ++ Support Linux /dev/mapper/* devices if device-mapper support is ++ available; only DM-RAID devices are understood at present. ++ (find_system_device): Add `st' argument. Pass it to ++ convert_system_partition_to_system_disk. ++ (grub_util_biosdisk_get_grub_dev): Pass stat result to ++ find_system_device and convert_system_partition_to_system_disk. Use ++ find_partition_start. ++ ++ * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, ++ kern/err.c, kern/list.c, and kern/misc.c. ++ * util/deviceiter.c [__linux__]: Define MINOR. ++ (grub_util_iterate_devices): Add support for DM-RAID disk devices. ++ * util/mkdevicemap.c (grub_putchar): New function. ++ (grub_getkey): New function. ++ (grub_refresh): New function. ++ (main): Set debug=all if -v -v is used. +diff -Nur -x '*.orig' -x '*~' grub2/conf/common.rmk grub2.new/conf/common.rmk +--- grub2/conf/common.rmk 2010-02-06 10:32:37.000000000 -0800 ++++ grub2.new/conf/common.rmk 2010-02-06 10:33:54.000000000 -0800 +@@ -3,7 +3,8 @@ + sbin_UTILITIES += grub-mkdevicemap + grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ + util/deviceiter.c \ +- util/misc.c ++ util/misc.c \ ++ kern/env.c kern/err.c kern/list.c kern/misc.c + + ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) + grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c +diff -Nur -x '*.orig' -x '*~' grub2/configure.ac grub2.new/configure.ac +--- grub2/configure.ac 2010-02-06 10:32:49.000000000 -0800 ++++ grub2.new/configure.ac 2010-02-06 10:33:54.000000000 -0800 +@@ -660,6 +660,22 @@ + AC_SUBST([freetype_cflags]) + AC_SUBST([freetype_libs]) + ++AC_ARG_ENABLE([device-mapper], ++ [AS_HELP_STRING([--enable-device-mapper], ++ [enable Linux device-mapper support (default=guessed)])]) ++if test x"$enable_device_mapper" = xno ; then ++ device_mapper_excuse="explicitly disabled" ++fi ++ ++if test x"$device_mapper_excuse" = x ; then ++ # Check for device-mapper library. ++ AC_CHECK_LIB([devmapper], [dm_task_create], ++ [LDFLAGS="$LDFLAGS -ldevmapper" ++ AC_DEFINE([HAVE_DEVICE_MAPPER], [1], ++ [Define to 1 if you have the devmapper library.])], ++ [device_mapper_excuse="need devmapper library"]) ++fi ++ + AC_SUBST(ASFLAGS) + + # Output files. +diff -Nur -x '*.orig' -x '*~' grub2/util/deviceiter.c grub2.new/util/deviceiter.c +--- grub2/util/deviceiter.c 2010-02-06 10:32:37.000000000 -0800 ++++ grub2.new/util/deviceiter.c 2010-02-06 10:33:54.000000000 -0800 +@@ -31,6 +31,8 @@ + + #include <grub/util/misc.h> + #include <grub/util/deviceiter.h> ++#include <grub/list.h> ++#include <grub/misc.h> + + #ifdef __linux__ + # if !defined(__GLIBC__) || \ +@@ -62,12 +64,23 @@ + | ((unsigned int) (__dev >> 32) & ~0xfff); \ + }) + # endif /* ! MAJOR */ ++# ifndef MINOR ++# define MINOR(dev) \ ++ ({ \ ++ unsigned long long __dev = (dev); \ ++ (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \ ++ }) ++# endif /* ! MINOR */ + # ifndef CDROM_GET_CAPABILITY + # define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ + # endif /* ! CDROM_GET_CAPABILITY */ + # ifndef BLKGETSIZE + # define BLKGETSIZE _IO(0x12,96) /* return device size */ + # endif /* ! BLKGETSIZE */ ++ ++#ifdef HAVE_DEVICE_MAPPER ++# include <libdevmapper.h> ++#endif + #endif /* __linux__ */ + + /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with +@@ -411,6 +424,16 @@ + return 1; + } + ++#ifdef __linux__ ++# ifdef HAVE_DEVICE_MAPPER ++struct dmraid_seen ++{ ++ struct dmraid_seen *next; ++ const char *name; ++}; ++# endif /* HAVE_DEVICE_MAPPER */ ++#endif /* __linux__ */ ++ + void + grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), + int floppy_disks) +@@ -643,6 +666,123 @@ + return; + } + } ++ ++# ifdef HAVE_DEVICE_MAPPER ++# define dmraid_check(cond, ...) \ ++ if (! (cond)) \ ++ { \ ++ grub_dprintf ("deviceiter", __VA_ARGS__); \ ++ goto dmraid_end; \ ++ } ++ ++ /* DM-RAID. */ ++ { ++ struct dm_tree *tree = NULL; ++ struct dm_task *task = NULL; ++ struct dm_names *names = NULL; ++ unsigned int next = 0; ++ void *top_handle, *second_handle; ++ struct dm_tree_node *root, *top, *second; ++ struct dmraid_seen *seen = NULL; ++ ++ /* Build DM tree for all devices. */ ++ tree = dm_tree_create (); ++ dmraid_check (tree, "dm_tree_create failed\n"); ++ task = dm_task_create (DM_DEVICE_LIST); ++ dmraid_check (task, "dm_task_create failed\n"); ++ dmraid_check (dm_task_run (task), "dm_task_run failed\n"); ++ names = dm_task_get_names (task); ++ dmraid_check (names, "dm_task_get_names failed\n"); ++ dmraid_check (names->dev, "No DM devices found\n"); ++ do ++ { ++ names = (void *) names + next; ++ dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), ++ MINOR (names->dev)), ++ "dm_tree_add_dev (%s) failed\n", names->name); ++ next = names->next; ++ } ++ while (next); ++ ++ /* Walk the second-level children of the inverted tree; that is, devices ++ which are directly composed of non-DM devices such as hard disks. ++ This class includes all DM-RAID disks and excludes all DM-RAID ++ partitions. */ ++ root = dm_tree_find_node (tree, 0, 0); ++ top_handle = NULL; ++ top = dm_tree_next_child (&top_handle, root, 1); ++ while (top) ++ { ++ second_handle = NULL; ++ second = dm_tree_next_child (&second_handle, top, 1); ++ while (second) ++ { ++ const char *node_name, *node_uuid; ++ char *name; ++ struct dmraid_seen *seen_elt; ++ ++ node_name = dm_tree_node_get_name (second); ++ dmraid_check (node_name, "dm_tree_node_get_name failed\n"); ++ node_uuid = dm_tree_node_get_uuid (second); ++ dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); ++ if (strncmp (node_uuid, "DMRAID-", 7) != 0) ++ { ++ grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); ++ goto dmraid_next_child; ++ } ++ ++ /* Have we already seen this node? There are typically very few ++ DM-RAID disks, so a list should be fast enough. */ ++ if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) ++ { ++ grub_dprintf ("deviceiter", "Already seen DM device %s\n", ++ node_name); ++ goto dmraid_next_child; ++ } ++ ++ name = xasprintf ("/dev/mapper/%s", node_name); ++ if (check_device (name)) ++ { ++ if (hook (name, 0)) ++ { ++ free (name); ++ while (seen) ++ { ++ struct dmraid_seen *seen_elt = ++ grub_list_pop (GRUB_AS_LIST_P (&seen)); ++ free (seen_elt); ++ } ++ if (task) ++ dm_task_destroy (task); ++ if (tree) ++ dm_tree_free (tree); ++ return; ++ } ++ } ++ free (name); ++ ++ seen_elt = xmalloc (sizeof *seen_elt); ++ seen_elt->name = node_name; ++ grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); ++ ++dmraid_next_child: ++ second = dm_tree_next_child (&second_handle, top, 1); ++ } ++ top = dm_tree_next_child (&top_handle, root, 1); ++ } ++ ++dmraid_end: ++ while (seen) ++ { ++ struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); ++ free (seen_elt); ++ } ++ if (task) ++ dm_task_destroy (task); ++ if (tree) ++ dm_tree_free (tree); ++ } ++# endif /* HAVE_DEVICE_MAPPER */ + #endif /* __linux__ */ + } + +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-mkdevicemap.c grub2.new/util/grub-mkdevicemap.c +--- grub2/util/grub-mkdevicemap.c 2010-02-06 10:32:37.000000000 -0800 ++++ grub2.new/util/grub-mkdevicemap.c 2010-02-06 10:33:54.000000000 -0800 +@@ -31,6 +31,7 @@ + + #include <grub/util/misc.h> + #include <grub/util/deviceiter.h> ++#include <grub/env.h> + #include <grub/i18n.h> + + #define _GNU_SOURCE 1 +@@ -38,6 +39,24 @@ + + #include "progname.h" + ++void ++grub_putchar (int c) ++{ ++ putchar (c); ++} ++ ++int ++grub_getkey (void) ++{ ++ return -1; ++} ++ ++void ++grub_refresh (void) ++{ ++ fflush (stdout); ++} ++ + static void + make_device_map (const char *device_map, int floppy_disks) + { +@@ -158,6 +177,9 @@ + } + } + ++ if (verbosity > 1) ++ grub_env_set ("debug", "all"); ++ + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); + + free (dev_map); +diff -Nur -x '*.orig' -x '*~' grub2/util/hostdisk.c grub2.new/util/hostdisk.c +--- grub2/util/hostdisk.c 2010-02-06 10:32:55.000000000 -0800 ++++ grub2.new/util/hostdisk.c 2010-02-06 10:33:54.000000000 -0800 +@@ -97,6 +97,10 @@ + # include <sys/disk.h> + #endif + ++#ifdef HAVE_DEVICE_MAPPER ++# include <libdevmapper.h> ++#endif ++ + struct + { + char *drive; +@@ -253,6 +257,115 @@ + return GRUB_ERR_NONE; + } + ++#ifdef HAVE_DEVICE_MAPPER ++static int ++device_is_mapped (const char *dev) ++{ ++ struct stat st; ++ ++ if (stat (dev, &st) < 0) ++ return 0; ++ ++ return dm_is_dm_major (major (st.st_rdev)); ++} ++#endif /* HAVE_DEVICE_MAPPER */ ++ ++#if defined(__linux__) || defined(__CYGWIN__) ++static grub_disk_addr_t ++find_partition_start (const char *dev) ++{ ++ int fd; ++ struct hd_geometry hdg; ++ ++#ifdef HAVE_DEVICE_MAPPER ++ if (device_is_mapped (dev)) { ++ struct dm_task *task = NULL; ++ grub_uint64_t start, length; ++ char *target_type, *params, *space; ++ grub_disk_addr_t partition_start; ++ ++ /* If any device-mapper operation fails, we fall back silently to ++ HDIO_GETGEO. */ ++ task = dm_task_create (DM_DEVICE_TABLE); ++ if (! task) ++ { ++ grub_dprintf ("hostdisk", "dm_task_create failed\n"); ++ goto devmapper_fail; ++ } ++ ++ if (! dm_task_set_name (task, dev)) ++ { ++ grub_dprintf ("hostdisk", "dm_task_set_name failed\n"); ++ goto devmapper_fail; ++ } ++ ++ if (! dm_task_run (task)) ++ { ++ grub_dprintf ("hostdisk", "dm_task_run failed\n"); ++ goto devmapper_fail; ++ } ++ ++ dm_get_next_target (task, NULL, &start, &length, &target_type, ¶ms); ++ if (! target_type) ++ { ++ grub_dprintf ("hostdisk", "no dm target\n"); ++ goto devmapper_fail; ++ } ++ if (strcmp (target_type, "linear") != 0) ++ { ++ grub_dprintf ("hostdisk", "ignoring dm target %s (not linear)\n", ++ target_type); ++ goto devmapper_fail; ++ } ++ if (! params) ++ { ++ grub_dprintf ("hostdisk", "no dm params\n"); ++ goto devmapper_fail; ++ } ++ ++ /* The params string for a linear target looks like this: ++ DEVICE-NAME START-SECTOR ++ Parse this out. */ ++ space = strchr (params, ' '); ++ if (! space) ++ goto devmapper_fail; ++ errno = 0; ++ partition_start = strtoull (space + 1, NULL, 10); ++ if (errno == 0) ++ { ++ grub_dprintf ("hostdisk", "dm %s starts at %llu\n", ++ dev, partition_start); ++ dm_task_destroy (task); ++ return partition_start; ++ } ++ ++devmapper_fail: ++ if (task) ++ dm_task_destroy (task); ++ } ++#endif /* HAVE_DEVICE_MAPPER */ ++ ++ fd = open (dev, O_RDONLY); ++ if (fd == -1) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); ++ return 0; ++ } ++ ++ if (ioctl (fd, HDIO_GETGEO, &hdg)) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, ++ "cannot get geometry of `%s'", dev); ++ close (fd); ++ return 0; ++ } ++ ++ close (fd); ++ ++ return hdg.start; ++} ++#endif /* __linux__ || __CYGWIN__ */ ++ + #ifdef __linux__ + static int + linux_find_partition (char *dev, unsigned long sector) +@@ -284,22 +397,20 @@ + for (i = 1; i < 10000; i++) + { + int fd; +- struct hd_geometry hdg; ++ grub_disk_addr_t start; + + sprintf (p, format, i); ++ + fd = open (real_dev, O_RDONLY); + if (fd == -1) + return 0; +- +- if (ioctl (fd, HDIO_GETGEO, &hdg)) +- { +- close (fd); +- return 0; +- } +- + close (fd); + +- if (hdg.start == sector) ++ start = find_partition_start (real_dev); ++ /* We don't care about errors here. */ ++ grub_errno = GRUB_ERR_NONE; ++ ++ if (start == sector) + { + strcpy (dev, real_dev); + return 1; +@@ -711,7 +822,7 @@ + } + + static char * +-convert_system_partition_to_system_disk (const char *os_dev) ++convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) + { + #if defined(__linux__) + char *path = xmalloc (PATH_MAX); +@@ -829,6 +940,96 @@ + p[4] = '\0'; + return path; + } ++ ++#ifdef HAVE_DEVICE_MAPPER ++ /* If this is a DM-RAID device. */ ++ if ((strncmp ("mapper/", p, 7) == 0)) ++ { ++ static struct dm_tree *tree = NULL; ++ uint32_t maj, min; ++ struct dm_tree_node *node, *child; ++ void *handle; ++ const char *node_uuid, *mapper_name, *child_uuid, *child_name; ++ ++ if (! tree) ++ tree = dm_tree_create (); ++ ++ if (! tree) ++ { ++ grub_dprintf ("hostdisk", "dm_tree_create failed\n"); ++ return NULL; ++ } ++ ++ maj = major (st->st_rdev); ++ min = minor (st->st_rdev); ++ if (! dm_tree_add_dev (tree, maj, min)) ++ { ++ grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); ++ return NULL; ++ } ++ ++ node = dm_tree_find_node (tree, maj, min); ++ if (! node) ++ { ++ grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); ++ return NULL; ++ } ++ node_uuid = dm_tree_node_get_uuid (node); ++ if (! node_uuid) ++ { ++ grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); ++ return NULL; ++ } ++ else if (strncmp (node_uuid, "DMRAID-", 7) != 0) ++ { ++ grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); ++ return NULL; ++ } ++ ++ handle = NULL; ++ mapper_name = NULL; ++ /* Counter-intuitively, device-mapper refers to the disk-like ++ device containing a DM-RAID partition device as a "child" of ++ the partition device. */ ++ child = dm_tree_next_child (&handle, node, 0); ++ if (! child) ++ { ++ grub_dprintf ("hostdisk", "%s has no DM children\n", path); ++ goto devmapper_out; ++ } ++ child_uuid = dm_tree_node_get_uuid (child); ++ if (! child_uuid) ++ { ++ grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); ++ goto devmapper_out; ++ } ++ else if (strncmp (child_uuid, "DMRAID-", 7) != 0) ++ { ++ grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); ++ goto devmapper_out; ++ } ++ child_name = dm_tree_node_get_name (child); ++ if (! child_name) ++ { ++ grub_dprintf ("hostdisk", "%s child has no DM name\n", path); ++ goto devmapper_out; ++ } ++ mapper_name = child_name; ++ ++devmapper_out: ++ if (! mapper_name) ++ { ++ /* This is a DM-RAID disk, not a partition. */ ++ mapper_name = dm_tree_node_get_name (node); ++ if (! mapper_name) ++ { ++ grub_dprintf ("hostdisk", "%s has no DM name\n", path); ++ return NULL; ++ } ++ } ++ return xasprintf ("/dev/mapper/%s", mapper_name); ++ } ++#endif /* HAVE_DEVICE_MAPPER */ + } + + return path; +@@ -884,12 +1085,12 @@ + #endif + + static int +-find_system_device (const char *os_dev) ++find_system_device (const char *os_dev, struct stat *st) + { + unsigned int i; + char *os_disk; + +- os_disk = convert_system_partition_to_system_disk (os_dev); ++ os_disk = convert_system_partition_to_system_disk (os_dev, st); + if (! os_disk) + return -1; + +@@ -923,7 +1124,7 @@ + return 0; + } + +- drive = find_system_device (os_dev); ++ drive = find_system_device (os_dev, &st); + if (drive < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, +@@ -931,8 +1132,8 @@ + return 0; + } + +- if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev)) +- == 0) ++ if (grub_strcmp (os_dev, ++ convert_system_partition_to_system_disk (os_dev, &st)) == 0) + return make_device_name (drive, -1, -1); + + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) +@@ -954,8 +1155,7 @@ + { + char *name; + grub_disk_t disk; +- int fd; +- struct hd_geometry hdg; ++ grub_disk_addr_t start; + int dos_part = -1; + int bsd_part = -1; + auto int find_partition (grub_disk_t disk, +@@ -985,7 +1185,7 @@ + partition->index, partition->start); + } + +- if (hdg.start == partition->start) ++ if (start == partition->start) + { + if (pcdata) + { +@@ -1008,28 +1208,16 @@ + if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) + return name; + +- fd = open (os_dev, O_RDONLY); +- if (fd == -1) +- { +- grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); +- free (name); +- return 0; +- } +- +- if (ioctl (fd, HDIO_GETGEO, &hdg)) ++ start = find_partition_start (os_dev); ++ if (grub_errno != GRUB_ERR_NONE) + { +- grub_error (GRUB_ERR_BAD_DEVICE, +- "cannot get geometry of `%s'", os_dev); +- close (fd); + free (name); + return 0; + } + +- close (fd); +- +- grub_util_info ("%s starts from %lu", os_dev, hdg.start); ++ grub_util_info ("%s starts from %lu", os_dev, start); + +- if (hdg.start == 0 && device_is_wholedisk (os_dev)) ++ if (start == 0 && device_is_wholedisk (os_dev)) + return name; + + grub_util_info ("opening the device %s", name); diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/962_no_device_map.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/962_no_device_map.diff new file mode 100644 index 0000000..c129254 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/962_no_device_map.diff @@ -0,0 +1,112 @@ +Ubuntu: Don't generate a device map by default. + +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-install.in grub2.new/util/grub-install.in +--- grub2/util/grub-install.in 2010-03-22 14:11:42.000000000 +0000 ++++ grub2.new/util/grub-install.in 2010-03-22 16:23:14.000000000 +0000 +@@ -39,7 +39,6 @@ + else + grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` + fi +-grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` + grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` + grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` + rootdir= +@@ -74,7 +73,6 @@ + instead of the root directory + --grub-setup=FILE use FILE as grub-setup + --grub-mkimage=FILE use FILE as grub-mkimage +- --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap + --grub-probe=FILE use FILE as grub-probe + --no-floppy do not probe any floppy drive + --recheck probe a device map even if it already exists +@@ -124,7 +122,7 @@ + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --grub-mkdevicemap=*) +- grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; ++ : ;; # compatibility only + --grub-probe=*) + grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-floppy) +@@ -209,14 +207,6 @@ + exit 1 + fi + +-set $grub_mkdevicemap dummy +-if test -f "$1"; then +- : +-else +- echo "$1: Not found." 1>&2 +- exit 1 +-fi +- + # Create the GRUB directory if it is not present. + test -d "$bootdir" || mkdir "$bootdir" || exit 1 + test -d "$grubdir" || mkdir "$grubdir" || exit 1 +@@ -226,22 +216,14 @@ + rm -f $device_map + fi + +-# Create the device map file if it is not present. ++# Make sure that there is no duplicated entry in the device map. + if test -f "$device_map"; then +- : +-else +- # Create a safe temporary file. +- test -n "$mklog" && log_file=`$mklog` +- +- $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 +-fi +- +-# Make sure that there is no duplicated entry. +-tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ +- | sort | uniq -d | sed -n 1p` +-if test -n "$tmp"; then +- echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 +- exit 1 ++ tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ ++ | sort | uniq -d | sed -n 1p` ++ if test -n "$tmp"; then ++ echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 ++ exit 1 ++ fi + fi + + # Copy the GRUB images to the GRUB directory. +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-mkconfig.in grub2.new/util/grub-mkconfig.in +--- grub2/util/grub-mkconfig.in 2010-03-22 16:23:13.000000000 +0000 ++++ grub2.new/util/grub-mkconfig.in 2010-03-22 16:23:57.000000000 +0000 +@@ -31,7 +31,6 @@ + grub_cfg="" + grub_mkconfig_dir=${sysconfdir}/grub.d + +-grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` + grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` + + # Usage: usage +@@ -96,14 +95,6 @@ + fi + fi + +-set $grub_mkdevicemap dummy +-if test -f "$1"; then +- : +-else +- echo "$1: Not found." 1>&2 +- exit 1 +-fi +- + set $grub_probe dummy + if test -f "$1"; then + : +@@ -114,10 +105,6 @@ + + mkdir -p ${grub_prefix} + +-if test -e ${grub_prefix}/device.map ; then : ; else +- ${grub_mkdevicemap} +-fi +- + # Device containing our userland. Typically used for root= parameter. + GRUB_DEVICE="`${grub_probe} --target=device /`" + GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff new file mode 100644 index 0000000..30ebcbe --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff @@ -0,0 +1,310 @@ +Upstream: http://lists.gnu.org/archive/html/grub-devel/2010-03/msg00008.html +Description: Optimise hostdisk device handling + This substantially speeds up grub-probe filesystem reads. + +diff -Nur -x '*.orig' -x '*~' grub2/ChangeLog.hostdisk-speedup grub2.new/ChangeLog.hostdisk-speedup +--- grub2/ChangeLog.hostdisk-speedup 1970-01-01 01:00:00.000000000 +0100 ++++ grub2.new/ChangeLog.hostdisk-speedup 2010-03-03 10:43:43.000000000 +0000 +@@ -0,0 +1,18 @@ ++2010-03-03 Colin Watson <cjwatson@ubuntu.com> ++ ++ * util/hostdisk.c (struct grub_util_biosdisk_data): New structure. ++ (grub_util_biosdisk_open): Initialise disk->data. ++ (struct linux_partition_cache): New structure. ++ (linux_find_partition): Cache partition start positions; these are ++ expensive to compute on every read and write. ++ (open_device): Cache open file descriptor in disk->data, so that we ++ don't have to reopen it and flush the buffer cache for consecutive ++ operations on the same device. ++ (grub_util_biosdisk_close): New function. ++ (grub_util_biosdisk_dev): Set `close' member. ++ ++ * conf/common.rmk (grub_probe_SOURCES): Add kern/list.c. ++ * conf/i386-efi.rmk (grub_setup_SOURCES): Likewise. ++ * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. ++ * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. ++ * conf/x86_64-efi.rmk (grub_setup_SOURCES): Likewise. +diff -Nur -x '*.orig' -x '*~' grub2/conf/common.rmk grub2.new/conf/common.rmk +--- grub2/conf/common.rmk 2010-03-03 20:11:04.000000000 +0000 ++++ grub2.new/conf/common.rmk 2010-03-03 20:11:05.000000000 +0000 +@@ -25,7 +25,7 @@ + grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ + util/hostdisk.c util/misc.c util/getroot.c \ + kern/device.c kern/disk.c kern/err.c kern/misc.c \ +- kern/parser.c kern/partition.c kern/file.c \ ++ kern/parser.c kern/partition.c kern/file.c kern/list.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ +diff -Nur -x '*.orig' -x '*~' grub2/conf/i386-efi.rmk grub2.new/conf/i386-efi.rmk +--- grub2/conf/i386-efi.rmk 2010-03-03 20:08:04.000000000 +0000 ++++ grub2.new/conf/i386-efi.rmk 2010-03-03 20:11:05.000000000 +0000 +@@ -21,7 +21,7 @@ + # kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ + # fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ + # fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +-# kern/fs.c kern/env.c fs/fshelp.c ++# kern/fs.c kern/env.c kern/list.c fs/fshelp.c + + # Scripts. + sbin_SCRIPTS = grub-install +diff -Nur -x '*.orig' -x '*~' grub2/conf/i386-pc.rmk grub2.new/conf/i386-pc.rmk +--- grub2/conf/i386-pc.rmk 2010-03-03 20:08:04.000000000 +0000 ++++ grub2.new/conf/i386-pc.rmk 2010-03-03 20:11:05.000000000 +0000 +@@ -96,7 +96,8 @@ + util/i386/pc/grub-setup.c util/hostdisk.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ +- kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ ++ kern/file.c kern/fs.c kern/env.c kern/list.c \ ++ fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ +diff -Nur -x '*.orig' -x '*~' grub2/conf/sparc64-ieee1275.rmk grub2.new/conf/sparc64-ieee1275.rmk +--- grub2/conf/sparc64-ieee1275.rmk 2010-03-03 20:08:04.000000000 +0000 ++++ grub2.new/conf/sparc64-ieee1275.rmk 2010-03-03 20:11:05.000000000 +0000 +@@ -70,7 +70,8 @@ + grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ +- kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ ++ kern/file.c kern/fs.c kern/env.c kern/list.c \ ++ fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ +diff -Nur -x '*.orig' -x '*~' grub2/conf/x86_64-efi.rmk grub2.new/conf/x86_64-efi.rmk +--- grub2/conf/x86_64-efi.rmk 2010-03-03 20:08:04.000000000 +0000 ++++ grub2.new/conf/x86_64-efi.rmk 2010-03-03 20:11:05.000000000 +0000 +@@ -20,7 +20,7 @@ + # kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ + # fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ + # fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +-# kern/fs.c kern/env.c fs/fshelp.c ++# kern/fs.c kern/env.c kern/list.c fs/fshelp.c + + # Scripts. + sbin_SCRIPTS = grub-install +diff -Nur -x '*.orig' -x '*~' grub2/util/hostdisk.c grub2.new/util/hostdisk.c +--- grub2/util/hostdisk.c 2010-03-03 20:11:04.000000000 +0000 ++++ grub2.new/util/hostdisk.c 2010-03-03 20:11:05.000000000 +0000 +@@ -26,6 +26,7 @@ + #include <grub/util/hostdisk.h> + #include <grub/misc.h> + #include <grub/i18n.h> ++#include <grub/list.h> + + #include <stdio.h> + #include <stdlib.h> +@@ -107,6 +108,13 @@ + char *device; + } map[256]; + ++struct grub_util_biosdisk_data ++{ ++ char *dev; ++ int access_mode; ++ int fd; ++}; ++ + #ifdef __linux__ + /* Check if we have devfs support. */ + static int +@@ -169,6 +177,7 @@ + { + int drive; + struct stat st; ++ struct grub_util_biosdisk_data *data; + + drive = find_grub_drive (name); + if (drive < 0) +@@ -177,6 +186,10 @@ + + disk->has_partitions = 1; + disk->id = drive; ++ disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data)); ++ data->dev = NULL; ++ data->access_mode = 0; ++ data->fd = -1; + + /* Get the size. */ + #if defined(__MINGW32__) +@@ -367,6 +380,17 @@ + #endif /* __linux__ || __CYGWIN__ */ + + #ifdef __linux__ ++/* Cache of partition start sectors for each disk. */ ++struct linux_partition_cache ++{ ++ struct linux_partition_cache *next; ++ char *dev; ++ unsigned long start; ++ int partno; ++}; ++ ++struct linux_partition_cache *linux_partition_cache_list; ++ + static int + linux_find_partition (char *dev, unsigned long sector) + { +@@ -375,6 +399,7 @@ + char *p; + int i; + char real_dev[PATH_MAX]; ++ struct linux_partition_cache *cache; + + strcpy(real_dev, dev); + +@@ -394,6 +419,16 @@ + format = "%d"; + } + ++ for (cache = linux_partition_cache_list; cache; cache = cache->next) ++ { ++ if (strcmp (cache->dev, dev) == 0 && cache->start == sector) ++ { ++ sprintf (p, format, cache->partno); ++ strcpy (dev, real_dev); ++ return 1; ++ } ++ } ++ + for (i = 1; i < 10000; i++) + { + int fd; +@@ -412,6 +447,15 @@ + + if (start == sector) + { ++ struct linux_partition_cache *new_cache_item; ++ ++ new_cache_item = xmalloc (sizeof *new_cache_item); ++ new_cache_item->dev = xstrdup (dev); ++ new_cache_item->start = start; ++ new_cache_item->partno = i; ++ grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list), ++ GRUB_AS_LIST (new_cache_item)); ++ + strcpy (dev, real_dev); + return 1; + } +@@ -425,6 +469,7 @@ + open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) + { + int fd; ++ struct grub_util_biosdisk_data *data = disk->data; + + #ifdef O_LARGEFILE + flags |= O_LARGEFILE; +@@ -451,18 +496,35 @@ + && strncmp (map[disk->id].device, "/dev/", 5) == 0) + is_partition = linux_find_partition (dev, disk->partition->start); + +- /* Open the partition. */ +- grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); +- fd = open (dev, flags); +- if (fd < 0) ++ if (data->dev && strcmp (data->dev, dev) == 0 && ++ data->access_mode == (flags & O_ACCMODE)) + { +- grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); +- return -1; ++ grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev); ++ fd = data->fd; + } ++ else ++ { ++ free (data->dev); ++ if (data->fd != -1) ++ close (data->fd); ++ ++ /* Open the partition. */ ++ grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); ++ fd = open (dev, flags); ++ if (fd < 0) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); ++ return -1; ++ } + +- /* Flush the buffer cache to the physical disk. +- XXX: This also empties the buffer cache. */ +- ioctl (fd, BLKFLSBUF, 0); ++ /* Flush the buffer cache to the physical disk. ++ XXX: This also empties the buffer cache. */ ++ ioctl (fd, BLKFLSBUF, 0); ++ ++ data->dev = xstrdup (dev); ++ data->access_mode = (flags & O_ACCMODE); ++ data->fd = fd; ++ } + + if (is_partition) + sector -= disk->partition->start; +@@ -486,7 +548,26 @@ + } + #endif + +- fd = open (map[disk->id].device, flags); ++ if (data->dev && strcmp (data->dev, map[disk->id].device) == 0 && ++ data->access_mode == (flags & O_ACCMODE)) ++ { ++ grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev); ++ fd = data->fd; ++ } ++ else ++ { ++ free (data->dev); ++ if (data->fd != -1) ++ close (data->fd); ++ ++ fd = open (map[disk->id].device, flags); ++ if (fd >= 0) ++ { ++ data->dev = xstrdup (map[disk->id].device); ++ data->access_mode = (flags & O_ACCMODE); ++ data->fd = fd; ++ } ++ } + + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + if (! (sysctl_oldflags & 0x10) +@@ -646,7 +727,6 @@ + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device); + +- close (fd); + return grub_errno; + } + +@@ -681,17 +761,27 @@ + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device); + +- close (fd); + return grub_errno; + } + ++static void ++grub_util_biosdisk_close (struct grub_disk *disk) ++{ ++ struct grub_util_biosdisk_data *data = disk->data; ++ ++ free (data->dev); ++ if (data->fd != -1) ++ close (data->fd); ++ free (data); ++} ++ + static struct grub_disk_dev grub_util_biosdisk_dev = + { + .name = "biosdisk", + .id = GRUB_DISK_DEVICE_BIOSDISK_ID, + .iterate = grub_util_biosdisk_iterate, + .open = grub_util_biosdisk_open, +- .close = 0, ++ .close = grub_util_biosdisk_close, + .read = grub_util_biosdisk_read, + .write = grub_util_biosdisk_write, + .next = 0 diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/969_lvm_raid_probe.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/969_lvm_raid_probe.diff new file mode 100644 index 0000000..52a5c44 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/969_lvm_raid_probe.diff @@ -0,0 +1,227 @@ +Description: Fix LVM/RAID probing without device.map + When probing LVM or RAID without a device.map, probe all devices in order + that we will know about the underlying physical volumes. +Bug-Ubuntu: https://bugs.launchpad.net/bugs/525085 +Forwarded: http://lists.gnu.org/archive/html/grub-devel/2010-03/msg00084.html +Last-Update: 2010-03-22 + +diff -Nur -x '*.orig' -x '*~' grub2/conf/common.rmk grub2.new/conf/common.rmk +--- grub2/conf/common.rmk 2010-03-22 13:49:14.000000000 +0000 ++++ grub2.new/conf/common.rmk 2010-03-22 13:53:20.000000000 +0000 +@@ -24,6 +24,7 @@ + util/grub-probe.c_DEPENDENCIES = grub_probe_init.h + grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ + util/hostdisk.c util/misc.c util/getroot.c \ ++ util/deviceiter.c \ + kern/device.c kern/disk.c kern/err.c kern/misc.c \ + kern/parser.c kern/partition.c kern/file.c kern/list.c \ + \ +diff -Nur -x '*.orig' -x '*~' grub2/conf/i386-pc.rmk grub2.new/conf/i386-pc.rmk +--- grub2/conf/i386-pc.rmk 2010-03-22 13:49:14.000000000 +0000 ++++ grub2.new/conf/i386-pc.rmk 2010-03-22 13:49:17.000000000 +0000 +@@ -94,7 +94,8 @@ + util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h + grub_setup_SOURCES = gnulib/progname.c \ + util/i386/pc/grub-setup.c util/hostdisk.c \ +- util/misc.c util/getroot.c kern/device.c kern/disk.c \ ++ util/misc.c util/getroot.c util/deviceiter.c \ ++ kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ +diff -Nur -x '*.orig' -x '*~' grub2/conf/sparc64-ieee1275.rmk grub2.new/conf/sparc64-ieee1275.rmk +--- grub2/conf/sparc64-ieee1275.rmk 2010-03-22 13:49:14.000000000 +0000 ++++ grub2.new/conf/sparc64-ieee1275.rmk 2010-03-22 13:49:17.000000000 +0000 +@@ -68,7 +68,8 @@ + # For grub-setup. + util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h + grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ +- util/misc.c util/getroot.c kern/device.c kern/disk.c \ ++ util/misc.c util/getroot.c util/deviceiter.c \ ++ kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ +diff -Nur -x '*.orig' -x '*~' grub2/include/grub/util/hostdisk.h grub2.new/include/grub/util/hostdisk.h +--- grub2/include/grub/util/hostdisk.h 2010-03-22 13:47:27.000000000 +0000 ++++ grub2.new/include/grub/util/hostdisk.h 2010-03-22 13:51:33.000000000 +0000 +@@ -22,6 +22,7 @@ + + void grub_util_biosdisk_init (const char *dev_map); + void grub_util_biosdisk_fini (void); ++int grub_util_biosdisk_probe_device (const char *name, int is_floppy); + char *grub_util_biosdisk_get_grub_dev (const char *os_dev); + + #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-probe.c grub2.new/util/grub-probe.c +--- grub2/util/grub-probe.c 2010-03-22 13:47:27.000000000 +0000 ++++ grub2.new/util/grub-probe.c 2010-03-22 13:53:10.000000000 +0000 +@@ -28,6 +28,7 @@ + #include <grub/msdos_partition.h> + #include <grub/util/hostdisk.h> + #include <grub/util/getroot.h> ++#include <grub/util/deviceiter.h> + #include <grub/term.h> + #include <grub/env.h> + #include <grub/raid.h> +@@ -106,13 +107,14 @@ + } + + static void +-probe (const char *path, char *device_name) ++probe (const char *path, char *device_name, const char *dev_map) + { + char *drive_name = NULL; + char *grub_path = NULL; + char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL; + grub_device_t dev = NULL; + grub_fs_t fs; ++ struct stat dev_map_stat; + + if (path == NULL) + { +@@ -136,6 +138,22 @@ + goto end; + } + ++ if (stat (dev_map, &dev_map_stat) == -1 && ++ grub_util_get_dev_abstraction (device_name) != GRUB_DEV_ABSTRACTION_NONE) ++ { ++ /* If we don't have a device map, then we won't yet know about the ++ physical volumes underlying this device, so probe all devices. */ ++ grub_util_iterate_devices (grub_util_biosdisk_probe_device, 0); ++ ++ /* Now reinitialise the higher layers. */ ++ grub_lvm_fini (); ++ grub_mdraid_fini (); ++ grub_raid_fini (); ++ grub_raid_init (); ++ grub_mdraid_init (); ++ grub_lvm_init (); ++ } ++ + drive_name = grub_util_get_grub_dev (device_name); + if (! drive_name) + grub_util_error ("cannot find a GRUB drive for %s. Check your device.map", device_name); +@@ -428,9 +446,9 @@ + + /* Do it. */ + if (argument_is_device) +- probe (NULL, argument); ++ probe (NULL, argument, dev_map ? : DEFAULT_DEVICE_MAP); + else +- probe (argument, NULL); ++ probe (argument, NULL, dev_map ? : DEFAULT_DEVICE_MAP); + + /* Free resources. */ + grub_fini_all (); +diff -Nur -x '*.orig' -x '*~' grub2/util/hostdisk.c grub2.new/util/hostdisk.c +--- grub2/util/hostdisk.c 2010-03-22 13:49:14.000000000 +0000 ++++ grub2.new/util/hostdisk.c 2010-03-22 13:51:53.000000000 +0000 +@@ -1237,6 +1237,48 @@ + return i; + } + ++static void ++store_grub_dev (const char *grub_disk, const char *os_disk) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE (map); i++) ++ if (! map[i].device) ++ break; ++ else if (strcmp (map[i].drive, grub_disk) == 0) ++ { ++ if (strcmp (map[i].device, os_disk) == 0) ++ return; ++ grub_util_error (_("drive `%s' already mapped to `%s'"), ++ map[i].drive, map[i].device); ++ } ++ ++ if (i == ARRAY_SIZE (map)) ++ grub_util_error (_("device count exceeds limit")); ++ ++ map[i].drive = xstrdup (grub_disk); ++ map[i].device = xstrdup (os_disk); ++} ++ ++static int num_hd = 0; ++static int num_fd = 0; ++ ++int ++grub_util_biosdisk_probe_device (const char *name, int is_floppy) ++{ ++ char *grub_disk; ++ ++ if (is_floppy) ++ grub_disk = xasprintf ("fd%d", num_fd++); ++ else ++ grub_disk = xasprintf ("hd%d", num_hd++); ++ ++ store_grub_dev (grub_disk, name); ++ free (grub_disk); ++ ++ return 0; ++} ++ + char * + grub_util_biosdisk_get_grub_dev (const char *os_dev) + { +diff -Nur -x '*.orig' -x '*~' grub2/util/i386/pc/grub-setup.c grub2.new/util/i386/pc/grub-setup.c +--- grub2/util/i386/pc/grub-setup.c 2010-03-22 13:49:13.000000000 +0000 ++++ grub2.new/util/i386/pc/grub-setup.c 2010-03-22 13:53:10.000000000 +0000 +@@ -36,6 +36,7 @@ + #include <grub/util/raid.h> + #include <grub/util/lvm.h> + #include <grub/util/getroot.h> ++#include <grub/util/deviceiter.h> + + static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; + +@@ -646,6 +647,7 @@ + char *core_file = 0; + char *dir = 0; + char *dev_map = 0; ++ struct stat dev_map_stat; + char *root_dev = 0; + char *dest_dev; + int must_embed = 0, force = 0, fs_probe = 1; +@@ -744,6 +746,9 @@ + /* Initialize the emulated biosdisk driver. */ + grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP); + ++ if (stat (dev_map ? : DEFAULT_DEVICE_MAP, &dev_map_stat) == -1) ++ grub_util_iterate_devices (grub_util_biosdisk_probe_device, 0); ++ + /* Initialize all modules. */ + grub_init_all (); + +diff -Nur -x '*.orig' -x '*~' grub2/util/sparc64/ieee1275/grub-setup.c grub2.new/util/sparc64/ieee1275/grub-setup.c +--- grub2/util/sparc64/ieee1275/grub-setup.c 2010-03-22 13:47:27.000000000 +0000 ++++ grub2.new/util/sparc64/ieee1275/grub-setup.c 2010-03-22 13:53:10.000000000 +0000 +@@ -46,6 +46,7 @@ + #include <sys/stat.h> + #include <dirent.h> + #include <grub/util/getroot.h> ++#include <grub/util/deviceiter.h> + + #define _GNU_SOURCE 1 + #include <getopt.h> +@@ -618,6 +619,7 @@ + main (int argc, char *argv[]) + { + struct grub_setup_info ginfo; ++ struct stat dev_map_stat; + + set_program_name (argv[0]); + +@@ -630,6 +632,9 @@ + /* Initialize the emulated biosdisk driver. */ + grub_util_biosdisk_init (ginfo.dev_map ? ginfo.dev_map : DEFAULT_DEVICE_MAP); + ++ if (stat (ginfo.dev_map ? : DEFAULT_DEVICE_MAP, &dev_map_stat) == -1) ++ grub_util_iterate_devices (grub_util_biosdisk_probe_device, 0); ++ + /* Initialize all modules. */ + grub_init_all (); + diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/970_fix_locale_installation.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/970_fix_locale_installation.diff new file mode 100644 index 0000000..ab20288 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/970_fix_locale_installation.diff @@ -0,0 +1,55 @@ +Description: Copy .mo files from @datadir@/locale + This matches where 'make install' puts them. +Origin: upstream, http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/2265 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/537998 +Forwarded: http://lists.gnu.org/archive/html/grub-devel/2010-03/msg00074.html +Last-Update: 2010-03-22 + +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-install.in grub2.new/util/grub-install.in +--- grub2/util/grub-install.in 2010-03-22 15:49:32.000000000 +0000 ++++ grub2.new/util/grub-install.in 2010-03-22 15:54:31.000000000 +0000 +@@ -32,6 +32,7 @@ + host_os=@host_os@ + font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 + pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` ++localedir=@datadir@/locale + + grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` + if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then +@@ -245,9 +246,9 @@ + + # Copy gettext files + mkdir -p ${grubdir}/locale/ +-for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do +- if test -f "$file"; then +- cp -f "$file" ${grubdir}/locale/ ++for dir in ${localedir}/*; do ++ if test -f "$dir/LC_MESSAGES/grub.mo"; then ++ cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" + fi + done + +diff -Nur -x '*.orig' -x '*~' grub2/util/i386/efi/grub-install.in grub2.new/util/i386/efi/grub-install.in +--- grub2/util/i386/efi/grub-install.in 2010-03-09 16:14:00.000000000 +0000 ++++ grub2.new/util/i386/efi/grub-install.in 2010-03-22 15:54:31.000000000 +0000 +@@ -31,6 +31,7 @@ + platform=@platform@ + host_os=@host_os@ + pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` ++localedir=@datadir@/locale + + grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` + grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` +@@ -182,9 +183,9 @@ + + # Copy gettext files + mkdir -p ${grubdir}/locale/ +-for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do +- if test -f "$file"; then +- cp -f "$file" ${grubdir}/locale/ ++for dir in ${localedir}/*; do ++ if test -f "$dir/LC_MESSAGES/grub.mo"; then ++ cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" + fi + done + diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/971_langpacks.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/971_langpacks.diff new file mode 100644 index 0000000..7e1cb89 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/971_langpacks.diff @@ -0,0 +1,30 @@ +Description: Prefer translations from language packs +Author: Colin Watson <cjwatson@ubuntu.com> +Bug-Ubuntu: https://bugs.launchpad.net/bugs/537998 +Forwarded: not-needed +Last-Update: 2010-03-22 + +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-install.in grub2.new/util/grub-install.in +--- grub2/util/grub-install.in 2010-03-22 15:58:16.000000000 +0000 ++++ grub2.new/util/grub-install.in 2010-03-22 15:59:04.000000000 +0000 +@@ -246,7 +246,7 @@ + + # Copy gettext files + mkdir -p ${grubdir}/locale/ +-for dir in ${localedir}/*; do ++for dir in ${localedir}/* ${localedir}-langpack/*; do + if test -f "$dir/LC_MESSAGES/grub.mo"; then + cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" + fi +diff -Nur -x '*.orig' -x '*~' grub2/util/i386/efi/grub-install.in grub2.new/util/i386/efi/grub-install.in +--- grub2/util/i386/efi/grub-install.in 2010-03-22 15:58:16.000000000 +0000 ++++ grub2.new/util/i386/efi/grub-install.in 2010-03-22 15:59:17.000000000 +0000 +@@ -183,7 +183,7 @@ + + # Copy gettext files + mkdir -p ${grubdir}/locale/ +-for dir in ${localedir}/*; do ++for dir in ${localedir}/* ${localedir}-langpack/*; do + if test -f "$dir/LC_MESSAGES/grub.mo"; then + cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" + fi diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/974_drive_probe.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/974_drive_probe.diff new file mode 100644 index 0000000..0c9f364 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/974_drive_probe.diff @@ -0,0 +1,23 @@ +Description: Probe all devices if we've been asked for a drive name + This allows --target=drive to work properly even without a device.map. + . + Depends on 969_lvm_raid_probe.diff. +Author: Colin Watson <cjwatson@ubuntu.com> +Bug-Ubuntu: https://bugs.launchpad.net/bugs/549980 +Forwarded: no +Last-Update: 2010-04-08 + +diff -Nur -x '*.orig' -x '*~' grub2/util/grub-probe.c grub2.new/util/grub-probe.c +--- grub2/util/grub-probe.c 2010-04-08 12:02:36.000000000 +0100 ++++ grub2.new/util/grub-probe.c 2010-04-08 12:04:05.000000000 +0100 +@@ -139,7 +139,9 @@ + } + + if (stat (dev_map, &dev_map_stat) == -1 && +- grub_util_get_dev_abstraction (device_name) != GRUB_DEV_ABSTRACTION_NONE) ++ (print == PRINT_DRIVE || ++ grub_util_get_dev_abstraction (device_name) != ++ GRUB_DEV_ABSTRACTION_NONE)) + { + /* If we don't have a device map, then we won't yet know about the + physical volumes underlying this device, so probe all devices. */ diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/975_hostdisk_hd.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/975_hostdisk_hd.diff new file mode 100644 index 0000000..7ea7f5f --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream-1.98/975_hostdisk_hd.diff @@ -0,0 +1,114 @@ +Description: Adjust hostdisk id for hard disks + This allows grub-setup to use its standard workaround for broken BIOSes. +Author: Colin Watson <cjwatson@ubuntu.com> +Bug: http://savannah.gnu.org/bugs/?29464 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/555500 +Forwarded: http://savannah.gnu.org/bugs/?29464 +Last-Update: 2010-04-08 + +diff -Nur -x '*.orig' -x '*~' grub2/util/hostdisk.c grub2.new/util/hostdisk.c +--- grub2/util/hostdisk.c 2010-04-08 17:09:02.000000000 +0100 ++++ grub2.new/util/hostdisk.c 2010-04-08 17:10:18.000000000 +0100 +@@ -186,6 +186,8 @@ + + disk->has_partitions = 1; + disk->id = drive; ++ if (strncmp (map[drive].drive, "hd", 2) == 0) ++ disk->id += 0x80; + disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data)); + data->dev = NULL; + data->access_mode = 0; +@@ -491,9 +493,9 @@ + int is_partition = 0; + char dev[PATH_MAX]; + +- strcpy (dev, map[disk->id].device); ++ strcpy (dev, map[disk->id & 0x7f].device); + if (disk->partition && sector >= disk->partition->start +- && strncmp (map[disk->id].device, "/dev/", 5) == 0) ++ && strncmp (map[disk->id & 0x7f].device, "/dev/", 5) == 0) + is_partition = linux_find_partition (dev, disk->partition->start); + + if (data->dev && strcmp (data->dev, dev) == 0 && +@@ -548,7 +550,7 @@ + } + #endif + +- if (data->dev && strcmp (data->dev, map[disk->id].device) == 0 && ++ if (data->dev && strcmp (data->dev, map[disk->id & 0x7f].device) == 0 && + data->access_mode == (flags & O_ACCMODE)) + { + grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev); +@@ -560,10 +562,10 @@ + if (data->fd != -1) + close (data->fd); + +- fd = open (map[disk->id].device, flags); ++ fd = open (map[disk->id & 0x7f].device, flags); + if (fd >= 0) + { +- data->dev = xstrdup (map[disk->id].device); ++ data->dev = xstrdup (map[disk->id & 0x7f].device); + data->access_mode = (flags & O_ACCMODE); + data->fd = fd; + } +@@ -581,12 +583,12 @@ + #if defined(__APPLE__) + /* If we can't have exclusive access, try shared access */ + if (fd < 0) +- fd = open(map[disk->id].device, flags | O_SHLOCK); ++ fd = open(map[disk->id & 0x7f].device, flags | O_SHLOCK); + #endif + + if (fd < 0) + { +- grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' in open_device()", map[disk->id].device); ++ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' in open_device()", map[disk->id & 0x7f].device); + return -1; + } + #endif /* ! __linux__ */ +@@ -604,7 +606,7 @@ + offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS; + if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) + { +- grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); ++ grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id & 0x7f].device); + close (fd); + return -1; + } +@@ -615,7 +617,7 @@ + + if (lseek (fd, offset, SEEK_SET) != offset) + { +- grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); ++ grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id & 0x7f].device); + close (fd); + return -1; + } +@@ -713,7 +715,7 @@ + parts. -jochen */ + if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) + { +- grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device); ++ grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id & 0x7f].device); + close (fd); + return grub_errno; + } +@@ -725,7 +727,7 @@ + + if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS) + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) +- grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device); ++ grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id & 0x7f].device); + + return grub_errno; + } +@@ -759,7 +761,7 @@ + + if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS) + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) +- grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device); ++ grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id & 0x7f].device); + + return grub_errno; + } diff --git a/sys-boot/grub/files/ubuntu-upstream/01_uuids_and_lvm_dont_play_along_nicely.diff b/sys-boot/grub/files/ubuntu-upstream/01_uuids_and_lvm_dont_play_along_nicely.diff new file mode 100644 index 0000000..c997b84 --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream/01_uuids_and_lvm_dont_play_along_nicely.diff @@ -0,0 +1,14 @@ +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index c2da413..cbd9d6b 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -36,7 +36,8 @@ case ${GRUB_DEVICE} in + esac + + if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ +- || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then ++ || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ ++ || [ "`grub-probe -t abstraction --device ${GRUB_DEVICE} | sed -e 's,.*\(lvm\).*,\1,'`" = "lvm" ] ; then + LINUX_ROOT_DEVICE=${GRUB_DEVICE} + else + LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} diff --git a/sys-boot/grub/files/ubuntu-upstream/904_disable_floppies.diff b/sys-boot/grub/files/ubuntu-upstream/904_disable_floppies.diff new file mode 100644 index 0000000..66a41cd --- /dev/null +++ b/sys-boot/grub/files/ubuntu-upstream/904_disable_floppies.diff @@ -0,0 +1,28 @@ + +Author: Robert Millan + +An ugly kludge. Should this be merged upstream? + +Index: util/hostdisk.c +=================================================================== +--- util/hostdisk.c (revision 1832) ++++ util/hostdisk.c (working copy) +@@ -544,6 +544,18 @@ + continue; + } + ++ if (! strncmp (p, "/dev/fd", sizeof ("/dev/fd") - 1)) ++ { ++ char *q = p + sizeof ("/dev/fd") - 1; ++ if (*q >= '0' && *q <= '9') ++ { ++ free (map[drive].drive); ++ map[drive].drive = NULL; ++ grub_util_info ("`%s' looks like a floppy drive, skipping", p); ++ continue; ++ } ++ } ++ + #ifdef __linux__ + /* On Linux, the devfs uses symbolic links horribly, and that + confuses the interface very much, so use realpath to expand diff --git a/sys-boot/grub/grub-0.97-r22.ebuild b/sys-boot/grub/grub-0.97-r22.ebuild new file mode 100644 index 0000000..0be60db --- /dev/null +++ b/sys-boot/grub/grub-0.97-r22.ebuild @@ -0,0 +1,240 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-0.97-r9.ebuild,v 1.4 2009/05/15 21:11:24 maekke Exp $ + +# XXX: we need to review menu.lst vs grub.conf handling. We've been converting +# all systems to grub.conf (and symlinking menu.lst to grub.conf), but +# we never updated any of the source code (it still all wants menu.lst), +# and there is no indication that upstream is making the transition. + +inherit mount-boot eutils flag-o-matic toolchain-funcs autotools multilib + +PATCHVER="1.9" # Should match the revision ideally +DESCRIPTION="GNU GRUB Legacy boot loader" +HOMEPAGE="http://www.gnu.org/software/grub/" +SRC_URI="mirror://gentoo/${P}.tar.gz + ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz + mirror://gentoo/${P}-patches-${PATCHVER}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="amd64 x86 ~x86-fbsd" +IUSE="custom-cflags ncurses netboot static" + +DEPEND="ncurses? ( + >=sys-libs/ncurses-5.2-r5 + amd64? ( app-emulation/emul-linux-x86-baselibs ) + )" +PROVIDE="virtual/bootloader" + +src_unpack() { + unpack ${A} + cd "${S}" + + # patch breaks booting for some people #111885 + rm "${WORKDIR}"/patch/400_* + + # Grub will not handle a kernel larger than EXTENDED_MEMSIZE Mb as + # discovered in bug 160801. We can change this, however, using larger values + # for this variable means that Grub needs more memory to run and boot. For a + # kernel of size N, Grub needs (N+1)*2. Advanced users should set a custom + # value in make.conf, it is possible to make kernels ~16Mb in size, but it + # needs the kitchen sink built-in. + local t="custom" + if [[ -z ${GRUB_MAX_KERNEL_SIZE} ]] ; then + case $(tc-arch) in + amd64) GRUB_MAX_KERNEL_SIZE=7 ;; + x86) GRUB_MAX_KERNEL_SIZE=3 ;; + esac + t="default" + fi + einfo "Grub will support the ${t} maximum kernel size of ${GRUB_MAX_KERNEL_SIZE} Mb (GRUB_MAX_KERNEL_SIZE)" + + sed -i \ + -e "/^#define.*EXTENDED_MEMSIZE/s,3,${GRUB_MAX_KERNEL_SIZE},g" \ + "${S}"/grub/asmstub.c \ + || die "Failed to hack memory size" + + # UUID support + epatch "${FILESDIR}/${P}-uuid.patch" + epatch "${FILESDIR}/${P}-uuid_doc.patch" + # Gfxmenu support + epatch "${FILESDIR}/${P}-gfxmenu-v8.patch" + + if [[ -n ${PATCHVER} ]] ; then + EPATCH_SUFFIX="patch" + epatch "${WORKDIR}"/patch + eautoreconf + fi +} + +src_compile() { + filter-flags -fPIE #168834 + + # Fix libvolume_id build (UUID) + export CPPFLAGS="${CPPFLAGS} -I/usr/include -I/usr/$(get_libdir)/gcc/${CHOST}/$(gcc-fullversion)/include" + + use amd64 && multilib_toolchain_setup x86 + + unset BLOCK_SIZE #73499 + + ### i686-specific code in the boot loader is a bad idea; disabling to ensure + ### at least some compatibility if the hard drive is moved to an older or + ### incompatible system. + + # grub-0.95 added -fno-stack-protector detection, to disable ssp for stage2, + # but the objcopy's (faulty) test fails if -fstack-protector is default. + # create a cache telling configure that objcopy is ok, and add -C to econf + # to make use of the cache. + # + # CFLAGS has to be undefined running econf, else -fno-stack-protector detection fails. + # STAGE2_CFLAGS is not allowed to be used on emake command-line, it overwrites + # -fno-stack-protector detected by configure, removed from netboot's emake. + use custom-cflags || unset CFLAGS + + export grub_cv_prog_objcopy_absolute=yes #79734 + use static && append-ldflags -static + + # Per bug 216625, the emul packages do not provide .a libs for performing + # suitable static linking + if use amd64 && use static ; then + if [ -z "${GRUB_STATIC_PACKAGE_BUILDING}" ]; then + die "You must use the grub-static package if you want a static Grub on amd64!" + else + eerror "You have set GRUB_STATIC_PACKAGE_BUILDING. This" + eerror "is specifically intended for building the tarballs for the" + eerror "grub-static package via USE='static -ncurses'." + eerror "All bets are now off." + ebeep 10 + fi + fi + + # build the net-bootable grub first, but only if "netboot" is set + if use netboot ; then + econf \ + --libdir=/lib \ + --datadir=/usr/lib/grub \ + --exec-prefix=/ \ + --disable-auto-linux-mem-opt \ + --enable-diskless \ + --enable-{3c{5{03,07,09,29,95},90x},cs89x0,davicom,depca,eepro{,100}} \ + --enable-{epic100,exos205,ni5210,lance,ne2100,ni{50,65}10,natsemi} \ + --enable-{ne,ns8390,wd,otulip,rtl8139,sis900,sk-g16,smc9000,tiara} \ + --enable-{tulip,via-rhine,w89c840} || die "netboot econf failed" + + emake w89c840_o_CFLAGS="-O" || die "making netboot stuff" + + mv -f stage2/{nbgrub,pxegrub} "${S}"/ + mv -f stage2/stage2 stage2/stage2.netboot + + make clean || die "make clean failed" + fi + + # Now build the regular grub + # Note that FFS and UFS2 support are broken for now - stage1_5 files too big + econf \ + --libdir=/lib \ + --datadir=/usr/lib/grub \ + --exec-prefix=/ \ + --disable-auto-linux-mem-opt \ + $(use_with ncurses curses) \ + || die "econf failed" + + # sanity check due to common failure + use ncurses && ! grep -qs "HAVE_LIBCURSES.*1" config.h && die "USE=ncurses but curses not found" + + emake || die "making regular stuff" +} + +src_test() { + # non-default block size also give false pass/fails. + unset BLOCK_SIZE + make check || die "make check failed" +} + +src_install() { + emake DESTDIR="${D}" install || die + if use netboot ; then + exeinto /usr/lib/grub/${CHOST} + doexe nbgrub pxegrub stage2/stage2.netboot || die "netboot install" + fi + + dodoc AUTHORS BUGS ChangeLog NEWS README THANKS TODO + newdoc docs/menu.lst grub.conf.sample + dodoc "${FILESDIR}"/grub.conf.gentoo + prepalldocs + + [ -n "${GRUB_STATIC_PACKAGE_BUILDING}" ] && \ + mv \ + "${D}"/usr/share/doc/${PF} \ + "${D}"/usr/share/doc/grub-static-${PF/grub-} + + insinto /usr/share/grub + doins "${FILESDIR}"/splash.xpm.gz + +} + +setup_boot_dir() { + local boot_dir=$1 + local dir=${boot_dir} + + mkdir -p "${dir}" + [[ ! -L ${dir}/boot ]] && ln -s . "${dir}/boot" + dir="${dir}/grub" + if [[ ! -e ${dir} ]] ; then + mkdir "${dir}" || die "${dir} does not exist!" + fi + + # change menu.lst to grub.conf + if [[ ! -e ${dir}/grub.conf ]] && [[ -e ${dir}/menu.lst ]] ; then + mv -f "${dir}"/menu.lst "${dir}"/grub.conf + ewarn + ewarn "*** IMPORTANT NOTE: menu.lst has been renamed to grub.conf" + ewarn + fi + + if [[ ! -e ${dir}/menu.lst ]]; then + einfo "Linking from new grub.conf name to menu.lst" + ln -snf grub.conf "${dir}"/menu.lst + fi + + if [[ ! -e ${dir}/grub.conf ]] ; then + s="${ROOT}/usr/share/doc/${PF}/grub.conf.gentoo" + [[ -e "${s}" ]] && cat "${s}" >${dir}/grub.conf + [[ -e "${s}.gz" ]] && zcat "${s}.gz" >${dir}/grub.conf + [[ -e "${s}.bz2" ]] && bzcat "${s}.bz2" >${dir}/grub.conf + fi + + einfo "Grub has been installed to ${boot_dir} successfully." +} + +pkg_postinst() { + if [[ -n ${DONT_MOUNT_BOOT} ]]; then + elog "WARNING: you have DONT_MOUNT_BOOT in effect, so you must apply" + elog "the following instructions for your /boot!" + elog "Neglecting to do so may cause your system to fail to boot!" + elog + else + setup_boot_dir "${ROOT}"/boot + # Trailing output because if this is run from pkg_postinst, it gets mixed into + # the other output. + einfo "" + fi + elog "To interactively install grub files to another device such as a USB" + elog "stick, just run the following and specify the directory as prompted:" + elog " emerge --config =${PF}" + elog "Alternately, you can export GRUB_ALT_INSTALLDIR=/path/to/use to tell" + elog "grub where to install in a non-interactive way." + +} + +pkg_config() { + local dir + if [ ! -d "${GRUB_ALT_INSTALLDIR}" ]; then + einfo "Enter the directory where you want to setup grub:" + read dir + else + dir="${GRUB_ALT_INSTALLDIR}" + fi + setup_boot_dir "${dir}" +} diff --git a/sys-boot/grub/grub-1.98-r10.ebuild b/sys-boot/grub/grub-1.98-r10.ebuild new file mode 100644 index 0000000..bc0710a --- /dev/null +++ b/sys-boot/grub/grub-1.98-r10.ebuild @@ -0,0 +1,141 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-1.98.ebuild,v 1.1 2010/03/10 19:47:34 vapier Exp $ + +inherit mount-boot eutils flag-o-matic toolchain-funcs + +if [[ ${PV} == "9999" ]] ; then + EBZR_REPO_URI="http://bzr.savannah.gnu.org/r/grub/trunk/grub" + inherit autotools bzr + SRC_URI="" +else + SRC_URI="ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz + mirror://gentoo/${P}.tar.gz" +fi + +DESCRIPTION="GNU GRUB 2 boot loader" +HOMEPAGE="http://www.gnu.org/software/grub/" + +LICENSE="GPL-3" +use multislot && SLOT="2" || SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="custom-cflags truetype multislot static" + +RDEPEND=">=sys-libs/ncurses-5.2-r5 + dev-libs/lzo + truetype? ( + media-libs/freetype + media-fonts/unifont + )" +DEPEND="${RDEPEND} + dev-lang/ruby" +PDEPEND="${PDEPEND} + sys-boot/os-prober" +PROVIDE="virtual/bootloader" + +export STRIP_MASK="*/grub/*/*.mod" +QA_EXECSTACK="sbin/grub-probe sbin/grub-setup sbin/grub-mkdevicemap" + +src_unpack() { + if [[ ${PV} == "9999" ]] ; then + bzr_src_unpack + else + unpack ${A} + fi + cd "${S}" + epatch "${FILESDIR}"/${PN}-1.98-genkernel.patch + epatch "${FILESDIR}"/${PN}-1.97-vga-deprecated.patch + epatch "${FILESDIR}"/${PN}-1.98-wallpaper-settings-support.patch + # see Gentoo #302634 + epatch "${FILESDIR}"/${PN}-1.98-add-legacy-rootfs-detection.patch + + # Ubuntu and upstream patches + epatch "${FILESDIR}"/ubuntu-upstream-${PV}/*.diff + + epatch_user + + # see Gentoo #321569 + epatch "${FILESDIR}"/${PN}-1.98-follow-dev-mapper-symlinks.patch + + # Genkernel doesn't support "single" for rescue mode + # but rather init_opts=single + epatch "${FILESDIR}"/${PN}-1.98-genkernel-initramfs-single.patch + + # autogen.sh does more than just run autotools + # need to eautomake due to weirdness #296013 + if [[ ${PV} == "9999" ]] ; then + sed -i \ + -e '/^\(auto\|ac\)/s:^:e:' \ + -e "s:^eautomake:`which automake`:" \ + autogen.sh + (. ./autogen.sh) || die + fi +} + +src_compile() { + use custom-cflags || unset CFLAGS CPPFLAGS LDFLAGS + use static && append-ldflags -static + + econf \ + --disable-werror \ + --sbindir=/sbin \ + --bindir=/bin \ + --libdir=/$(get_libdir) \ + --disable-efiemu \ + $(use_enable truetype grub-mkfont) + emake -j1 || die "making regular stuff" +} + +src_install() { + emake DESTDIR="${D}" install || die + dodoc AUTHORS ChangeLog NEWS README THANKS TODO + if use multislot ; then + sed -i "s:grub-install:grub2-install:" "${D}"/sbin/grub-install || die + mv "${D}"/sbin/grub{,2}-install || die + mv "${D}"/sbin/grub{,2}-set-default || die + mv "${D}"/usr/share/info/grub{,2}.info || die + fi + + # install /etc/default/grub + cp "${FILESDIR}/grub2-default" grub + dodir /etc/default + insinto /etc/default + doins grub + + # Install fonts setup hook + exeinto /etc/grub.d + doexe "${FILESDIR}/00_fonts" + doexe "${FILESDIR}/05_distro_theme" + + dodir /boot/grub + insinto /boot/grub + newins "${FILESDIR}/default-splash-6.png" default-splash.png + # keep backward compat + dodir /usr/share/grub + insinto /usr/share/grub + newins "${FILESDIR}/default-splash-6.png" default-splash.png + +} + +setup_boot_dir() { + local boot_dir=$1 + local dir=${boot_dir}/grub + + if [[ ! -e ${dir}/grub.cfg ]] ; then + einfo "Running: grub-mkconfig -o '${dir}/grub.cfg'" + grub-mkconfig -o "${dir}/grub.cfg" + fi + + #local install=grub-install + #use multislot && install="grub2-install --grub-setup=/bin/true" + #einfo "Running: ${install} " + #${install} +} + +pkg_postinst() { + if use multislot ; then + elog "You have installed grub2 with USE=multislot, so to coexist" + elog "with grub1, the grub2 install binary is named grub2-install." + fi + setup_boot_dir "${ROOT}"boot +} diff --git a/sys-boot/grub/grub-1.98-r9.ebuild b/sys-boot/grub/grub-1.98-r9.ebuild new file mode 100644 index 0000000..43a8bf4 --- /dev/null +++ b/sys-boot/grub/grub-1.98-r9.ebuild @@ -0,0 +1,145 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-1.98.ebuild,v 1.1 2010/03/10 19:47:34 vapier Exp $ + +inherit mount-boot eutils flag-o-matic toolchain-funcs + +if [[ ${PV} == "9999" ]] ; then + EBZR_REPO_URI="http://bzr.savannah.gnu.org/r/grub/trunk/grub" + inherit autotools bzr + SRC_URI="" +else + SRC_URI="ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz + mirror://gentoo/${P}.tar.gz" +fi + +DESCRIPTION="GNU GRUB 2 boot loader" +HOMEPAGE="http://www.gnu.org/software/grub/" + +LICENSE="GPL-3" +use multislot && SLOT="2" || SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="custom-cflags debug truetype multislot static" + +RDEPEND=">=sys-libs/ncurses-5.2-r5 + dev-libs/lzo + truetype? ( + media-libs/freetype + media-fonts/unifont + )" +DEPEND="${RDEPEND} + dev-lang/ruby" +PDEPEND="${PDEPEND} + sys-boot/os-prober" +PROVIDE="virtual/bootloader" + +export STRIP_MASK="*/grub/*/*.mod" +QA_EXECSTACK="sbin/grub-probe sbin/grub-setup sbin/grub-mkdevicemap" + +src_unpack() { + if [[ ${PV} == "9999" ]] ; then + bzr_src_unpack + else + unpack ${A} + fi + cd "${S}" + epatch "${FILESDIR}"/${PN}-1.98-genkernel.patch + epatch "${FILESDIR}"/${PN}-1.97-vga-deprecated.patch + epatch "${FILESDIR}"/${PN}-1.98-wallpaper-settings-support.patch + # see Gentoo #302634 + epatch "${FILESDIR}"/${PN}-1.98-add-legacy-rootfs-detection.patch + + # Ubuntu and upstream patches + epatch "${FILESDIR}"/ubuntu-upstream-${PV}/*.diff + + epatch_user + + # see Gentoo #321569 + epatch "${FILESDIR}"/${PN}-1.98-follow-dev-mapper-symlinks.patch + + # Genkernel doesn't support "single" for rescue mode + # but rather init_opts=single + epatch "${FILESDIR}"/${PN}-1.98-genkernel-initramfs-single.patch + + # autogen.sh does more than just run autotools + # need to eautomake due to weirdness #296013 + if [[ ${PV} == "9999" ]] ; then + sed -i \ + -e '/^\(auto\|ac\)/s:^:e:' \ + -e "s:^eautomake:`which automake`:" \ + autogen.sh + (. ./autogen.sh) || die + fi +} + +src_compile() { + use custom-cflags || unset CFLAGS CPPFLAGS LDFLAGS + use static && append-ldflags -static + + econf \ + --disable-werror \ + --sbindir=/sbin \ + --bindir=/bin \ + --libdir=/$(get_libdir) \ + --disable-efiemu \ + $(use_enable truetype grub-mkfont) \ + $(use_enable debug mm-debug) \ + $(use_enable debug grub-emu) \ + $(use_enable debug grub-emu-usb) \ + $(use_enable debug grub-fstest) + emake -j1 || die "making regular stuff" +} + +src_install() { + emake DESTDIR="${D}" install || die + dodoc AUTHORS ChangeLog NEWS README THANKS TODO + if use multislot ; then + sed -i "s:grub-install:grub2-install:" "${D}"/sbin/grub-install || die + mv "${D}"/sbin/grub{,2}-install || die + mv "${D}"/sbin/grub{,2}-set-default || die + mv "${D}"/usr/share/info/grub{,2}.info || die + fi + + # install /etc/default/grub + cp "${FILESDIR}/grub2-default" grub + dodir /etc/default + insinto /etc/default + doins grub + + # Install fonts setup hook + exeinto /etc/grub.d + doexe "${FILESDIR}/00_fonts" + doexe "${FILESDIR}/05_distro_theme" + + dodir /boot/grub + insinto /boot/grub + newins "${FILESDIR}/default-splash-6.png" default-splash.png + # keep backward compat + dodir /usr/share/grub + insinto /usr/share/grub + newins "${FILESDIR}/default-splash-6.png" default-splash.png + +} + +setup_boot_dir() { + local boot_dir=$1 + local dir=${boot_dir}/grub + + if [[ ! -e ${dir}/grub.cfg ]] ; then + einfo "Running: grub-mkconfig -o '${dir}/grub.cfg'" + grub-mkconfig -o "${dir}/grub.cfg" + fi + + #local install=grub-install + #use multislot && install="grub2-install --grub-setup=/bin/true" + #einfo "Running: ${install} " + #${install} +} + +pkg_postinst() { + if use multislot ; then + elog "You have installed grub2 with USE=multislot, so to coexist" + elog "with grub1, the grub2 install binary is named grub2-install." + fi + setup_boot_dir "${ROOT}"boot +} diff --git a/sys-boot/grub/grub-1.99.ebuild b/sys-boot/grub/grub-1.99.ebuild new file mode 100644 index 0000000..3ca30a1 --- /dev/null +++ b/sys-boot/grub/grub-1.99.ebuild @@ -0,0 +1,279 @@ +# Copyright 1999-2011 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=4 + +if [[ ${PV} == "9999" ]] ; then + EBZR_REPO_URI="http://bzr.savannah.gnu.org/r/grub/trunk/grub/" + LIVE_ECLASS="autotools bzr" + SRC_URI="" +else + MY_P=${P/_/\~} + SRC_URI="mirror://gnu/${PN}/${MY_P}.tar.xz + mirror://gentoo/${MY_P}.tar.xz" + S=${WORKDIR}/${MY_P} +fi + +inherit mount-boot eutils flag-o-matic toolchain-funcs autotools ${LIVE_ECLASS} +unset LIVE_ECLASS + +DESCRIPTION="GNU GRUB boot loader" +HOMEPAGE="http://www.gnu.org/software/grub/" + +LICENSE="GPL-3" +use multislot && SLOT="2" || SLOT="0" +[[ ${PV} != "9999" ]] && KEYWORDS="~amd64 ~x86 ~mips ~ppc ~ppc64" +IUSE="custom-cflags debug +device-mapper multislot nls static sdl +truetype" + +GRUB_PLATFORMS="coreboot efi-32 efi-64 emu ieee1275 multiboot pc yeeloong" +# everywhere: +# emu +# mips only: +# qemu-mips, yeelong +# amd64, x86, ppc, ppc64 +# ieee1275 +# amd64, x86 +# coreboot, multiboot, efi-32, pc, qemu +# amd64 +# efi-64 +for i in ${GRUB_PLATFORMS}; do + IUSE+=" grub_platforms_${i}" +done +unset i + +# os-prober: Used on runtime to detect other OSes +# xorriso (dev-libs/libisoburn): Used on runtime for mkrescue +RDEPEND=" + dev-libs/libisoburn + dev-libs/lzo + sys-boot/os-prober + >=sys-libs/ncurses-5.2-r5 + debug? ( + sdl? ( media-libs/libsdl ) + ) + device-mapper? ( >=sys-fs/lvm2-2.02.45 ) + truetype? ( media-libs/freetype >=media-fonts/unifont-5 )" +DEPEND="${RDEPEND} + >=dev-lang/python-2.5.2 +" +if [[ ${PV} == "9999" ]]; then + DEPEND+=" >=sys-devel/autogen-5.10 sys-apps/help2man" +else + DEPEND+=" >=sys-devel/autogen-5.10 app-arch/xz-utils" +fi + +export STRIP_MASK="*/grub/*/*.mod" +QA_EXECSTACK=" + sbin/grub-probe + sbin/grub-setup + sbin/grub-mkdevicemap + bin/grub-script-check + bin/grub-fstest +" + +grub_run_phase() { + local phase=$1 + local platform=$2 + [[ -z ${phase} ]] && die "${FUNCNAME}: Phase is undefined" + [[ -z ${platform} ]] && die "${FUNCNAME}: Platform is undefined" + + [[ -d "${WORKDIR}/build-${platform}" ]] || \ + { mkdir "${WORKDIR}/build-${platform}" || die ; } + pushd "${WORKDIR}/build-${platform}" > /dev/null || die + + echo ">>> Running ${phase} for platform \"${platform}\"" + echo ">>> Working in: \"${WORKDIR}/build-${platform}\"" + + grub_${phase} ${platform} + + popd > /dev/null || die +} + +grub_src_configure() { + local platform=$1 + local target + + [[ -z ${platform} ]] && die "${FUNCNAME}: Platform is undefined" + + # if we have no platform then --with-platform=guessed does not work + [[ ${platform} == "guessed" ]] && platform="" + + # check if we have to specify the target (EFI) + # or just append correct --with-platform + if [[ -n ${platform} ]]; then + if [[ ${platform/-*} == ${platform} ]]; then + platform=" --with-platform=${platform}" + else + # EFI platform hack + [[ ${platform/*-} == 32 ]] && target=i386 + [[ ${platform/*-} == 64 ]] && target=x86_64 + # program-prefix is required empty because otherwise it is equal to + # target variable, which we do not want at all + platform=" + --with-platform=${platform/-*} + --target=${target} + --program-prefix= + " + fi + fi + + ECONF_SOURCE="${WORKDIR}/${P}/" \ + econf \ + --disable-werror \ + --sbindir=/sbin \ + --bindir=/bin \ + --libdir=/$(get_libdir) \ + --disable-efiemu \ + $(use_enable device-mapper) \ + $(use_enable truetype grub-mkfont) \ + $(use_enable nls) \ + $(use_enable debug mm-debug) \ + $(use sdl && use_enable debug grub-emu-sdl) \ + $(use_enable debug grub-emu-usb) \ + ${platform} +} + +grub_src_compile() { + default_src_compile +} + +grub_src_install() { + default_src_install +} + +src_prepare() { + local i j archs + + epatch "${FILESDIR}"/${PN}-1.99-genkernel.patch #256335 + epatch "${FILESDIR}"/${PN}-1.99-vga-deprecated.patch + epatch "${FILESDIR}"/${PN}-1.99-wallpaper-settings-support.patch + # This happens with md raid metadata 0.90. Due to limitations of the format + epatch "${FILESDIR}"/${PN}-1.99-workaround-raid-bios-bug.patch + # vga= not yet deprecated for us + epatch "${FILESDIR}"/${PN}-1.99-vga-deprecated-not-yet.patch + epatch "${FILESDIR}"/${PN}-1.99-disable-floppies.patch + epatch_user + # Genkernel doesn't support "single" for rescue mode + # but rather init_opts=single + epatch "${FILESDIR}"/${PN}-1.98-genkernel-initramfs-single.patch + + sed -i -e '/^autoreconf/ d' autogen.sh || die + (. ./autogen.sh) || die + eautoreconf + + # get enabled platforms + GRUB_ENABLED_PLATFORMS="" + for i in ${GRUB_PLATFORMS}; do + use grub_platforms_${i} && GRUB_ENABLED_PLATFORMS+=" ${i}" + done + [[ -z ${GRUB_ENABLED_PLATFORMS} ]] && GRUB_ENABLED_PLATFORMS="guessed" + einfo "Going to build following platforms: ${GRUB_ENABLED_PLATFORMS}" +} + +src_configure() { + local i + + use custom-cflags || unset CFLAGS CPPFLAGS LDFLAGS + use static && append-ldflags -static + + for i in ${GRUB_ENABLED_PLATFORMS}; do + grub_run_phase ${FUNCNAME} ${i} + done +} + +src_compile() { + local i + + for i in ${GRUB_ENABLED_PLATFORMS}; do + grub_run_phase ${FUNCNAME} ${i} + done +} + +src_install() { + local i + + for i in ${GRUB_ENABLED_PLATFORMS}; do + grub_run_phase ${FUNCNAME} ${i} + done + if use multislot ; then + sed -i "s:grub-install:grub2-install:" "${D}"/sbin/grub-install || die + mv "${D}"/sbin/grub{,2}-install || die + mv "${D}"/sbin/grub{,2}-set-default || die + mv "${D}"/usr/share/info/grub{,2}.info || die + fi + + # can't be in docs array as we use defualt_src_install in different builddir + dodoc AUTHORS ChangeLog NEWS README THANKS TODO + insinto /etc/default + newins "${FILESDIR}"/grub2-default-1.99 grub + cat <<-EOF >> "${D}"/lib*/grub/grub-mkconfig_lib + GRUB_DISTRIBUTOR="Sabayon" +EOF + + # Install fonts setup hook + exeinto /etc/grub.d + doexe "${FILESDIR}/00_fonts" + doexe "${FILESDIR}/05_distro_theme" + + dodir /boot/grub + insinto /boot/grub + newins "${FILESDIR}/default-splash-6.png" default-splash.png + # keep backward compat + dodir /usr/share/grub + insinto /usr/share/grub + newins "${FILESDIR}/default-splash-6.png" default-splash.png + + dodir /etc/env.d + echo 'CONFIG_PROTECT_MASK="/etc/grub.d"' > "${D}/etc/env.d/10grub2" + +} + +setup_boot_dir() { + local dir=$1 + + if [[ ! -e ${dir}/grub.cfg ]]; then + # display the link to guide if user didn't set up anything yet. + elog "For informations how to configure grub-2 please reffer to guide:" + # FIXME: we don't have any guide yet! + # Lets just use archlinux wiki until we have some. + elog " https://wiki.archlinux.org/index.php/GRUB2" + fi + + if [[ ! -e ${dir}/grub.cfg && -e ${dir}/menu.lst ]] ; then + # This is first grub2 install and we have old configuraton for + # grub1 around. Lets try to generate grub.cfg from it so user + # does not loose any stuff when rebooting. + # NOTE: in long term he still NEEDS to migrate to grub.d stuff. + einfo "Running: grub-menulst2cfg '${dir}/menu.lst' '${dir}/grub.cfg'" + grub-menulst2cfg "${dir}/menu.lst" "${dir}/grub.cfg" || \ + ewarn "Running grub-menulst2cfg failed!" + + einfo "Even if we just created configuration for your grub-2 using old" + einfo "grub-1 configuration file you should migrate to use new style" + einfo "configuration in '${ROOT}/etc/grub.d'." + einfo + elog "Remember to run grub-install to install your grub!" + else + # we need to refresh the grub.cfg everytime just to play it safe + einfo "Running: grub-mkconfig -o '${dir}/grub.cfg'" + grub-mkconfig -o "${dir}/grub.cfg" || \ + ewarn "Running grub-mkconfig failed! Check your configuration files!" + fi + + elog "Remember to run \"grub-mkconfig -o '${dir}/grub.cfg'\" every time" + elog "you update the configuration files." +} + +pkg_postinst() { + if use multislot ; then + elog "You have installed grub2 with USE=multislot, so to coexist" + elog "with grub1, the grub2 install binary is named grub2-install." + fi + mount-boot_mount_boot_partition + + setup_boot_dir "${ROOT}"boot/grub + + # needs to be called after we call setup_boot_dir + mount-boot_pkg_postinst +} |