FreeBSD The Power to Serve

FreeBSD support on LinuxBoot

Contact: Warner Losh <imp@bsdimp.com>

LinuxBoot is an effort to create a clean, robust, auditable and repeatable boot firmware. What originally started as a specific project at Google has grown to encompass any boot environment that uses Linux to launch the final operating system. Many platforms now support this environment, and in some cases it is the only available boot environment. In addition, some embedded boxes have a LinuxBoot environment hard-coded that is quite hard to change, and being able to reboot into FreeBSD is desirable.

The old Sony PlayStation 3 port used a boot loader called 'kboot' to boot the FreeBSD port from its Linux kernel (all predating the LinuxBoot project). That code has been greatly expanded, made generic with easily replaceable per-architecture plug ins. The normal FreeBSD /boot/loader is built as a Linux binary that reads in the FreeBSD kernel, modules and tunables. It places them into memory as if it were running in a pre-boot environment, then loads that image into the Linux kernel with kexec_load(2) and does a special reboot to that image. For UEFI-enabled systems, it passes the UEFI memory table and pointer to UEFI runtime services to the new kernel.

It supports loading files from the host’s filesystem, from any loader(8)-supported filesystem on the host’s block devices (including pools that span multiple devices), from ram disk images and from files downloaded over the network. Any mix of these is available. So, for example, configuration overrides can be loaded from the host’s filesystem whilst the kernel loads from dedicated storage (say NVME) or a ram disk image. It supports a host console running over stdin/stdout. It supports explicit locations such as /dev/nvme0ns1:/boot/loader/gerbil.conf for where to load filesystems from. It supports ZFS boot environments, including the boot-once feature.

Additional details about kboot, what it supports and some general background can be found in Warner’s BSDcan talk (slides linked above).

FreeBSD/aarch64 now can boot from Linux in a LinuxBoot environment, with support and functionality comparable to loader.efi(8). Memory layout passed in for GICv3 workarounds. Need patch for aarch64 kernel for the GICv3 workaround (https://reviews.freebsd.org/D40902).

FreeBSD/amd64 support is in progress and is maybe 80% done. The amd64 boot environment places more requirements on the boot loader to provide data for the kernel than aarch64, due to amd64 being an older port. All sources for data in the BIOS environment had to be provided by the boot loader since the kernel had no access to them from long mode. While UEFI and ACPI provide ways for the kernel to get this data, much of the data must still be provided by the boot loader. The kernel panics during initialization since all these prerequisites have not been discovered and implemented.

PowerPC builds, but nothing more of its state is known. Attempts to acquire a suitable Playstation 3 proved to be too time consuming for the author.

Help Needed

  1. loader.kboot(8) needs to be written. It should document how to use loader.kboot, how to create images, and the use cases that work today.

  2. Finish amd64 support.

  3. The current elf arch-specific metadata code is copied from efi. Unifying the kboot and efi copies is needed. While they are mostly the same, sharing is complicated by remaining compile-time differences. In addition, the build infrastructure makes sharing awkward.

  4. It would be nice to add riscv64 support.

  5. PowerPC testing (it has been untested since the refactoring started).

  6. Creating a script to repackage EDK-II image (say, from QEMU) as a linux-boot image with a Linux kernel built on FreeBSD for CI testing.

  7. Testing it from the coreboot LinuxBoot.

Sponsored by: Netflix, Inc


Last modified on: July 28, 2023 by Graham Perrin