From 9b11c0e080902f91cf60ca9f321f0e144a335a33 Mon Sep 17 00:00:00 2001 From: Graham MacDonald Date: Thu, 24 Oct 2024 22:07:52 +0100 Subject: [PATCH] Fix small mapping issues, update toolchain Signed-off-by: Graham MacDonald --- .vscode/settings.json | 6 +++- aarch64/lib/kernel.ld | 20 ++++++------ aarch64/src/kmem.rs | 71 +++++++++++++++++++++++++++++++++++++++---- aarch64/src/main.rs | 44 +++++++++++---------------- aarch64/src/vm.rs | 38 +++++++++-------------- port/src/lib.rs | 1 - port/src/mem.rs | 5 +++ rust-toolchain.toml | 6 ++-- 8 files changed, 119 insertions(+), 72 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 83a9058..d9188fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,9 @@ "xtask", "check", "--json" - ] + ], + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "auto", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "commands" } \ No newline at end of file diff --git a/aarch64/lib/kernel.ld b/aarch64/lib/kernel.ld index 4e1cd05..de87ed6 100644 --- a/aarch64/lib/kernel.ld +++ b/aarch64/lib/kernel.ld @@ -11,25 +11,23 @@ SECTIONS { boottext = .; .text.boot : ALIGN(4096) { *(.boottext .bootdata) - . = ALIGN(4096); - eboottext = .; - . = ALIGN(2097152); - esys = .; } + . = ALIGN(4096); + eboottext = .; text = .; .text : ALIGN(4096) { *(.text* .stub .gnu.linkonce.t.*) - . = ALIGN(2097152); - etext = .; } + . = ALIGN(4096); + etext = .; rodata = .; .rodata : ALIGN(4096) { *(.rodata* .gnu.linkonce.r.*) - . = ALIGN(2097152); - erodata = .; } + . = ALIGN(4096); + erodata = .; data = .; .data : ALIGN(4096) { @@ -41,14 +39,15 @@ SECTIONS { .got.plt : ALIGN(4096) { *(.got.plt) } + . = ALIGN(4096); edata = .; bss = .; .bss : ALIGN(4096) { *(.bss*) *(COMMON) - . = ALIGN(2097152); } + . = ALIGN(4096); ebss = .; /* Reserve section for early pagetables. Align to 2MiB to allow us to map @@ -59,9 +58,8 @@ SECTIONS { early_pagetables = .; . += 2 * 1024 * 1024; eearly_pagetables = .; - + end = .; - PROVIDE(end = .); /DISCARD/ : { *(.eh_frame .note.GNU-stack) diff --git a/aarch64/src/kmem.rs b/aarch64/src/kmem.rs index e7a7a28..92c4cda 100644 --- a/aarch64/src/kmem.rs +++ b/aarch64/src/kmem.rs @@ -3,37 +3,96 @@ use port::mem::{PhysAddr, PhysRange}; // These map to definitions in kernel.ld extern "C" { + static eboottext: [u64; 0]; + static text: [u64; 0]; static etext: [u64; 0]; + static rodata: [u64; 0]; static erodata: [u64; 0]; + static data: [u64; 0]; + static edata: [u64; 0]; + static bss: [u64; 0]; static ebss: [u64; 0]; + static end: [u64; 0]; static early_pagetables: [u64; 0]; static eearly_pagetables: [u64; 0]; } -pub fn text_addr() -> usize { +fn base_addr() -> usize { 0xffff_8000_0000_0000 } -pub fn etext_addr() -> usize { +fn eboottext_addr() -> usize { + unsafe { eboottext.as_ptr().addr() } +} + +fn text_addr() -> usize { + unsafe { text.as_ptr().addr() } +} + +fn etext_addr() -> usize { unsafe { etext.as_ptr().addr() } } -pub fn erodata_addr() -> usize { +fn rodata_addr() -> usize { + unsafe { rodata.as_ptr().addr() } +} + +fn erodata_addr() -> usize { unsafe { erodata.as_ptr().addr() } } -pub fn ebss_addr() -> usize { +fn data_addr() -> usize { + unsafe { data.as_ptr().addr() } +} + +fn edata_addr() -> usize { + unsafe { edata.as_ptr().addr() } +} + +fn bss_addr() -> usize { + unsafe { bss.as_ptr().addr() } +} + +fn ebss_addr() -> usize { unsafe { ebss.as_ptr().addr() } } -pub fn early_pagetables_addr() -> usize { +fn end_addr() -> usize { + unsafe { end.as_ptr().addr() } +} + +fn early_pagetables_addr() -> usize { unsafe { early_pagetables.as_ptr().addr() } } -pub fn eearly_pagetables_addr() -> usize { +fn eearly_pagetables_addr() -> usize { unsafe { eearly_pagetables.as_ptr().addr() } } +pub fn boottext_range() -> PhysRange { + PhysRange(from_virt_to_physaddr(base_addr())..from_virt_to_physaddr(eboottext_addr())) +} + +pub fn text_range() -> PhysRange { + PhysRange(from_virt_to_physaddr(text_addr())..from_virt_to_physaddr(etext_addr())) +} + +pub fn rodata_range() -> PhysRange { + PhysRange(from_virt_to_physaddr(rodata_addr())..from_virt_to_physaddr(erodata_addr())) +} + +pub fn data_range() -> PhysRange { + PhysRange(from_virt_to_physaddr(data_addr())..from_virt_to_physaddr(edata_addr())) +} + +pub fn bss_range() -> PhysRange { + PhysRange(from_virt_to_physaddr(bss_addr())..from_virt_to_physaddr(ebss_addr())) +} + +pub fn total_kernel_range() -> PhysRange { + PhysRange(from_virt_to_physaddr(base_addr())..from_virt_to_physaddr(end_addr())) +} + pub const fn physaddr_as_virt(pa: PhysAddr) -> usize { (pa.addr() as usize).wrapping_add(KZERO) } diff --git a/aarch64/src/main.rs b/aarch64/src/main.rs index f568900..b30e24b 100644 --- a/aarch64/src/main.rs +++ b/aarch64/src/main.rs @@ -4,7 +4,6 @@ #![cfg_attr(not(test), no_main)] #![feature(alloc_error_handler)] #![feature(core_intrinsics)] -#![feature(strict_provenance)] #![feature(sync_unsafe_cell)] #![forbid(unsafe_op_in_unsafe_fn)] @@ -22,8 +21,8 @@ mod vm; use crate::kmem::from_virt_to_physaddr; use crate::vm::kernel_root; -use core::ffi::c_void; use core::ptr; +use kmem::{boottext_range, bss_range, data_range, rodata_range, text_range, total_kernel_range}; use port::fdt::DeviceTree; use port::mem::PhysRange; use port::println; @@ -34,35 +33,20 @@ core::arch::global_asm!(include_str!("l.S")); static mut KPGTBL: PageTable = PageTable::empty(); -unsafe fn print_memory_range(name: &str, start: &*const c_void, end: &*const c_void) { - let start = start as *const _ as u64; - let end = end as *const _ as u64; - let size = end - start; - println!(" {name}{start:#x}..{end:#x} ({size:#x})"); +unsafe fn print_memory_range(name: &str, range: &PhysRange) { + let size = range.size(); + println!(" {name}{range} ({size:#x})"); } fn print_binary_sections() { - extern "C" { - static boottext: *const c_void; - static eboottext: *const c_void; - static text: *const c_void; - static etext: *const c_void; - static rodata: *const c_void; - static erodata: *const c_void; - static data: *const c_void; - static edata: *const c_void; - static bss: *const c_void; - static end: *const c_void; - } - println!("Binary sections:"); unsafe { - print_memory_range("boottext:\t", &boottext, &eboottext); - print_memory_range("text:\t\t", &text, &etext); - print_memory_range("rodata:\t", &rodata, &erodata); - print_memory_range("data:\t\t", &data, &edata); - print_memory_range("bss:\t\t", &bss, &end); - print_memory_range("total:\t", &boottext, &end); + print_memory_range("boottext:\t", &boottext_range()); + print_memory_range("text:\t\t", &text_range()); + print_memory_range("rodata:\t", &rodata_range()); + print_memory_range("data:\t\t", &data_range()); + print_memory_range("bss:\t\t", &bss_range()); + print_memory_range("total:\t", &total_kernel_range()); } } @@ -141,6 +125,14 @@ pub extern "C" fn main9(dtb_va: usize) { print_memory_info(); + if let Ok(page) = pagealloc::allocate() { + println!("page addr: {:#016x}", page.data().as_ptr() as *const _ as u64); + + //let mapped_range = + // let kpgtable = unsafe { &mut *ptr::addr_of_mut!(KPGTBL) }; + // kpgtable.map_phys_range(range, *flags, *page_size).expect("dynamic mapping failed"); + } + kernel_root().print_recursive_tables(); println!("looping now"); diff --git a/aarch64/src/vm.rs b/aarch64/src/vm.rs index 02c8c52..d24db77 100644 --- a/aarch64/src/vm.rs +++ b/aarch64/src/vm.rs @@ -2,8 +2,8 @@ use crate::{ kmem::{ - ebss_addr, erodata_addr, etext_addr, from_ptr_to_physaddr, from_virt_to_physaddr, - physaddr_as_ptr_mut, physaddr_as_virt, text_addr, + boottext_range, bss_range, data_range, from_ptr_to_physaddr, physaddr_as_ptr_mut, + physaddr_as_virt, rodata_range, text_range, }, pagealloc, registers::rpi_mmio, @@ -48,6 +48,10 @@ impl Page4K { core::intrinsics::volatile_set_memory(&mut self.0, 0u8, 1); } } + + pub fn data(&mut self) -> &mut [u8] { + &mut self.0 + } } #[derive(Debug, IntoPrimitive, FromPrimitive)] @@ -485,24 +489,16 @@ pub unsafe fn init(kpage_table: &mut PageTable, dtb_range: PhysRange, available_ // TODO leave the first page unmapped to catch null pointer dereferences in unsafe code let custom_map = { - let text_range = - PhysRange(from_virt_to_physaddr(text_addr())..from_virt_to_physaddr(etext_addr())); - let data_range = PhysRange::with_len( - from_virt_to_physaddr(etext_addr()).addr(), - erodata_addr() - etext_addr(), - ); - let bss_range = PhysRange::with_len( - from_virt_to_physaddr(erodata_addr()).addr(), - ebss_addr() - erodata_addr(), - ); - + let text_range = boottext_range().add(&text_range()); + let data_range = rodata_range().add(&data_range()); + let bss_range = bss_range(); let mmio_range = rpi_mmio().expect("mmio base detect failed"); let mut map = [ ("DTB", dtb_range, Entry::ro_kernel_data(), PageSize::Page4K), - ("Kernel Text", text_range, Entry::ro_kernel_text(), PageSize::Page2M), - ("Kernel Data", data_range, Entry::ro_kernel_data(), PageSize::Page2M), - ("Kernel BSS", bss_range, Entry::rw_kernel_data(), PageSize::Page2M), + ("Kernel Text", text_range, Entry::ro_kernel_text(), PageSize::Page4K), + ("Kernel Data", data_range, Entry::rw_kernel_data(), PageSize::Page4K), + ("Kernel BSS", bss_range, Entry::rw_kernel_data(), PageSize::Page4K), ("MMIO", mmio_range, Entry::ro_kernel_device(), PageSize::Page2M), ]; map.sort_by_key(|a| a.1.start()); @@ -515,14 +511,8 @@ pub unsafe fn init(kpage_table: &mut PageTable, dtb_range: PhysRange, available_ kpage_table.map_phys_range(range, *flags, *page_size).expect("init mapping failed"); println!( - " {:14}{:#018x}..{:#018x} to {:#018x}..{:#018x} flags: {:?} page_size: {:?}", - name, - range.start().addr(), - range.end().addr(), - mapped_range.0, - mapped_range.1, - flags, - page_size + " {:14}{} to {:#018x}..{:#018x} flags: {:?} page_size: {:?}", + name, range, mapped_range.0, mapped_range.1, flags, page_size ); } diff --git a/port/src/lib.rs b/port/src/lib.rs index 66f324d..cf4e115 100644 --- a/port/src/lib.rs +++ b/port/src/lib.rs @@ -4,7 +4,6 @@ #![feature(allocator_api)] #![feature(maybe_uninit_slice)] #![feature(step_trait)] -#![feature(strict_provenance)] #![forbid(unsafe_op_in_unsafe_fn)] extern crate alloc; diff --git a/port/src/mem.rs b/port/src/mem.rs index 40154ee..4ff6371 100644 --- a/port/src/mem.rs +++ b/port/src/mem.rs @@ -1,5 +1,6 @@ use crate::fdt::RegBlock; use core::{ + cmp::{max, min}, fmt, iter::{Step, StepBy}, ops::{self, Range}, @@ -145,6 +146,10 @@ impl PhysRange { let endpa = self.end().round_up(step_size as u64); (startpa..endpa).step_by(step_size) } + + pub fn add(&self, other: &PhysRange) -> Self { + Self(min(self.0.start, other.0.start)..max(self.0.end, other.0.end)) + } } impl fmt::Display for PhysRange { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c41b3c1..e5af38f 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,8 +1,8 @@ [toolchain] -channel = "nightly-2024-10-15" -components = [ "rustfmt", "rust-src", "clippy", "llvm-tools" ] +channel = "nightly-2024-10-23" +components = ["rustfmt", "rust-src", "clippy", "llvm-tools"] targets = [ "aarch64-unknown-none", "riscv64gc-unknown-none-elf", - "x86_64-unknown-none" + "x86_64-unknown-none", ]