Skip to content

Added some docs and an example for how to use the APIC #460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added some more explanation on what the purpose of everything is
  • Loading branch information
Radu-Voinea committed Oct 7, 2024
commit 8f2570d1b7986cdc0de841098500a6435afa7dcb
30 changes: 30 additions & 0 deletions docs/apic_example/apic.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nicer to look at on GitHub if this was called README.md

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# How to use the APIC

## src/main.rs

In the example provided we will be using a dynamic memory mapping. This is for exemplification only and can be changed
with your own implementation of the memory mapper.

## src/apic.rs

Here we create an `AcpiHandlerImpl` that implements the `AcpiHandler` trait from the `apic` crate.
We have also added an enum with all the APIC registers from
the [OS Dev Wiki](https://wiki.osdev.org/APIC)
The main functions of the file are:

- Init the Local APIC
- Init the IO APIC
- Map the APIC

## src/frame_allocator.rs

This implements a basic frame allocator based on the [blog post](https://os.phil-opp.com/heap-allocation/)

## src/gdt.rs

Implements a basic Global Descriptor Table based on
the [blog post](https://os.phil-opp.com/double-fault-exceptions/#the-global-descriptor-table/) as well as ensures that
all segment registers are written, including `ss` and `ds`.

## src/idt.rs
Implements a basic Interrupt Descriptor Table based on the [blog post](https://os.phil-opp.com/hardware-interrupts/)
2 changes: 1 addition & 1 deletion docs/apic_example/src/apic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ lazy_static! {
pub static ref LAPIC_ADDR: Mutex<LAPICAddress> = Mutex::new(LAPICAddress::new()); // Needs to be initialized
}

// https://wiki.osdev.org/APIC#:~:text=APIC%20(%22Advanced%20Programmable%20Interrupt%20Controller%22)%20is%20the
// https://wiki.osdev.org/APIC
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
#[repr(isize)]
Expand Down
5 changes: 1 addition & 4 deletions docs/migration/v0.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ This guide summarizes the steps for migrating from `bootloader v0.9.X` to `bootl
```
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 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). To do so you can use the provided [example](../apic_example/apic.md) as a starting point.
- 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.
Expand Down
Loading