Solved How to write FreeBSD boot loader into grub.cfg?

Today I have installed two more OS in my PC based on debian10,win10(/dev/sda2) + FreeBSD (/dev/sdb2).
I want to write all win10 + FreeBSD boot loader into grub.cfg.

Code:
debian@debian:~$ sudo os-prober
/dev/sda2@/EFI/Microsoft/Boot/bootmgfw.efi:Windows Boot Manager:Windows:efi
/dev/sdb2:FreeBSD 13.0-RELEASE:FreeBSD:linux

All the os can be detected.
Code:
debian@debian:~$ sudo grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-4.19.0-17-amd64
Found initrd image: /boot/initrd.img-4.19.0-17-amd64
Found linux image: /boot/vmlinuz-4.19.0-16-amd64
Found initrd image: /boot/initrd.img-4.19.0-16-amd64
Found Windows Boot Manager on /dev/sda2@/EFI/Microsoft/Boot/bootmgfw.efi
Found FreeBSD 13.0-RELEASE on /dev/sdb2
Adding boot menu entry for EFI firmware configuration
done

Check if all of them are written into grub.cfg.
Code:
debian@debian:~$ cat  /boot/grub/grub.cfg  |grep  -i  window
menuentry 'Windows Boot Manager (on /dev/sda2)' --class windows --class os $menuentry_id_option 'osprober-efi-4A44-FBE5' {

Win10 is already written into grub.cfg.

Code:
debian@debian:~$ cat  /boot/grub/grub.cfg  |grep  -i  bsd
debian@debian:~$ cat  /boot/grub/grub.cfg  |grep  -i  FreeBSD

Why FreeBSD can be detected but can't be written into grub.cfg?

Reboot my pc,it shows as below:

target.jpg

How can i add FreeBSD into the grub.cfg ?

Code:
debian@debian:~$ sudo fdisk -l
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: ST1000VX000     
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: BF20422A-7E3A-4CA2-B249-61BB4A5D42B7

Device         Start        End    Sectors   Size Type
/dev/sda1       2048     923647     921600   450M Windows recovery environment
/dev/sda2     923648    1128447     204800   100M EFI System
/dev/sda3    1128448    1161215      32768    16M Microsoft reserved
/dev/sda4    1161216  314069245  312908030 149.2G Microsoft basic data
/dev/sda5  314071040  315117567    1046528   511M Windows recovery environment
/dev/sda6  315119616  346370047   31250432  14.9G Linux swap
/dev/sda7  346370048 1953523711 1607153664 766.4G Linux filesystem


Disk /dev/sdb: 465.8 GiB, 500107862016 bytes, 976773168 sectors
Disk model: ST500DM002-1SB10
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 4635826C-E544-11EB-AD01-48F31700362D

Device         Start       End   Sectors   Size Type
/dev/sdb1         40    532519    532480   260M EFI System
/dev/sdb2     532520 968884255 968351736 461.8G FreeBSD UFS
/dev/sdb3  968884256 976773127   7888872   3.8G FreeBSD swap
 
Last edited by a moderator:
Hello,

i never have used grub much in the linux time but you can try editing the grub.conf and adding FreeBSD by hand.

Your efi file should be /boot/efi/efi/boot/bootx64.efi
 
I suggest installing rEFInd (easiest way via Debian10) ... it lets you choose different OSes via EFI and configuration is really easy (one per OS with the respective efi files inside is enough, Debian/FreeBSD/Windows will be recognized automatically)
 
Also, if, for some reason, rEFInd doesn't work for you, usually, when installing FreeBSD on UEFI it will say something about an efi partition (or just use existing). Assuming that part is alright, you may be able to boot with it by hitting whatever key brings you to the boot menu, (for example, on my T495, it's F12) and that should show you the FreeBSD install.
For what it's worth, I've not gotten grub to work booting FreeBSD on Debian based (Ubuntu and LinuxMint) installs. I've had to use either CentOS's grub or VoidLinux's grub. I never looked into this deeply though, because when I do multiboot, it's often mostly for fun, and I'll have a few installs to choose from.
 
Every time I run update-grub in Debian 10, it overwrites the file /boot/grub/grub.cfg, so I never try to edit it directly. Instead, the preferred method seems to be editing the file /etc/grub.d/40_custom.

If I use UEFI booting, I add something like this:
Code:
menuentry "FreeBSD" {
  root=(hd0,gpt14)
  chainloader /boot/loader.efi
}
If I use MBR booting with a GPT partition scheme:
Code:
menuentry "FreeBSD" {
  root=(hd0,gpt14)
  kfreebsd /boot/loader
}
If I use MBR booting with an MS-DOS partition scheme:
Code:
menuentry "FreeBSD" {
  root=(hd0,1)
  kfreebsd /boot/loader
}
Here, hd0 represents your first hard drive. If FreeBSD is on a second drive, use hd1 instead, and so forth.

After adding one of the above entries to /etc/grub.d/40_custom, run update-grub as root, or use the sudo command if you so prefer.

As already mentioned by Alain De Vos, there are multiple threads in this forum, and really, all over the internet covering this same topic, if you're still curious, or if you might have other special requirements.

Search engine results
 
Also, if, for some reason, rEFInd doesn't work for you, usually, when installing FreeBSD on UEFI it will say something about an efi partition (or just use existing). Assuming that part is alright, you may be able to boot with it by hitting whatever key brings you to the boot menu, (for example, on my T495, it's F12) and that should show you the FreeBSD install.
For what it's worth, I've not gotten grub to work booting FreeBSD on Debian based (Ubuntu and LinuxMint) installs. I've had to use either CentOS's grub or VoidLinux's grub. I never looked into this deeply though, because when I do multiboot, it's often mostly for fun, and I'll have a few installs to choose from.
Ubuntu now has its own version of grub2, so I have to use something like this in Ubuntu and/or Linux Mint:
Code:
menuentry "FreeBSD-13.0 (plasma5) gpt12" {
  insmod ufs2
  root=(hd0,gpt12)
  chainloader /boot/loader_4th.efi
}

Reference link regarding Ubuntu's changes
 
debian@debian:~$ sudo mkdir /mnt/freebsd
debian@debian:~$ sudo mount -r -t ufs -o ufstype=ufs2 /dev/sdb2 /mnt/freebsd
debian@debian:~$ ls /mnt/freebsd
bin COPYRIGHT entropy home libexec mnt proc root sys usr
boot dev etc lib media net rescue sbin tmp var
debian@debian:~$ ls /mnt/freebsd/boot
beastie.4th efi.4th loader.efi modules
boot entropy loader_lua pmbr
boot0 firmware loader_lua.efi pxeboot
boot0sio fonts loader.rc screen.4th
boot1 frames.4th loader_simp shortcuts.4th
boot1.efi gptboot loader_simp.efi support.4th
boot2 gptboot.efi logo-beastie.4th uboot
brand.4th gptzfsboot logo-beastiebw.4th userboot_4th.so
brand-fbsd.4th images logo-fbsdbw.4th userboot_lua.so
cdboot isoboot logo-orb.4th userboot.so
check-password.4th kernel logo-orbbw.4th version.4th
color.4th loader lua zfs
defaults loader.4th mbr zfsboot
delay.4th loader_4th menu.4th zfsloader
device.hints loader_4th.efi menu-commands.4th
dtb loader.conf menu.rc
efi loader.conf.d menusets.4th

List some info related when entering via debian.

Edit the grub.cfg munually:

sudo vim /boot/grub/grub.cfg
### BEGIN /etc/grub.d/40_custom ###
menuentry "FreeBSD" {
insmod ufs2
insmod bsd
set root=(hd1,gpt2)
kfreebsd /boot/loader
kfreebsd /boot/kernel
set kFreeBSD.vfs.root.mountfrom=ufs:/dev/ada1p2
set kFreeBSD.vfs.root.mountfrom.options=rw
set kFreeBSD.hw.psm.synaptics_support=1
}
### END /etc/grub.d/40_custom ###
Reboot,the `FreeBSD` added in grub menu.
grub.jpg


Click it to boot,it encounter "invalid a.out header".

How to fix it?
 
You need "insmod gpt", without it grub can not recognize the partition table.
It is enough to load the boatloader whith chainloading, ie you don't need to load the kernel.
 
Vull and Alain De Vos ,it is no use to do as you say.
Please try one of these other 2 menuentry options I listed in this post then. One or the other of these three options should work. Different system types require different types of entries.

Please don't put your changes in /boot/grub/grub.cfg.

Put your changes in /etc/grub.d/40_custom and then run sudo update-grub.

I've been doing this for years using Debian. I'm using it right now on two different systems, using Debian releases 10.9 and 10.10.
 
To determine the correct setting of the FreeBSD GRUB menu entry it's not absolutely necessary to modify every time /etc/grub.d/40_custom and then run update-grub, reboot system, and check if the FreeBSD menu is working.

This can be handled much simpler. At the GRUB menu select the FreeBSD entry and press the "E" key. That opens the selected menu entry in editor mode. There you can make changes and check the effect of the changes immediate. If the settings are not working return to the editor and re-edited them as much as you like.

To boot, after finish editing, press F10.

After finding the correct GRUB settings, proceed to make them permanent the recommended way.

To the menu entry, try
Code:
menuentry "FreeBSD 13.0-RELEASE {
       insmod ufs2
       chainloader (hd1,gpt2)/boot/loader_4th.efi
}

If this is not working post error message.
 
To determine the correct setting of the FreeBSD GRUB menu entry it's not absolutely necessary to modify every time /etc/grub.d/40_custom and then run update-grub, reboot system, and check if the FreeBSD menu is working.

This can be handled much simpler. At the GRUB menu select the FreeBSD entry and press the "E" key. That opens the selected menu entry in editor mode. There you can make changes and check the effect of the changes immediate. If the settings are not working return to the editor and re-edited them as much as you like.

To boot, after finish editing, press F10.

After finding the correct GRUB settings, proceed to make them permanent the recommended way.

To the menu entry, try
Code:
menuentry "FreeBSD 13.0-RELEASE {
       insmod ufs2
       chainloader (hd1,gpt2)/boot/loader_4th.efi
}

If this is not working post error message.
Thanks very much for this, and really for all the good advice you've given here about grub2, as well as on other topics. Please allow me to clarify some additional fine points.

  1. The insmod ufs2 line is no longer necessary in the latest versions of grub2 provided by Debian and Ubuntu derivatives, nor is insmod gpart. These were however necessary on older versions.
  2. My only experience with grub2 is limited to ufs2 filesystems, and the grub2 versions provided by ( a.) Debian, ( b.) Ubuntu (a Debian derivative), and ( c.) Linux Mint (an Ubuntu derivative).
  3. The version of grub2 on Debian is presently different than that used by Ubuntu and Linux Mint, as follows:
If you have more than one FreeBSD partition, a line like chainloader (hd1,gpt2)/boot/loader_4th.efi will work just fine, but, on Debian, it will only work for the first FreeBSD partition on a disk. To make the second and any subsequent partitions bootable, I need to use 2 separate lines for each partition, like in this example:
Code:
menuentry "FreeBSD-RELEASE-13.0" {
  root=(hd1,gpt3)
  chainloader /boot/loader.efi
}
There may be other ways of doing it, but this is at least one way that works.
Furthermore, it seems worth clarifying that, on Debian's version, it's still adequate to specify /boot/loader.efi, but on the Ubuntu style systems, something like /boot/loader_4th.efi is now necessary. I might never have figured out this last bit without your help, so thanks again.
 
I have posted info on /boot after mounting the FreeBSD partition in debian.
It shows that :
Code:
    sudo mount -r -t ufs -o ufstype=ufs2 /dev/sdb2  /mnt/freebsd
    ls  /mnt/freebsd/boot | grep boot
    boot
    boot0
    boot0sio
    boot1
    boot1.efi
    boot2
    cdboot
    gptboot
    gptboot.efi
    gptzfsboot
    isoboot
    pxeboot
    uboot
    userboot_4th.so
    userboot_lua.so
    userboot.so
    zfsboot

So add lines in /boot/grub/grub.cfg as below:
Code:
    ### BEGIN /etc/grub.d/40_custom ###
    menuentry "FreeBSD" {
           insmod ufs2
           chainloader (hd1,gpt2)/boot/boot1.efi
    }
    ### END /etc/grub.d/40_custom ###

It works fine.
 
I have posted info on /boot after mounting the FreeBSD partition in debian.
It shows that :
Code:
    sudo mount -r -t ufs -o ufstype=ufs2 /dev/sdb2  /mnt/freebsd
    ls  /mnt/freebsd/boot | grep boot
    boot
    boot0
    boot0sio
    boot1
    boot1.efi
    boot2
    cdboot
    gptboot
    gptboot.efi
    gptzfsboot
    isoboot
    pxeboot
    uboot
    userboot_4th.so
    userboot_lua.so
    userboot.so
    zfsboot

So add lines in /boot/grub/grub.cfg as below:
Code:
    ### BEGIN /etc/grub.d/40_custom ###
    menuentry "FreeBSD" {
           insmod ufs2
           chainloader (hd1,gpt2)/boot/boot1.efi
    }
    ### END /etc/grub.d/40_custom ###

It works fine.
Thanks for letting us know how it worked out. Hope you enjoy FreeBSD as much as I do. I guess you can probably mark this topic as "Solved" now if you like.
 
Back
Top