Skip to content

Commit

Permalink
Merge pull request #346 from devsnek/x/kernel-image-fields
Browse files Browse the repository at this point in the history
kernel image fields & zero out rbp
  • Loading branch information
phil-opp authored Aug 14, 2023
2 parents ddbe9e0 + a65533a commit 7c8e2ca
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
9 changes: 9 additions & 0 deletions api/src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ pub struct BootInfo {
pub ramdisk_addr: Optional<u64>,
/// Ramdisk image size, set to 0 if addr is None
pub ramdisk_len: u64,
/// Physical address of the kernel ELF in memory.
pub kernel_addr: u64,
/// Size of the kernel ELF in memory.
pub kernel_len: u64,
/// Virtual address of the loaded kernel image.
pub kernel_image_offset: u64,

#[doc(hidden)]
pub _test_sentinel: u64,
Expand All @@ -76,6 +82,9 @@ impl BootInfo {
tls_template: Optional::None,
ramdisk_addr: Optional::None,
ramdisk_len: 0,
kernel_addr: 0,
kernel_len: 0,
kernel_image_offset: 0,
_test_sentinel: 0,
}
}
Expand Down
3 changes: 2 additions & 1 deletion common/src/legacy_memory_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,11 @@ where
pub fn construct_memory_map(
self,
regions: &mut [MaybeUninit<MemoryRegion>],
kernel_slice_start: u64,
kernel_slice_start: PhysAddr,
kernel_slice_len: u64,
) -> &mut [MemoryRegion] {
let mut next_index = 0;
let kernel_slice_start = kernel_slice_start.as_u64();

for descriptor in self.original {
let mut start = descriptor.start();
Expand Down
25 changes: 19 additions & 6 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub mod serial;

const PAGE_SIZE: u64 = 4096;

/// Initialize a text-based logger using the given pixel-based framebuffer as output.
/// Initialize a text-based logger using the given pixel-based framebuffer as output.
pub fn init_logger(
framebuffer: &'static mut [u8],
info: FrameBufferInfo,
Expand Down Expand Up @@ -195,10 +195,10 @@ where
enable_write_protect_bit();

let config = kernel.config;
let kernel_slice_start = kernel.start_address as u64;
let kernel_slice_start = PhysAddr::new(kernel.start_address as _);
let kernel_slice_len = u64::try_from(kernel.len).unwrap();

let (entry_point, tls_template) = load_kernel::load_kernel(
let (kernel_image_offset, entry_point, tls_template) = load_kernel::load_kernel(
kernel,
kernel_page_table,
frame_allocator,
Expand Down Expand Up @@ -402,6 +402,8 @@ where

kernel_slice_start,
kernel_slice_len,
kernel_image_offset,

ramdisk_slice_start,
ramdisk_slice_len,
}
Expand All @@ -426,9 +428,11 @@ pub struct Mappings {
pub tls_template: Option<TlsTemplate>,

/// Start address of the kernel slice allocation in memory.
pub kernel_slice_start: u64,
pub kernel_slice_start: PhysAddr,
/// Size of the kernel slice allocation in memory.
pub kernel_slice_len: u64,
/// Relocation offset of the kernel image in virtual memory.
pub kernel_image_offset: VirtAddr,
pub ramdisk_slice_start: Option<VirtAddr>,
pub ramdisk_slice_len: u64,
}
Expand Down Expand Up @@ -543,6 +547,9 @@ where
.map(|addr| addr.as_u64())
.into();
info.ramdisk_len = mappings.ramdisk_slice_len;
info.kernel_addr = mappings.kernel_slice_start.as_u64();
info.kernel_len = mappings.kernel_slice_len as _;
info.kernel_image_offset = mappings.kernel_image_offset.as_u64();
info._test_sentinel = boot_config._test_sentinel;
info
});
Expand Down Expand Up @@ -587,15 +594,21 @@ pub struct PageTables {
///
/// Must be the page table that the `kernel` field of this struct refers to.
///
/// This frame is loaded into the `CR3` register on the final context switch to the kernel.
/// This frame is loaded into the `CR3` register on the final context switch to the kernel.
pub kernel_level_4_frame: PhysFrame,
}

/// Performs the actual context switch.
unsafe fn context_switch(addresses: Addresses) -> ! {
unsafe {
asm!(
"mov cr3, {}; mov rsp, {}; push 0; jmp {}",
r#"
xor rbp, rbp
mov cr3, {}
mov rsp, {}
push 0
jmp {}
"#,
in(reg) addresses.page_table.start_address().as_u64(),
in(reg) addresses.stack_top.as_u64(),
in(reg) addresses.entry_point.as_u64(),
Expand Down
8 changes: 6 additions & 2 deletions common/src/load_kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,11 +721,15 @@ pub fn load_kernel(
page_table: &mut (impl MapperAllSizes + Translate),
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
used_entries: &mut UsedLevel4Entries,
) -> Result<(VirtAddr, Option<TlsTemplate>), &'static str> {
) -> Result<(VirtAddr, VirtAddr, Option<TlsTemplate>), &'static str> {
let mut loader = Loader::new(kernel, page_table, frame_allocator, used_entries)?;
let tls_template = loader.load_segments()?;

Ok((loader.entry_point(), tls_template))
Ok((
VirtAddr::new(loader.inner.virtual_address_offset.virtual_address_offset() as u64),
loader.entry_point(),
tls_template,
))
}

/// A helper type used to offset virtual addresses for position independent
Expand Down

0 comments on commit 7c8e2ca

Please sign in to comment.