bootloader 0.11.15

An experimental x86_64 bootloader that works on both BIOS and UEFI systems.
Documentation
# 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:
  ```diff
  -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:
  ```diff
  -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:
  ```rust
  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`](https://docs.rs/bootloader_api/0.11/bootloader_api/config/struct.BootloaderConfig.html) 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`](../../common/src/framebuffer.rs) module for an example implementation based on the [`noto-sans-mono-bitmap`](https://docs.rs/noto-sans-mono-bitmap/latest/noto_sans_mono_bitmap/index.html) and [`log`](https://docs.rs/log/latest) crates.
- If you want to use UEFI booting, you cannot use the [legacy PIC](https://wiki.osdev.org/8259_PIC) for interrupt handling. Instead, you have to set up the [`APIC`](https://wiki.osdev.org/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`](https://wiki.osdev.org/RSDP) structure, which is part of the [`ACPI`](https://en.wikipedia.org/wiki/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`](https://docs.rs/acpi/4.1.1/acpi/index.html) crate and its [`AcpiTables::from_rsdp`](https://docs.rs/acpi/4.1.1/acpi/struct.AcpiTables.html#method.from_rsdp) function to load the ACPI tables. Then use the [`platform_info`](https://docs.rs/acpi/4.1.1/acpi/struct.AcpiTables.html#method.platform_info) method and read the [`interrupt_model`](https://docs.rs/acpi/4.1.1/acpi/platform/struct.PlatformInfo.html#structfield.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](https://github.com/rust-osdev/apic) 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`](https://github.com/rust-osdev/bootloader/issues/196).

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`](https://docs.rs/bootloader/0.11) 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](../create-disk-image.md) for a detailed explanation of the new build process.