Skip to content

Commit 7c8e2ca

Browse files
authored
Merge pull request #346 from devsnek/x/kernel-image-fields
kernel image fields & zero out rbp
2 parents ddbe9e0 + a65533a commit 7c8e2ca

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

api/src/info.rs

+9
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ pub struct BootInfo {
5656
pub ramdisk_addr: Optional<u64>,
5757
/// Ramdisk image size, set to 0 if addr is None
5858
pub ramdisk_len: u64,
59+
/// Physical address of the kernel ELF in memory.
60+
pub kernel_addr: u64,
61+
/// Size of the kernel ELF in memory.
62+
pub kernel_len: u64,
63+
/// Virtual address of the loaded kernel image.
64+
pub kernel_image_offset: u64,
5965

6066
#[doc(hidden)]
6167
pub _test_sentinel: u64,
@@ -76,6 +82,9 @@ impl BootInfo {
7682
tls_template: Optional::None,
7783
ramdisk_addr: Optional::None,
7884
ramdisk_len: 0,
85+
kernel_addr: 0,
86+
kernel_len: 0,
87+
kernel_image_offset: 0,
7988
_test_sentinel: 0,
8089
}
8190
}

common/src/legacy_memory_region.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,11 @@ where
110110
pub fn construct_memory_map(
111111
self,
112112
regions: &mut [MaybeUninit<MemoryRegion>],
113-
kernel_slice_start: u64,
113+
kernel_slice_start: PhysAddr,
114114
kernel_slice_len: u64,
115115
) -> &mut [MemoryRegion] {
116116
let mut next_index = 0;
117+
let kernel_slice_start = kernel_slice_start.as_u64();
117118

118119
for descriptor in self.original {
119120
let mut start = descriptor.start();

common/src/lib.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub mod serial;
3939

4040
const PAGE_SIZE: u64 = 4096;
4141

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

197197
let config = kernel.config;
198-
let kernel_slice_start = kernel.start_address as u64;
198+
let kernel_slice_start = PhysAddr::new(kernel.start_address as _);
199199
let kernel_slice_len = u64::try_from(kernel.len).unwrap();
200200

201-
let (entry_point, tls_template) = load_kernel::load_kernel(
201+
let (kernel_image_offset, entry_point, tls_template) = load_kernel::load_kernel(
202202
kernel,
203203
kernel_page_table,
204204
frame_allocator,
@@ -402,6 +402,8 @@ where
402402

403403
kernel_slice_start,
404404
kernel_slice_len,
405+
kernel_image_offset,
406+
405407
ramdisk_slice_start,
406408
ramdisk_slice_len,
407409
}
@@ -426,9 +428,11 @@ pub struct Mappings {
426428
pub tls_template: Option<TlsTemplate>,
427429

428430
/// Start address of the kernel slice allocation in memory.
429-
pub kernel_slice_start: u64,
431+
pub kernel_slice_start: PhysAddr,
430432
/// Size of the kernel slice allocation in memory.
431433
pub kernel_slice_len: u64,
434+
/// Relocation offset of the kernel image in virtual memory.
435+
pub kernel_image_offset: VirtAddr,
432436
pub ramdisk_slice_start: Option<VirtAddr>,
433437
pub ramdisk_slice_len: u64,
434438
}
@@ -543,6 +547,9 @@ where
543547
.map(|addr| addr.as_u64())
544548
.into();
545549
info.ramdisk_len = mappings.ramdisk_slice_len;
550+
info.kernel_addr = mappings.kernel_slice_start.as_u64();
551+
info.kernel_len = mappings.kernel_slice_len as _;
552+
info.kernel_image_offset = mappings.kernel_image_offset.as_u64();
546553
info._test_sentinel = boot_config._test_sentinel;
547554
info
548555
});
@@ -587,15 +594,21 @@ pub struct PageTables {
587594
///
588595
/// Must be the page table that the `kernel` field of this struct refers to.
589596
///
590-
/// This frame is loaded into the `CR3` register on the final context switch to the kernel.
597+
/// This frame is loaded into the `CR3` register on the final context switch to the kernel.
591598
pub kernel_level_4_frame: PhysFrame,
592599
}
593600

594601
/// Performs the actual context switch.
595602
unsafe fn context_switch(addresses: Addresses) -> ! {
596603
unsafe {
597604
asm!(
598-
"mov cr3, {}; mov rsp, {}; push 0; jmp {}",
605+
r#"
606+
xor rbp, rbp
607+
mov cr3, {}
608+
mov rsp, {}
609+
push 0
610+
jmp {}
611+
"#,
599612
in(reg) addresses.page_table.start_address().as_u64(),
600613
in(reg) addresses.stack_top.as_u64(),
601614
in(reg) addresses.entry_point.as_u64(),

common/src/load_kernel.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -721,11 +721,15 @@ pub fn load_kernel(
721721
page_table: &mut (impl MapperAllSizes + Translate),
722722
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
723723
used_entries: &mut UsedLevel4Entries,
724-
) -> Result<(VirtAddr, Option<TlsTemplate>), &'static str> {
724+
) -> Result<(VirtAddr, VirtAddr, Option<TlsTemplate>), &'static str> {
725725
let mut loader = Loader::new(kernel, page_table, frame_allocator, used_entries)?;
726726
let tls_template = loader.load_segments()?;
727727

728-
Ok((loader.entry_point(), tls_template))
728+
Ok((
729+
VirtAddr::new(loader.inner.virtual_address_offset.virtual_address_offset() as u64),
730+
loader.entry_point(),
731+
tls_template,
732+
))
729733
}
730734

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

0 commit comments

Comments
 (0)