This guide summarizes the steps for migrating from bootloader v0.9.X
to bootloader v0.11
. Note that some bigger changes are required to support UEFI booting (to support the framebuffer and APIC).
- Replace the
bootloader
dependency of your kernel with a dependency on thebootloader_api
crate:-bootloader = { version = "0.9.23", features = [...]} +bootloader_api = "0.11"
- In your
main.rs
, adjust the import path and change the signature of the entry point function:-use bootloader::{entry_point, BootInfo}; +use bootloader_api::{entry_point, BootInfo}; entry_point!(kernel_main); -fn kernel_main(boot_info: &'static BootInfo) -> ! { +fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
- If you used optional features, such as
map_physical_memory
, you can enable them again through theentry_point
macro:See theuse bootloader_api::config::{BootloaderConfig, Mapping}; pub static BOOTLOADER_CONFIG: BootloaderConfig = { let mut config = BootloaderConfig::new_default(); config.mappings.physical_memory = Some(Mapping::Dynamic); config }; // add a `config` argument to the `entry_point` macro call entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);
BootloaderConfig
struct for all configuration options. - The
v0.11
version of the bootloader sets up a pixel-based framebuffer instead of using the VGA text mode. This means that you have to rewrite your screen output code. See thecommon/src/framebuffer.rs
module for an example implementation based on thenoto-sans-mono-bitmap
andlog
crates. - If you want to use UEFI booting, you cannot use the legacy PIC for interrupt handling. Instead, you have to set up the
APIC
. Unfortunately, we don't have a guide for this yet, but the basic steps are:- The
boot_info.rsdp_addr
field will tell you the physical address of theRSDP
structure, which is part of theACPI
standard. Note thatACPI
(Advanced Configuration and Power Interface) andAPIC
(Advanced Programmable Interrupt Controller) are completely different things that just have confusingly similar acronyms. - Use the
acpi
crate and itsAcpiTables::from_rsdp
function to load the ACPI tables. Then use theplatform_info
method and read theinterrupt_model
field of the returnedPlatformInfo
. This field gives you all the necessary information about the system's interrupt controller. - Parse and set up the local and IO APIC. We're working on a crate for that, but it's still in a very early state. We would love contributions! Alternatively, there are some other crates on crates.io that might work too.
- The
- If you reload the GDT at some point, ensure that all segment registers are written, including
ss
andds
. Thev0.9
version of the bootloader used to initialize some of them to 0, but this is no longer the case. If you don't do this, a general protection fault might happen oniretq
.
To build your kernel, run cargo build --target x86_64-unknown-none
. Since the x86_64-unknown-none
target is a Tier-2 target, there is no need for bootimage
, cargo-xbuild
, or xargo
anymore. Instead, you can run rustup target add x86_64-unknown-none
to download precompiled versions of the core
and alloc
crates. There is no need for custom JSON-based target files anymore.
The bootloader v0.11
release does not use the bootimage
tool anymore. Instead, the bootloader
crate provides functions to create bootable disk images from a kernel. The basic idea is to build your kernel first and then invoke a builder function that calls the disk image creation functions of the bootloader
crate.
See our disk image creation template for a detailed explanation of the new build process.