Skip to content
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

Use new UEFI bootloader #792

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
217e76f
Update rust toolchain
tsoutsman Dec 30, 2022
22936f7
Update `uefi_builder`
tsoutsman Dec 30, 2022
1855b46
Implement new bootloader
tsoutsman Jan 2, 2023
24147e3
Fix build for BIOS
tsoutsman Jan 2, 2023
961f07b
Dirty
tsoutsman Jan 3, 2023
8839b5e
Add `BootInformation::additional_reserved_memory_regions`
tsoutsman Jan 3, 2023
de3a88d
Add `nano_core/bios` feature to Clippy run
tsoutsman Jan 3, 2023
9732fc9
Don't reuse recursive entry in `PageTable::with`
tsoutsman Jan 3, 2023
c555e8f
Add current mapper to `PageTable::with` closure
tsoutsman Jan 3, 2023
1600a23
Use current page table to calculate stack and boot info frames
tsoutsman Jan 3, 2023
82e6da9
Cleanup
tsoutsman Jan 3, 2023
c7cc800
Remove kernel and user stack references
tsoutsman Jan 4, 2023
8ebb5e7
Update docs
tsoutsman Jan 4, 2023
db4f3df
Merge branch 'boot-spec-additional-memory-regions' into arbitrary-loa…
tsoutsman Jan 4, 2023
21f987a
Merge branch 'access-current-page-table-2' into arbitrary-load-address
tsoutsman Jan 4, 2023
14e5f0b
Calculate end of deginated low pages via translation
tsoutsman Jan 4, 2023
0b0989c
Translate section virtual addresses in `find_section_memory_bounds`
tsoutsman Jan 5, 2023
13a91a5
Use physical addresses for identity mapping nano core sections
tsoutsman Jan 5, 2023
2bbbe71
Merge branch 'arbitrary-load-address' into new-uefi-bootloader
tsoutsman Jan 5, 2023
52f9e73
Clarify docs
kevinaboos Jan 5, 2023
cfe9de3
Add default nano core feature
tsoutsman Jan 6, 2023
0336e92
Refactor `kernel_memory_region`
tsoutsman Jan 6, 2023
48bf42b
Update kernel/kernel_config/src/memory.rs
tsoutsman Jan 6, 2023
84312a5
Fix `TEMP_P4` address
tsoutsman Jan 6, 2023
823b0a5
Update `PageTable::with` docs
tsoutsman Jan 6, 2023
e07b3b4
Update temporary recursive index naming
tsoutsman Jan 6, 2023
b5055f4
Merge branch 'access-current-page-table-2' into new-uefi-bootloader
tsoutsman Jan 6, 2023
f38ebe1
Merge branch 'boot-spec-additional-memory-regions' into new-uefi-boot…
tsoutsman Jan 6, 2023
1631be1
Dirty
tsoutsman Jan 6, 2023
72b528b
Merge branch 'theseus_main' into new-uefi-bootloader
tsoutsman Jan 6, 2023
e90793f
Working commit on `x86_64`
tsoutsman Jan 7, 2023
2782231
Add new `uefi_builder`
tsoutsman Jan 8, 2023
a365488
Change `uefi-bootloader` path dependencies to git dependencies
tsoutsman Jan 8, 2023
6ec3292
Remove `aarch64` changes
tsoutsman Jan 8, 2023
0fe1c80
More cleanup
tsoutsman Jan 8, 2023
e13ce4a
Update `Cargo.lock`
tsoutsman Jan 9, 2023
68ca93b
Merge branch 'theseus_main' into new-uefi-bootloader-no-aarch
tsoutsman Jan 11, 2023
3c4c133
Remove changes to `rustfmt.toml`
tsoutsman Jan 11, 2023
b9dfb36
Merge branch 'theseus_main' into new-uefi-bootloader-no-aarch
tsoutsman Jan 11, 2023
bd7e64a
Remove changes to `vga_buffer`
tsoutsman Jan 11, 2023
e8ce958
Final cleanup
tsoutsman Jan 11, 2023
d05386d
Update Rust toolchain
tsoutsman Jan 11, 2023
b4a87f4
Clarify GDT entries
tsoutsman Jan 11, 2023
092566c
Merge branch 'theseus_main' into new-uefi-bootloader-no-aarch
tsoutsman Jan 11, 2023
abf982a
Update version
tsoutsman Jan 11, 2023
13c961a
Satisfy Clippy
tsoutsman Jan 11, 2023
d1eba72
Satisfy Clippy
tsoutsman Jan 11, 2023
2088ac2
Merge branch 'new-rust-version' into new-uefi-bootloader-no-aarch
tsoutsman Jan 11, 2023
b1413e0
Minor fixes
tsoutsman Jan 11, 2023
1435524
Update kernel/memory/src/paging/mapper.rs
tsoutsman Jan 11, 2023
b4af63d
Add crate descriptions
tsoutsman Jan 11, 2023
9ec7ae1
simplify/clarify
kevinaboos Jan 11, 2023
c904599
placate clippy
kevinaboos Jan 11, 2023
4522250
Merge branch 'theseus_main' into new-uefi-bootloader-no-aarch
kevinaboos Jan 12, 2023
e37526b
update to latest uefi-bootloader version
kevinaboos Jan 12, 2023
0160593
ensure same version of uefi-bootloader* crates are used
kevinaboos Jan 12, 2023
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
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ ifeq ($(boot_spec), uefi)
--release \
-Z bindeps \
--manifest-path \
$(ROOT_DIR)/tools/uefi_builder/Cargo.toml -- \
$(ROOT_DIR)/tools/uefi_builder/x86_64/Cargo.toml -- \
--kernel $(nano_core_binary) \
--modules $(OBJECT_FILES_BUILD_DIR) \
--efi-image $(iso) \
Expand Down
7 changes: 3 additions & 4 deletions kernel/boot_info/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ kernel_config = { path = "../kernel_config" }
memory_structs = { path = "../memory_structs" }
multiboot2 = { version = "0.14", optional = true }

[dependencies.bootloader_api]
git = "https://github.com/theseus-os/bootloader"
branch = "theseus"
[dependencies.uefi-bootloader-api]
git = "https://github.com/theseus-os/uefi-bootloader"
optional = true

[features]
uefi = ["dep:bootloader_api"]
uefi = ["dep:uefi-bootloader-api"]
multiboot2 = ["dep:multiboot2"]
7 changes: 4 additions & 3 deletions kernel/boot_info/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ pub trait ElfSection {
/// Returns the section's starting virtual address.
fn start(&self) -> VirtualAddress;

/// Returns the section's length.
/// Returns the section's length in memory, as opposed to its length in the
/// ELF file.
fn len(&self) -> usize;

/// Returns whether the section is empty.
Expand Down Expand Up @@ -121,8 +122,8 @@ pub trait BootInformation: 'static {
&self,
) -> Result<Self::AdditionalReservedMemoryRegions, &'static str>;

/// Returns the end of the kernel's image in physical memory.
fn kernel_end(&self) -> Result<PhysicalAddress, &'static str>;
/// Returns the end of the kernel's image in memory.
fn kernel_end(&self) -> Result<VirtualAddress, &'static str>;

/// Returns the RSDP if it was provided by the bootloader.
fn rsdp(&self) -> Option<PhysicalAddress>;
Expand Down
9 changes: 6 additions & 3 deletions kernel/boot_info/src/multiboot2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,12 @@ impl crate::BootInformation for multiboot2::BootInformation {
.into_iter())
}

fn kernel_end(&self) -> Result<PhysicalAddress, &'static str> {
let reserved_region = kernel_memory_region(self)?;
Ok(reserved_region.start + reserved_region.len)
fn kernel_end(&self) -> Result<VirtualAddress, &'static str> {
use crate::ElfSection;
self.elf_sections()?
.map(|section| section.start() + section.len())
.max()
.ok_or("no elf sections")
}

fn rsdp(&self) -> Option<PhysicalAddress> {
Expand Down
91 changes: 37 additions & 54 deletions kernel/boot_info/src/uefi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::ElfSectionFlags;
use bootloader_api::info;
use core::iter::{Iterator, Peekable};
use kernel_config::memory::{KERNEL_OFFSET, KERNEL_STACK_SIZE_IN_PAGES, PAGE_SIZE};
use kernel_config::memory::{KERNEL_STACK_SIZE_IN_PAGES, PAGE_SIZE};
use memory_structs::{PhysicalAddress, VirtualAddress};

// TODO: Ideally this would be defined in nano_core. However, that would
Expand All @@ -11,66 +10,50 @@ use memory_structs::{PhysicalAddress, VirtualAddress};
pub const STACK_SIZE: usize = (KERNEL_STACK_SIZE_IN_PAGES + 2) * PAGE_SIZE;

/// A custom memory region kind used by the bootloader for the modules.
const MODULES_MEMORY_KIND: info::MemoryRegionKind = info::MemoryRegionKind::UnknownUefi(0x80000000);
const MODULES_MEMORY_KIND: uefi_bootloader_api::MemoryRegionKind =
uefi_bootloader_api::MemoryRegionKind::UnknownUefi(0x80000000);

pub struct MemoryRegion {
start: PhysicalAddress,
len: usize,
is_usable: bool,
}

impl From<info::MemoryRegion> for MemoryRegion {
fn from(info::MemoryRegion { start, end, kind }: info::MemoryRegion) -> Self {
Self {
start: PhysicalAddress::new_canonical(start as usize),
len: (end - start) as usize,
is_usable: matches!(kind, info::MemoryRegionKind::Usable),
}
}
}

impl crate::MemoryRegion for MemoryRegion {
impl crate::MemoryRegion for uefi_bootloader_api::MemoryRegion {
fn start(&self) -> PhysicalAddress {
self.start
PhysicalAddress::new_canonical(self.start)
}

fn len(&self) -> usize {
self.len
}

fn is_usable(&self) -> bool {
self.is_usable
matches!(self.kind, uefi_bootloader_api::MemoryRegionKind::Usable)
}
}

pub struct MemoryRegions {
inner: Peekable<core::slice::Iter<'static, info::MemoryRegion>>,
pub struct MemoryRegions<'a> {
inner: Peekable<core::slice::Iter<'a, uefi_bootloader_api::MemoryRegion>>,
}

impl Iterator for MemoryRegions {
type Item = MemoryRegion;
impl<'a> Iterator for MemoryRegions<'a> {
type Item = uefi_bootloader_api::MemoryRegion;

fn next(&mut self) -> Option<Self::Item> {
let mut area: MemoryRegion = (*self.inner.next()?).into();
let mut region = *self.inner.next()?;

// UEFI often separates contiguous memory into separate memory regions. We
// consolidate them to minimise the number of entries in the frame allocator's
// reserved and available lists.
while let Some(next) = self.inner.next_if(|next| {
let next = MemoryRegion::from(**next);
area.is_usable == next.is_usable && (area.start + area.len) == next.start
}) {
let next = MemoryRegion::from(*next);
area.len += next.len;
while let Some(next) = self
.inner
.next_if(|next| region.kind == next.kind && (region.start + region.len) == next.start)
{
region.len += next.len;
}

Some(area)
Some(region)
}
}

impl<'a> crate::ElfSection for &'a info::ElfSection {
impl<'a> crate::ElfSection for &'a uefi_bootloader_api::ElfSection {
fn name(&self) -> &str {
info::ElfSection::name(self)
uefi_bootloader_api::ElfSection::name(self)
}

fn start(&self) -> VirtualAddress {
Expand All @@ -86,14 +69,15 @@ impl<'a> crate::ElfSection for &'a info::ElfSection {
}
}

#[derive(Debug)]
pub struct Module {
inner: info::Module,
regions: &'static info::MemoryRegions,
inner: uefi_bootloader_api::Module,
regions: &'static uefi_bootloader_api::MemoryRegions,
}

impl crate::Module for Module {
fn name(&self) -> Result<&str, &'static str> {
Ok(info::Module::name(&self.inner))
Ok(uefi_bootloader_api::Module::name(&self.inner))
}

fn start(&self) -> PhysicalAddress {
Expand All @@ -113,8 +97,8 @@ impl crate::Module for Module {
}

pub struct Modules {
inner: &'static info::Modules,
regions: &'static info::MemoryRegions,
inner: &'static uefi_bootloader_api::Modules,
regions: &'static uefi_bootloader_api::MemoryRegions,
index: usize,
}

Expand All @@ -132,12 +116,12 @@ impl Iterator for Modules {
}
}

impl crate::BootInformation for &'static bootloader_api::BootInfo {
type MemoryRegion<'a> = MemoryRegion;
type MemoryRegions<'a> = MemoryRegions;
impl crate::BootInformation for &'static uefi_bootloader_api::BootInformation {
type MemoryRegion<'a> = uefi_bootloader_api::MemoryRegion;
type MemoryRegions<'a> = MemoryRegions<'a>;

type ElfSection<'a> = &'a info::ElfSection;
type ElfSections<'a> = core::slice::Iter<'a, info::ElfSection>;
type ElfSection<'a> = &'a uefi_bootloader_api::ElfSection;
type ElfSections<'a> = core::slice::Iter<'a, uefi_bootloader_api::ElfSection>;

type Module<'a> = Module;
type Modules<'a> = Modules;
Expand Down Expand Up @@ -176,24 +160,23 @@ impl crate::BootInformation for &'static bootloader_api::BootInfo {
Ok(core::iter::empty())
}

fn kernel_end(&self) -> Result<PhysicalAddress, &'static str> {
fn kernel_end(&self) -> Result<VirtualAddress, &'static str> {
use crate::ElfSection;

PhysicalAddress::new(
VirtualAddress::new(
self.elf_sections()?
.filter(|section| section.flags().contains(ElfSectionFlags::ALLOCATED))
.filter(|section| section.size > 0)
.map(|section| section.start + section.size)
.max()
.ok_or("couldn't find kernel end address")? as usize
- KERNEL_OFFSET,
.ok_or("couldn't find kernel end address")? as usize,
)
.ok_or("kernel physical end address was invalid")
.ok_or("kernel virtual end address was invalid")
}

fn rsdp(&self) -> Option<PhysicalAddress> {
self.rsdp_addr
.into_option()
.map(|address| PhysicalAddress::new_canonical(address as usize))
self.rsdp_address
.map(|address| PhysicalAddress::new_canonical(address))
}

fn stack_size(&self) -> Result<usize, &'static str> {
Expand Down
2 changes: 2 additions & 0 deletions kernel/captain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub fn init(
bsp_initial_stack: NoDrop<Stack>,
ap_start_realmode_begin: VirtualAddress,
ap_start_realmode_end: VirtualAddress,
ap_gdt: VirtualAddress,
rsdp_address: Option<PhysicalAddress>,
) -> Result<(), &'static str> {
#[cfg(mirror_log_to_vga)]
Expand Down Expand Up @@ -128,6 +129,7 @@ pub fn init(
&kernel_mmi_ref,
ap_start_realmode_begin,
ap_start_realmode_end,
ap_gdt,
Some(kernel_config::display::FRAMEBUFFER_MAX_RESOLUTION),
)?;
let cpu_count = ap_count + 1;
Expand Down
14 changes: 13 additions & 1 deletion kernel/memory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mod paging;
pub use self::paging::{
PageTable, Mapper, Mutability, Mutable, Immutable,
MappedPages, BorrowedMappedPages, BorrowedSliceMappedPages,
translate,
};

pub use memory_structs::{Frame, Page, FrameRange, PageRange, VirtualAddress, PhysicalAddress};
Expand Down Expand Up @@ -220,7 +221,18 @@ pub fn init(
debug!("Initialized new frame allocator!");
frame_allocator::dump_frame_allocator_state();

page_allocator::init(VirtualAddress::new_canonical(boot_info.kernel_end()?.value()))?;
page_allocator::init(
VirtualAddress::new(
// We subtract 1 when translating because `kernel_end` returns an exclusive
// upper bound, which can cause problems if the kernel ends on a page boundary.
// We then add it back later to get the correct identity virtual address.
translate(boot_info.kernel_end()? - 1)
.ok_or("couldn't translate kernel end virtual address")?
.value()
+ 1,
)
.ok_or("couldn't convert kernel end physical address into virtual address")?,
)?;
debug!("Initialized new page allocator!");
page_allocator::dump_page_allocator_state();

Expand Down
5 changes: 5 additions & 0 deletions kernel/memory/src/paging/mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ use owned_borrowed_trait::{OwnedOrBorrowed, Owned, Borrowed};
/// that it is only invoked for `UnmappedFrames`.
pub(super) static INTO_ALLOCATED_FRAMES_FUNC: Once<fn(FrameRange) -> AllocatedFrames> = Once::new();

/// A convenience function to translate the given virtual address into a
/// physical address using the currently-active page table.
pub fn translate(virtual_address: VirtualAddress) -> Option<PhysicalAddress> {
Mapper::from_current().translate(virtual_address)
}

pub struct Mapper {
p4: Unique<Table<Level4>>,
Expand Down
Loading