Skip to content

Latest commit

 

History

History
49 lines (38 loc) · 4.55 KB

v0.9.md

File metadata and controls

49 lines (38 loc) · 4.55 KB

Migration from bootloader v0.9

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).

Kernel

  • Replace the bootloader dependency of your kernel with a dependency on the bootloader_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 the entry_point macro:
    use 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);
    See the 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 the common/src/framebuffer.rs module for an example implementation based on the noto-sans-mono-bitmap and log 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 the RSDP structure, which is part of the ACPI standard. Note that ACPI (Advanced Configuration and Power Interface) and APIC (Advanced Programmable Interrupt Controller) are completely different things that just have confusingly similar acronyms.
    • Use the acpi crate and its AcpiTables::from_rsdp function to load the ACPI tables. Then use the platform_info method and read the interrupt_model field of the returned PlatformInfo. 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.
  • If you reload the GDT at some point, ensure that all segment registers are written, including ss and ds. The v0.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 on iretq.

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.

Booting

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.