Skip to content

Add support for kernel info #177

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"rust-analyzer.checkOnSave.allTargets": false,
"rust-analyzer.checkOnSave.extraArgs": [
"-Zbuild-std=core,alloc"
]
],
"rust-analyzer.cargo.allFeatures": true,
}
16 changes: 14 additions & 2 deletions src/binary/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
binary::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion},
boot_info::{BootInfo, FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate},
boot_info::{BootInfo, FrameBuffer, FrameBufferInfo, KernelInfo, MemoryRegion, TlsTemplate},
};
use core::{
mem::{self, MaybeUninit},
Expand Down Expand Up @@ -139,8 +139,9 @@ where
// create a stack
let stack_start_addr = kernel_stack_start_location(&mut used_entries);
let stack_start: Page = Page::containing_address(stack_start_addr);
let stack_size = CONFIG.kernel_stack_size.unwrap_or(20 * PAGE_SIZE);
let stack_end = {
let end_addr = stack_start_addr + CONFIG.kernel_stack_size.unwrap_or(20 * PAGE_SIZE);
let end_addr = stack_start_addr + stack_size;
Page::containing_address(end_addr - 1u64)
};
for page in Page::range_inclusive(stack_start, stack_end) {
Expand Down Expand Up @@ -259,6 +260,13 @@ where
None
};

let kernel_info = KernelInfo {
kernel_base: kernel_bytes.as_ptr() as u64,
Copy link
Member

Choose a reason for hiding this comment

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

This is the physical memory address of the kernel ELF file. To get the virtual address at which the kernel is mapped, we need to look at the segments in the program header of the ELF file. Note that there is no guarantee that these segments are continuous in memory since each section can be mapped arbitrarily using a linker script.

kernel_size: kernel_bytes.len() as u64,
Copy link
Member

Choose a reason for hiding this comment

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

This is the size of the kernel ELF file, not the size that the kernel occupies in memory. Also, as noted in the previous comment, the kernel segments can be spread across the whole virtual address space, so I'm not sure if we can even choose a proper kernel_size for all kernels.

stack_top: stack_end.start_address().as_u64(),
stack_size,
};

Mappings {
framebuffer: framebuffer_virt_addr,
entry_point,
Expand All @@ -267,6 +275,7 @@ where
physical_memory_offset,
recursive_index,
tls_template,
kernel_info,
}
}

Expand All @@ -287,6 +296,8 @@ pub struct Mappings {
pub recursive_index: Option<PageTableIndex>,
/// The thread local storage template of the kernel executable, if it contains one.
pub tls_template: Option<TlsTemplate>,
/// The information about kernel specific mappings.
pub kernel_info: KernelInfo,
}

/// Allocates and initializes the boot info struct and the memory map.
Expand Down Expand Up @@ -372,6 +383,7 @@ where
info: system_info.framebuffer_info,
})
.into(),
kernel_info: mappings.kernel_info,
physical_memory_offset: mappings.physical_memory_offset.map(VirtAddr::as_u64).into(),
recursive_index: mappings.recursive_index.map(Into::into).into(),
rsdp_addr: system_info.rsdp_addr.map(|addr| addr.as_u64()).into(),
Expand Down
22 changes: 22 additions & 0 deletions src/boot_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ pub struct BootInfo {
/// the memory map before passing it to the kernel. Regions marked as usable can be freely
/// used by the kernel.
pub memory_regions: MemoryRegions,
/// Information about the kernel specific allocations that the bootloader provided
/// for the kernel.
pub kernel_info: KernelInfo,
/// Information about the framebuffer for screen output if available.
pub framebuffer: Optional<FrameBuffer>,
/// The virtual address at which the mapping of the physical memory starts.
Expand Down Expand Up @@ -149,6 +152,25 @@ pub enum MemoryRegionKind {
UnknownBios(u32),
}

/// Information about the kernel specific allocations that the bootloader provided
/// for the kernel.
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct KernelInfo {
/// The base address of the kernel. The kernel base is helpful
/// for stack unwinding during kernel panics.
pub kernel_base: u64,
/// The size of the kernel, required to calculate the end of the
/// kernel base.
pub kernel_size: u64,

/// The start address of the stack allocated for the kernel.
pub stack_top: u64,
/// The size of the stack allocated for the kernel, required to calculate
/// the end of the kernel stack.
pub stack_size: u64,
}

/// A pixel-based framebuffer that controls the screen output.
#[derive(Debug)]
#[repr(C)]
Expand Down