Howdy, Aurelien asked me about getting GRUB 2 working on GNU/kFreeBSD. There's been much work in upstream to implement loading for kernel of FreeBSD, and recently some polish in the installer, etc.
grub-mkconfig (update-grub's backend), however, still generates entries based on the single /boot/kernel/kernel instance. I hear you want it multi-version like on GNU/Linux, and support for loading acpi.ko too. I implemented both of them. It's basically a rewrite of 10_freebsd.in based on our existing 10_linux.in. It'll need some adjustments in upstream so they can share more code, but for now you can test it already, see attachment. (you can put it in util/grub.d/ and rebuild GRUB, or do the autoconf sed magic by hand) -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all."
#! /bin/sh -e # update-grub helper script. # Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. # # GRUB 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, either version 3 of the License, or # (at your option) any later version. # # GRUB is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GRUB. If not, see <http://www.gnu.org/licenses/>. pref...@prefix@ exec_pref...@exec_prefix@ libd...@libdir@ . ${libdir}/grub/grub-mkconfig_lib case "${GRUB_DISTRIBUTOR}" in Debian) OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" ;; *) OS="FreeBSD" ;; esac test_numeric () { local a=$1 local cmp=$2 local b=$3 if [ "$a" = "$b" ] ; then case $cmp in ge|eq|le) return 0 ;; gt|lt) return 1 ;; esac fi if [ "$cmp" = "lt" ] ; then c=$a a=$b b=$c fi if (echo $a ; echo $b) | sort -n | head -n 1 | grep -qx $b ; then return 0 else return 1 fi } test_gt () { local a=`echo $1 | sed -e "s/[^-]*-//g"` local b=`echo $2 | sed -e "s/[^-]*-//g"` local cmp=gt if [ "x$b" = "x" ] ; then return 0 fi case $a:$b in *.old:*.old) ;; *.old:*) a=`echo -n $a | sed -e s/\.old$//g` ; cmp=gt ;; *:*.old) b=`echo -n $b | sed -e s/\.old$//g` ; cmp=ge ;; esac test_numeric $a $cmp $b return $? } find_latest () { local a="" for i in $@ ; do if test_gt "$i" "$a" ; then a="$i" fi done echo "$a" } kfreebsd_entry () { cat << EOF menuentry "$1" { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF freebsd ${rel_dirname}/${basename} EOF if test -n "${devices}" ; then cat << EOF freebsd_loadenv ${devices_rel_dirname}/${devices_basename} EOF fi if test -n "${acpi_ko}" ; then cat << EOF freebsd_module_elf ${acpi_ko_rel_dirname}/${acpi_ko_basename} EOF fi cat << EOF set FreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${GRUB_DEVICE} set FreeBSD.vfs.root.mountfrom.options=rw } EOF } list=`for i in /boot/kfreebsd-* /boot/kernel/kernel ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` while [ "x$list" != "x" ] ; do kfreebsd=`find_latest $list` echo "Found kernel of FreeBSD: $kfreebsd" >&2 basename=`basename $kfreebsd` dirname=`dirname $kfreebsd` rel_dirname=`make_system_path_relative_to_its_root $dirname` if [ x"$devices" != "x" ] ; then devices_basename=`basename $devices` devices_dirname=`dirname $devices` devices_rel_dirname=`make_system_path_relative_to_its_root $devices_dirname` fi # For "ufs" it's the same. Do we care about the others? kfreebsd_fs=${GRUB_FS} version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"` alt_version=`echo $version | sed -e "s,\.old$,,g"` acpi_ko= for i in "/lib/modules/${version}/acpi.ko" "/lib/modules/${alt_version}/acpi.ko" \ "/boot/kernel/acpi.ko"; do if test -e "$i" ; then acpi_ko="$i" break fi done if test -n "${acpi_ko}" ; then echo "Found ACPI module: ${acpi_ko}" >&2 acpi_ko_basename=`basename ${acpi_ko}` acpi_ko_dirname=`dirname ${acpi_ko}` acpi_ko_rel_dirname=`make_system_path_relative_to_its_root $acpi_ko_dirname` fi kfreebsd_entry "${OS}, kFreeBSD ${version}" list=`echo $list | tr ' ' '\n' | grep -vx $kfreebsd | tr '\n' ' '` done

